Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/tpfmt C version of tpfmt.sh
details: https://anonhg.NetBSD.org/src/rev/36862cb2dc8a
branches: trunk
changeset: 759004:36862cb2dc8a
user: yamt <yamt%NetBSD.org@localhost>
date: Tue Nov 23 20:48:40 2010 +0000
description:
C version of tpfmt.sh
diffstat:
usr.bin/tpfmt/Makefile | 15 ++++
usr.bin/tpfmt/README | 3 +
usr.bin/tpfmt/sym.c | 155 +++++++++++++++++++++++++++++++++++++++++++
usr.bin/tpfmt/sym.h | 30 ++++++++
usr.bin/tpfmt/tpfmt.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 377 insertions(+), 0 deletions(-)
diffs (truncated from 397 to 300 lines):
diff -r 91b81d0be7cd -r 36862cb2dc8a usr.bin/tpfmt/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/tpfmt/Makefile Tue Nov 23 20:48:40 2010 +0000
@@ -0,0 +1,15 @@
+# $NetBSD: Makefile,v 1.1 2010/11/23 20:48:40 yamt Exp $
+
+PROG= tpfmt
+NOMAN=
+
+CPPFLAGS+= -I${NETBSDSRCDIR}/sys/
+SRCS= tpfmt.c sym.c
+
+LDADD+= -lpthread
+LDADD+= -lelf
+DPADD+= ${LIBPTHREAD}
+DPADD+= ${LIBELF}
+
+.include <bsd.own.mk>
+.include <bsd.prog.mk>
diff -r 91b81d0be7cd -r 36862cb2dc8a usr.bin/tpfmt/README
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/tpfmt/README Tue Nov 23 20:48:40 2010 +0000
@@ -0,0 +1,3 @@
+$Id: README,v 1.1 2010/11/23 20:48:40 yamt Exp $
+
+it's a C-version of tpfmt.sh. see usr.sbin/tprof/README for the usage.
diff -r 91b81d0be7cd -r 36862cb2dc8a usr.bin/tpfmt/sym.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/tpfmt/sym.c Tue Nov 23 20:48:40 2010 +0000
@@ -0,0 +1,155 @@
+/* $NetBSD: sym.c,v 1.1 2010/11/23 20:48:40 yamt Exp $ */
+
+/*-
+ * Copyright (c)2010 YAMAMOTO Takashi,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: sym.c,v 1.1 2010/11/23 20:48:40 yamt Exp $");
+#endif /* not lint */
+
+#include <assert.h>
+#include <err.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <inttypes.h>
+#include <libelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sym.h"
+
+struct sym {
+ char *name;
+ uint64_t value;
+ uint64_t size;
+};
+
+static struct sym **syms = NULL;
+static unsigned int nsyms = 0;
+
+static int
+compare_value(const void *p1, const void *p2)
+{
+ const struct sym *s1 = *(const struct sym * const *)p1;
+ const struct sym *s2 = *(const struct sym * const *)p2;
+
+ if (s1->value > s2->value) {
+ return -1;
+ } else if (s1->value < s2->value) {
+ return 1;
+ }
+ return 0;
+}
+
+void
+ksymload(const char *ksyms)
+{
+ Elf *e;
+ Elf_Scn *s;
+ GElf_Shdr sh_store;
+ GElf_Shdr *sh;
+ Elf_Data *d;
+ int fd;
+ size_t size;
+ unsigned int i;
+
+ fd = open(ksyms, O_RDONLY);
+ if (fd == -1) {
+ err(EXIT_FAILURE, "open");
+ }
+ if (elf_version(EV_CURRENT) == EV_NONE) {
+ goto elffail;
+ }
+ e = elf_begin(fd, ELF_C_READ, NULL);
+ if (e == NULL) {
+ goto elffail;
+ }
+ for (s = elf_nextscn(e, NULL); s != NULL; s = elf_nextscn(e, s)) {
+ sh = gelf_getshdr(s, &sh_store);
+ if (sh == NULL) {
+ goto elffail;
+ }
+ if (sh->sh_type == SHT_SYMTAB) {
+ break;
+ }
+ }
+ if (s == NULL) {
+ errx(EXIT_FAILURE, "no symtab");
+ }
+ d = elf_getdata(s, NULL);
+ if (d == NULL) {
+ goto elffail;
+ }
+ assert(sh->sh_size == d->d_size);
+ size = sh->sh_size / sh->sh_entsize;
+ for (i = 1; i < size; i++) {
+ GElf_Sym st_store;
+ GElf_Sym *st;
+ struct sym *sym;
+
+ st = gelf_getsym(d, i, &st_store);
+ if (st == NULL) {
+ goto elffail;
+ }
+ if (ELF_ST_TYPE(st->st_info) != STT_FUNC) {
+ continue;
+ }
+ sym = malloc(sizeof(*sym));
+ sym->name = strdup(elf_strptr(e, sh->sh_link, st->st_name));
+ sym->value = (uint64_t)st->st_value;
+ sym->size = st->st_size;
+ nsyms++;
+ syms = realloc(syms, sizeof(*syms) * nsyms);
+ if (syms == NULL) {
+ err(EXIT_FAILURE, "realloc");
+ }
+ syms[nsyms - 1] = sym;
+ }
+ qsort(syms, nsyms, sizeof(*syms), compare_value);
+ return;
+elffail:
+ errx(EXIT_FAILURE, "libelf: %s", elf_errmsg(elf_errno()));
+}
+
+const char *
+ksymlookup(uint64_t value, uint64_t *offset)
+{
+ unsigned int i;
+
+ for (i = 0; i < nsyms; i++) {
+ const struct sym *sym = syms[i];
+
+ if (sym->value <= value) {
+ *offset = value - sym->value;
+ return sym->name;
+ }
+ if (sym->size != 0 && sym->value + sym->size < value) {
+ break;
+ }
+ }
+ return NULL;
+}
diff -r 91b81d0be7cd -r 36862cb2dc8a usr.bin/tpfmt/sym.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/tpfmt/sym.h Tue Nov 23 20:48:40 2010 +0000
@@ -0,0 +1,30 @@
+/* $NetBSD: sym.h,v 1.1 2010/11/23 20:48:40 yamt Exp $ */
+
+/*-
+ * Copyright (c)2010 YAMAMOTO Takashi,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+void ksymload(const char *);
+const char *ksymlookup(uint64_t, uint64_t *);
diff -r 91b81d0be7cd -r 36862cb2dc8a usr.bin/tpfmt/tpfmt.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/tpfmt/tpfmt.c Tue Nov 23 20:48:40 2010 +0000
@@ -0,0 +1,174 @@
+/* $NetBSD: tpfmt.c,v 1.1 2010/11/23 20:48:40 yamt Exp $ */
+
+/*-
+ * Copyright (c)2010 YAMAMOTO Takashi,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: tpfmt.c,v 1.1 2010/11/23 20:48:40 yamt Exp $");
+#endif /* not lint */
+
+#include <sys/rbtree.h>
+
+#include <assert.h>
+#include <err.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sym.h"
+
+const char *ksyms = "/dev/ksyms";
+
+struct addr {
+ struct rb_node node;
+ uint64_t addr; /* address */
+ unsigned int nsamples; /* number of samples taken for the address */
+};
+
+rb_tree_t addrtree;
+
+static signed int
+addrtree_compare_key(void *ctx, const void *n1, const void *keyp)
+{
+ const struct addr *a1 = n1;
+ const uint64_t key = *(const uint64_t *)keyp;
+
+ if (a1->addr > key) {
+ return 1;
+ } else if (a1->addr < key) {
+ return -1;
+ }
+ return 0;
+}
+
+static signed int
+addrtree_compare_nodes(void *ctx, const void *n1, const void *n2)
+{
+ const struct addr *a2 = n2;
+
+ return addrtree_compare_key(ctx, n1, &a2->addr);
+}
+
Home |
Main Index |
Thread Index |
Old Index