summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2002-05-08 16:46:36 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2002-05-08 16:46:36 +0000
commit584e4fed1fb6695c8603287739b1b68ef791f48c (patch)
tree4fe9f999dfd7e5221b0cb16b978e75faf7a98dee /usr.bin
parent37392dec62ee72737d0bdef8be7fa39faa75df0b (diff)
Split out symbol handling into a separate file.
Implement symbol handling for ELF (based on FreeBSD). Implement dummy support for alpha, hppa, powerpc and sparc64. Tested during the last 2 months on various archs (never comitted because other stuff got in the way). Some fixups to i386 support from mickey@ This lets us switch all elf archs to this gprof.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/gprof/Makefile16
-rw-r--r--usr.bin/gprof/alpha.c7
-rw-r--r--usr.bin/gprof/alpha.h51
-rw-r--r--usr.bin/gprof/aout.c224
-rw-r--r--usr.bin/gprof/elf.c140
-rw-r--r--usr.bin/gprof/gprof.c201
-rw-r--r--usr.bin/gprof/gprof.h14
-rw-r--r--usr.bin/gprof/hppa.c7
-rw-r--r--usr.bin/gprof/hppa.h51
-rw-r--r--usr.bin/gprof/i386.c16
-rw-r--r--usr.bin/gprof/powerpc.c7
-rw-r--r--usr.bin/gprof/powerpc.h51
-rw-r--r--usr.bin/gprof/sparc64.c7
-rw-r--r--usr.bin/gprof/sparc64.h51
14 files changed, 634 insertions, 209 deletions
diff --git a/usr.bin/gprof/Makefile b/usr.bin/gprof/Makefile
index b63d3d77243..04109c0f75c 100644
--- a/usr.bin/gprof/Makefile
+++ b/usr.bin/gprof/Makefile
@@ -1,17 +1,19 @@
-# $OpenBSD: Makefile,v 1.12 2001/09/10 23:31:34 drahn Exp $
+# $OpenBSD: Makefile,v 1.13 2002/05/08 16:46:35 art Exp $
+
+.include <bsd.own.mk>
TARGET_MACHINE_ARCH?= ${MACHINE_ARCH}
-.if (${TARGET_MACHINE_ARCH} == "alpha") || \
- (${TARGET_MACHINE_ARCH} == "powerpc") || \
- (${TARGET_MACHINE_ARCH} == "sparc64") || \
- (${TARGET_MACHINE_ARCH} == "hppa")
-NOPROG=
-.else
PROG= gprof
SRCS= gprof.c arcs.c dfn.c lookup.c machine.c hertz.c \
printgprof.c printlist.c
CFLAGS+= -I${.CURDIR} -I.
+
+# XXX - need support for multiple archs.
+.if (${ELF_TOOLCHAIN} == "yes")
+SRCS+=elf.c
+.else
+SRCS+=aout.c
.endif
.if defined(PROG)
diff --git a/usr.bin/gprof/alpha.c b/usr.bin/gprof/alpha.c
new file mode 100644
index 00000000000..4586923c014
--- /dev/null
+++ b/usr.bin/gprof/alpha.c
@@ -0,0 +1,7 @@
+#include "gprof.h"
+
+void
+findcall(nltype *parentp, unsigned long p_lowpc, unsigned long p_highpc)
+{
+ /* not supported. */
+}
diff --git a/usr.bin/gprof/alpha.h b/usr.bin/gprof/alpha.h
new file mode 100644
index 00000000000..d985942094c
--- /dev/null
+++ b/usr.bin/gprof/alpha.h
@@ -0,0 +1,51 @@
+/* $OpenBSD: alpha.h,v 1.4 2002/05/08 16:46:35 art Exp $ */
+/* $NetBSD: sparc.h,v 1.3 1995/04/19 07:16:25 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)sparc.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * offset (in bytes) of the code from the entry address of a routine.
+ * (see asgnsamples for use and explanation.)
+ */
+#define OFFSET_OF_CODE 0
+#define UNITS_TO_CODE (OFFSET_OF_CODE / sizeof(UNIT))
+
+enum opermodes { dummy };
+typedef enum opermodes operandenum;
diff --git a/usr.bin/gprof/aout.c b/usr.bin/gprof/aout.c
new file mode 100644
index 00000000000..a84e648d0c4
--- /dev/null
+++ b/usr.bin/gprof/aout.c
@@ -0,0 +1,224 @@
+/*-
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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/types.h>
+#include <a.out.h>
+
+#include "gprof.h"
+
+static void getstrtab(FILE *, const char *);
+static void getsymtab(FILE *, const char *);
+static void gettextspace(FILE *);
+static bool funcsymbol(struct nlist *);
+
+static char *strtab; /* string table in core */
+static long ssiz; /* size of the string table */
+static struct exec xbuf; /* exec header of a.out */
+
+/* Things which get -E excluded by default. */
+static char *excludes[] = { "mcount", "__mcleanup", NULL };
+
+/*
+ * Set up string and symbol tables from a.out.
+ * and optionally the text space.
+ * On return symbol table is sorted by value.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+int
+getnfile(const char *filename, char ***defaultEs)
+{
+ FILE *nfile;
+
+ nfile = fopen( filename ,"r");
+ if (nfile == NULL)
+ err(1, "fopen: %s", filename);
+
+ fread(&xbuf, 1, sizeof(xbuf), nfile);
+ if (N_BADMAG(xbuf)) {
+ /* Bail out and let other binary formats try. */
+ fclose(nfile);
+ return (-1);
+ }
+ getstrtab(nfile, filename);
+ getsymtab(nfile, filename);
+ gettextspace(nfile);
+ fclose(nfile);
+#ifdef DEBUG
+ if (debug & AOUTDEBUG) {
+ int j;
+
+ for (j = 0; j < nname; j++) {
+ printf("[getnfile] 0X%08lx\t%s\n", nl[j].value,
+ nl[j].name);
+ }
+ }
+#endif
+ *defaultEs = excludes;
+ return (0);
+}
+
+static void
+getstrtab(FILE *nfile, const char *filename)
+{
+ fseek(nfile, (long)(N_SYMOFF(xbuf) + xbuf.a_syms), 0);
+ if (fread(&ssiz, sizeof (ssiz), 1, nfile) == 0)
+ errx(1, "%s: no string table (old format?)" , filename );
+ strtab = calloc(ssiz, 1);
+ if (strtab == NULL)
+ errx(1, "%s: no room for %d bytes of string table", filename,
+ ssiz);
+ if (fread(strtab + sizeof(ssiz), ssiz - sizeof(ssiz), 1, nfile) != 1)
+ errx(1, "%s: error reading string table", filename );
+}
+
+/*
+ * Read in symbol table
+ */
+static void
+getsymtab(FILE *nfile, const char *filename)
+{
+ struct nlist nbuf;
+ int askfor;
+ long i;
+
+ /* pass1 - count symbols */
+ fseek(nfile, (long)N_SYMOFF(xbuf), 0);
+ nname = 0;
+ for (i = xbuf.a_syms; i > 0; i -= sizeof(struct nlist)) {
+ fread(&nbuf, sizeof(nbuf), 1, nfile);
+ if (funcsymbol(&nbuf))
+ nname++;
+ }
+ if (nname == 0)
+ errx(1, "%s: no symbols", filename);
+
+ askfor = nname + 1;
+ nl = calloc(askfor , sizeof(nltype));
+ if (nl == 0)
+ errx(1, "No room for %d bytes of symbol table",
+ askfor * sizeof(nltype));
+
+ /* pass2 - read symbols */
+ fseek(nfile, (long)N_SYMOFF(xbuf), 0);
+ npe = nl;
+ nname = 0;
+ for (i = xbuf.a_syms; i > 0; i -= sizeof(struct nlist)) {
+ fread(&nbuf, sizeof(nbuf), 1, nfile);
+ if (!funcsymbol(&nbuf)) {
+#ifdef DEBUG
+ if (debug & AOUTDEBUG) {
+ printf("[getsymtab] rejecting: 0x%x %s\n",
+ nbuf.n_type, strtab + nbuf.n_un.n_strx);
+ }
+#endif
+ continue;
+ }
+ npe->value = nbuf.n_value;
+ npe->name = strtab + nbuf.n_un.n_strx;
+#ifdef DEBUG
+ if (debug & AOUTDEBUG) {
+ printf("[getsymtab] %d %s 0x%08lx\n",
+ nname, npe->name, npe->value);
+ }
+#endif
+ npe++;
+ nname++;
+ }
+ npe->value = -1;
+}
+
+/*
+ * read in the text space of an a.out file
+ */
+static void
+gettextspace(FILE *nfile)
+{
+ if (cflag == 0)
+ return;
+ textspace = malloc(xbuf.a_text);
+ if (textspace == 0) {
+ warnx("ran out room for %d bytes of text space: can't do -c" ,
+ xbuf.a_text);
+ return;
+ }
+ (void)fseek(nfile, N_TXTOFF(xbuf), 0);
+ if (fread(textspace, 1, xbuf.a_text, nfile) != xbuf.a_text ) {
+ warnx("couldn't read text space: can't do -c");
+ free(textspace);
+ textspace = 0;
+ return;
+ }
+}
+
+static bool
+funcsymbol(struct nlist *nlistp)
+{
+ char *name, c;
+
+ /*
+ * must be a text symbol,
+ * and static text symbols don't qualify if aflag set.
+ */
+ if (!((nlistp->n_type == (N_TEXT|N_EXT))
+ || ((nlistp->n_type == N_TEXT) && (aflag == 0))))
+ return FALSE;
+
+ /*
+ * name must start with an underscore if uflag is set.
+ * can't have any `funny' characters in name,
+ * where `funny' means `.' (.o file names)
+ * need to make an exception for sparc .mul & co.
+ * perhaps we should just drop this code entirely...
+ */
+ name = strtab + nlistp -> n_un.n_strx;
+#ifdef sparc
+ if (nlistp -> n_value & 3)
+ return (FALSE);
+ if (*name == '.') {
+ char *p = name + 1;
+ if (*p == 'u')
+ p++;
+ if (strcmp(p, "mul") == 0 || strcmp(p, "div") == 0 ||
+ strcmp(p, "rem") == 0 )
+ return (TRUE);
+ }
+#endif
+ while (c = *name++) {
+ if (c == '.') {
+ return (FALSE);
+ }
+ }
+
+ return (TRUE);
+}
diff --git a/usr.bin/gprof/elf.c b/usr.bin/gprof/elf.c
new file mode 100644
index 00000000000..dba5a3cd143
--- /dev/null
+++ b/usr.bin/gprof/elf.c
@@ -0,0 +1,140 @@
+/*-
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/exec_elf.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "gprof.h"
+
+static bool wantsym(const Elf_Sym *, const char *);
+
+/* Things which get -E excluded by default. */
+static char *excludes[] = { ".mcount", "_mcleanup", NULL };
+
+int
+getnfile(const char *filename, char ***defaultEs)
+{
+ int fd;
+ Elf_Ehdr h;
+ struct stat s;
+ void *mapbase;
+ const char *base;
+ const Elf_Shdr *shdrs;
+ const Elf_Shdr *sh_symtab;
+ const Elf_Shdr *sh_strtab;
+ const char *strtab;
+ const Elf_Sym *symtab;
+ int symtabct;
+ int i;
+
+ if ((fd = open(filename, O_RDONLY)) == -1)
+ err(1, "%s", filename);
+ if (read(fd, &h, sizeof h) != sizeof h || !IS_ELF(h)) {
+ close(fd);
+ return -1;
+ }
+ if (fstat(fd, &s) == -1)
+ err(1, "Cannot fstat %s", filename);
+ if ((mapbase = mmap(0, s.st_size, PROT_READ, MAP_SHARED, fd, 0)) ==
+ MAP_FAILED)
+ err(1, "Cannot mmap %s", filename);
+ close(fd);
+
+ base = (const char *)mapbase;
+ shdrs = (const Elf_Shdr *)(base + h.e_shoff);
+
+ /* Find the symbol table and associated string table section. */
+ for (i = 1; i < h.e_shnum; i++)
+ if (shdrs[i].sh_type == SHT_SYMTAB)
+ break;
+ if (i == h.e_shnum)
+ errx(1, "%s has no symbol table", filename);
+ sh_symtab = &shdrs[i];
+ sh_strtab = &shdrs[sh_symtab->sh_link];
+
+ symtab = (const Elf_Sym *)(base + sh_symtab->sh_offset);
+ symtabct = sh_symtab->sh_size / sh_symtab->sh_entsize;
+ strtab = (const char *)(base + sh_strtab->sh_offset);
+
+ /* Count the symbols that we're interested in. */
+ nname = 0;
+ for (i = 1; i < symtabct; i++)
+ if (wantsym(&symtab[i], strtab))
+ nname++;
+
+ /* Allocate memory for them, plus a terminating entry. */
+ if ((nl = (nltype *)calloc(nname + 1, sizeof(nltype))) == NULL)
+ errx(1, "Insufficient memory for symbol table");
+
+ /* Read them in. */
+ npe = nl;
+ for (i = 1; i < symtabct; i++) {
+ const Elf_Sym *sym = &symtab[i];
+
+ if (wantsym(sym, strtab)) {
+ npe->value = sym->st_value;
+ npe->name = strtab + sym->st_name;
+ npe++;
+ }
+ }
+ npe->value = -1;
+
+ *defaultEs = excludes;
+ return 0;
+}
+
+static bool
+wantsym(const Elf_Sym *sym, const char *strtab)
+{
+ int type;
+ int bind;
+
+ type = ELF_ST_TYPE(sym->st_info);
+ bind = ELF_ST_BIND(sym->st_info);
+
+ if (type != STT_FUNC || (aflag && bind == STB_LOCAL))
+#if 0
+ ||
+ (uflag && strchr(strtab + sym->st_name, '.') != NULL))
+#endif
+ return 0;
+
+ return 1;
+}
diff --git a/usr.bin/gprof/gprof.c b/usr.bin/gprof/gprof.c
index 13d5092b6fa..45bb6f7d09b 100644
--- a/usr.bin/gprof/gprof.c
+++ b/usr.bin/gprof/gprof.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gprof.c,v 1.10 2002/03/25 16:30:55 danh Exp $ */
+/* $OpenBSD: gprof.c,v 1.11 2002/05/08 16:46:35 art Exp $ */
/* $NetBSD: gprof.c,v 1.8 1995/04/19 07:15:59 cgd Exp $ */
/*
@@ -44,16 +44,13 @@ static char copyright[] =
#if 0
static char sccsid[] = "@(#)gprof.c 8.1 (Berkeley) 6/6/93";
#else
-static char rcsid[] = "$OpenBSD: gprof.c,v 1.10 2002/03/25 16:30:55 danh Exp $";
+static char rcsid[] = "$OpenBSD: gprof.c,v 1.11 2002/05/08 16:46:35 art Exp $";
#endif
#endif /* not lint */
#include "gprof.h"
- /*
- * things which get -E excluded by default.
- */
-char *defaultEs[] = { "mcount" , "__mcleanup" , 0 };
+int valcmp(const void *, const void *);
static struct gmonhdr gmonhdr;
extern char *__progname;
@@ -65,6 +62,7 @@ main(argc, argv)
{
char **sp;
nltype **timesortnlp;
+ char **defaultEs;
--argc;
argv++;
@@ -151,6 +149,15 @@ main(argc, argv)
gmonname = GMONNAME;
}
/*
+ * get information about a.out file.
+ */
+ if (getnfile(a_outname, &defaultEs) == -1)
+ errx(1, "%s: bad format", a_outname);
+ /*
+ * sort symbol table.
+ */
+ qsort(nl, nname, sizeof(nltype), valcmp);
+ /*
* turn off default functions
*/
for ( sp = &defaultEs[0] ; *sp ; sp++ ) {
@@ -160,10 +167,6 @@ main(argc, argv)
addlist( elist , *sp );
}
/*
- * get information about a.out file.
- */
- getnfile();
- /*
* get information about mon.out file(s).
*/
do {
@@ -211,136 +214,6 @@ main(argc, argv)
}
/*
- * Set up string and symbol tables from a.out.
- * and optionally the text space.
- * On return symbol table is sorted by value.
- */
-void
-getnfile()
-{
- FILE *nfile;
- int valcmp();
-
- nfile = fopen( a_outname ,"r");
- if (nfile == NULL)
- err(1, "fopen: %s", a_outname);
- fread(&xbuf, 1, sizeof(xbuf), nfile);
- if (N_BADMAG(xbuf))
- errx(1, "%s: bad format", a_outname );
- getstrtab(nfile);
- getsymtab(nfile);
- gettextspace( nfile );
- qsort(nl, nname, sizeof(nltype), valcmp);
- fclose(nfile);
-# ifdef DEBUG
- if ( debug & AOUTDEBUG ) {
- int j;
-
- for (j = 0; j < nname; j++){
- printf("[getnfile] 0X%08x\t%s\n", nl[j].value, nl[j].name);
- }
- }
-# endif /* DEBUG */
-}
-
-void
-getstrtab(nfile)
- FILE *nfile;
-{
-
- fseek(nfile, (long)(N_SYMOFF(xbuf) + xbuf.a_syms), 0);
- if (fread(&ssiz, sizeof (ssiz), 1, nfile) == 0)
- errx(1, "%s: no string table (old format?)" , a_outname);
- strtab = calloc(ssiz, 1);
- if (strtab == NULL)
- errx(1, "%s: no room for %ld bytes of string table", a_outname , ssiz);
- if (fread(strtab+sizeof(ssiz), ssiz-sizeof(ssiz), 1, nfile) != 1)
- err(1, "%s: reading string table", a_outname);
-}
-
- /*
- * Read in symbol table
- */
-void
-getsymtab(nfile)
- FILE *nfile;
-{
- long i;
- int askfor;
- struct nlist nbuf;
-
- /* pass1 - count symbols */
- fseek(nfile, (long)N_SYMOFF(xbuf), 0);
- nname = 0;
- for (i = xbuf.a_syms; i > 0; i -= sizeof(struct nlist)) {
- fread(&nbuf, sizeof(nbuf), 1, nfile);
- if ( ! funcsymbol( &nbuf ) ) {
- continue;
- }
- nname++;
- }
- if (nname == 0)
- errx(1, "%s: no symbols", a_outname);
- askfor = nname + 1;
- nl = (nltype *) calloc( askfor , sizeof(nltype) );
- if (nl == 0)
- errx(1, "No room for %d bytes of symbol table",
- askfor * sizeof(nltype));
-
- /* pass2 - read symbols */
- fseek(nfile, (long)N_SYMOFF(xbuf), 0);
- npe = nl;
- nname = 0;
- for (i = xbuf.a_syms; i > 0; i -= sizeof(struct nlist)) {
- fread(&nbuf, sizeof(nbuf), 1, nfile);
- if ( ! funcsymbol( &nbuf ) ) {
-# ifdef DEBUG
- if ( debug & AOUTDEBUG ) {
- printf( "[getsymtab] rejecting: 0x%x %s\n" ,
- nbuf.n_type , strtab + nbuf.n_un.n_strx );
- }
-# endif /* DEBUG */
- continue;
- }
- npe->value = nbuf.n_value;
- npe->name = strtab+nbuf.n_un.n_strx;
-# ifdef DEBUG
- if ( debug & AOUTDEBUG ) {
- printf( "[getsymtab] %d %s 0x%08x\n" ,
- nname , npe -> name , npe -> value );
- }
-# endif /* DEBUG */
- npe++;
- nname++;
- }
- npe->value = -1;
-}
-
- /*
- * read in the text space of an a.out file
- */
-void
-gettextspace( nfile )
- FILE *nfile;
-{
-
- if ( cflag == 0 ) {
- return;
- }
- textspace = (u_char *) malloc( xbuf.a_text );
- if ( textspace == 0 ) {
- warnx("ran out room for %d bytes of text space: can't do -c", xbuf.a_text );
- return;
- }
- (void) fseek( nfile , N_TXTOFF( xbuf ) , 0 );
- if ( fread( textspace , 1 , xbuf.a_text , nfile ) != xbuf.a_text ) {
- warnx("couldn't read text space: can't do -c");
- free( textspace );
- textspace = NULL;
- return;
- }
-}
- /*
* information from a gmon.out file is in two parts:
* an array of sampling hits within pc ranges,
* and the arcs.
@@ -498,9 +371,11 @@ dumpsum( sumfile )
}
int
-valcmp(p1, p2)
- nltype *p1, *p2;
+valcmp(const void *vp1, const void *vp2)
{
+ const nltype *p1 = vp1;
+ const nltype *p2 = vp2;
+
if ( p1 -> value < p2 -> value ) {
return LESSTHAN;
}
@@ -676,45 +551,3 @@ alignentries()
}
}
}
-
-bool
-funcsymbol( nlistp )
- struct nlist *nlistp;
-{
- extern char *strtab; /* string table from a.out */
- extern int aflag; /* if static functions aren't desired */
- char *name, c;
-
- /*
- * must be a text symbol,
- * and static text symbols don't qualify if aflag set.
- */
- if ( ! ( ( nlistp -> n_type == ( N_TEXT | N_EXT ) )
- || ( ( nlistp -> n_type == N_TEXT ) && ( aflag == 0 ) ) ) ) {
- return FALSE;
- }
- /*
- * can't have any `funny' characters in name,
- * where `funny' means `.', .o file names
- * need to make an exception for sparc .mul & co.
- * perhaps we should just drop this code entirely...
- */
- name = strtab + nlistp -> n_un.n_strx;
-#ifdef __sparc__
- if (nlistp -> n_value & 3)
- return FALSE;
- if ( *name == '.' ) {
- char *p = name + 1;
- if ( *p == 'u' )
- p++;
- if ( strcmp ( p, "mul" ) == 0 || strcmp ( p, "div" ) == 0 ||
- strcmp ( p, "rem" ) == 0 )
- return TRUE;
- }
-#endif
- while ((c = *name++))
- if (c == '.')
- return FALSE;
-
- return TRUE;
-}
diff --git a/usr.bin/gprof/gprof.h b/usr.bin/gprof/gprof.h
index c7e8024bf90..7cf52d7718a 100644
--- a/usr.bin/gprof/gprof.h
+++ b/usr.bin/gprof/gprof.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: gprof.h,v 1.7 2002/02/16 21:27:46 millert Exp $ */
+/* $OpenBSD: gprof.h,v 1.8 2002/05/08 16:46:35 art Exp $ */
/* $NetBSD: gprof.h,v 1.13 1996/04/01 21:54:06 mark Exp $ */
/*
@@ -100,7 +100,7 @@ typedef struct arcstruct arctype;
* its address, the number of calls and compute its share of cpu time.
*/
struct nl {
- char *name; /* the name */
+ const char *name; /* the name */
unsigned long value; /* the pc entry point */
unsigned long svalue; /* entry point aligned to histograms */
double time; /* ticks in this routine */
@@ -196,9 +196,6 @@ double totime; /* total time for all routines */
double printtime; /* total of time being printed */
double scale; /* scale factor converting samples to pc
values: each sample covers scale bytes */
-char *strtab; /* string table in core */
-long ssiz; /* size of the string table */
-struct exec xbuf; /* exec header of a.out */
unsigned char *textspace; /* text space of a.out in core */
int cyclethreshold; /* with -C, minimum cycle size to ignore */
@@ -263,12 +260,8 @@ void dumpsum();
void findcall(nltype *, u_long, u_long);
void flatprofheader();
void flatprofline();
-bool funcsymbol();
-void getnfile();
+int getnfile(const char *, char ***);
void getpfile();
-void getstrtab();
-void getsymtab();
-void gettextspace();
void gprofheader();
void gprofline();
int hertz();
@@ -300,7 +293,6 @@ int timecmp();
void timepropagate(nltype *);
int topcmp();
int totalcmp();
-int valcmp(nltype *p1, nltype *p2);
#define LESSTHAN -1
#define EQUALTO 0
diff --git a/usr.bin/gprof/hppa.c b/usr.bin/gprof/hppa.c
new file mode 100644
index 00000000000..4586923c014
--- /dev/null
+++ b/usr.bin/gprof/hppa.c
@@ -0,0 +1,7 @@
+#include "gprof.h"
+
+void
+findcall(nltype *parentp, unsigned long p_lowpc, unsigned long p_highpc)
+{
+ /* not supported. */
+}
diff --git a/usr.bin/gprof/hppa.h b/usr.bin/gprof/hppa.h
new file mode 100644
index 00000000000..daac13612bd
--- /dev/null
+++ b/usr.bin/gprof/hppa.h
@@ -0,0 +1,51 @@
+/* $OpenBSD: hppa.h,v 1.3 2002/05/08 16:46:35 art Exp $ */
+/* $NetBSD: sparc.h,v 1.3 1995/04/19 07:16:25 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)sparc.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * offset (in bytes) of the code from the entry address of a routine.
+ * (see asgnsamples for use and explanation.)
+ */
+#define OFFSET_OF_CODE 0
+#define UNITS_TO_CODE (OFFSET_OF_CODE / sizeof(UNIT))
+
+enum opermodes { dummy };
+typedef enum opermodes operandenum;
diff --git a/usr.bin/gprof/i386.c b/usr.bin/gprof/i386.c
index 809baeeecd3..f33548189fe 100644
--- a/usr.bin/gprof/i386.c
+++ b/usr.bin/gprof/i386.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i386.c,v 1.6 2002/04/20 03:37:40 tholo Exp $ */
+/* $OpenBSD: i386.c,v 1.7 2002/05/08 16:46:35 art Exp $ */
/* $NetBSD: i386.c,v 1.5 1995/04/19 07:16:04 cgd Exp $ */
/*-
@@ -29,12 +29,12 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: i386.c,v 1.6 2002/04/20 03:37:40 tholo Exp $";
+static char rcsid[] = "$OpenBSD: i386.c,v 1.7 2002/05/08 16:46:35 art Exp $";
#endif /* not lint */
#include "gprof.h"
-#define iscall(pc) ((*pc) == 0xE8)
+#define iscall(off) ((*(u_char *)&textspace[off]) == 0xE8)
void
findcall( parentp , p_lowpc , p_highpc )
@@ -42,10 +42,11 @@ findcall( parentp , p_lowpc , p_highpc )
unsigned long p_lowpc;
unsigned long p_highpc;
{
- unsigned char *pc;
+ unsigned long pc;
long len;
nltype *childp;
unsigned long destpc;
+ int off;
if (textspace == 0)
return;
@@ -59,10 +60,11 @@ findcall( parentp , p_lowpc , p_highpc )
parentp -> name , p_lowpc , p_highpc );
}
# endif /* DEBUG */
- for (pc = textspace + p_lowpc - N_TXTADDR(xbuf) ; pc < textspace + p_highpc - N_TXTADDR(xbuf) ; pc += len) {
+ for (pc = p_lowpc; pc < p_highpc; pc += len) {
+ off = pc - s_lowpc;
len = 1;
- if (iscall(pc)) {
- destpc = *(unsigned long *)(pc + 1) + (pc - textspace + N_TXTADDR(xbuf)) + 5;
+ if (iscall(off)) {
+ destpc = *(u_long *)&textspace[off + 1] + off + 5;
# ifdef DEBUG
if ( debug & CALLDEBUG ) {
printf( "[findcall]\t0x%x:calls" , pc - textspace );
diff --git a/usr.bin/gprof/powerpc.c b/usr.bin/gprof/powerpc.c
new file mode 100644
index 00000000000..4586923c014
--- /dev/null
+++ b/usr.bin/gprof/powerpc.c
@@ -0,0 +1,7 @@
+#include "gprof.h"
+
+void
+findcall(nltype *parentp, unsigned long p_lowpc, unsigned long p_highpc)
+{
+ /* not supported. */
+}
diff --git a/usr.bin/gprof/powerpc.h b/usr.bin/gprof/powerpc.h
new file mode 100644
index 00000000000..020f2f73650
--- /dev/null
+++ b/usr.bin/gprof/powerpc.h
@@ -0,0 +1,51 @@
+/* $OpenBSD: powerpc.h,v 1.3 2002/05/08 16:46:35 art Exp $ */
+/* $NetBSD: sparc.h,v 1.3 1995/04/19 07:16:25 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)sparc.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * offset (in bytes) of the code from the entry address of a routine.
+ * (see asgnsamples for use and explanation.)
+ */
+#define OFFSET_OF_CODE 0
+#define UNITS_TO_CODE (OFFSET_OF_CODE / sizeof(UNIT))
+
+enum opermodes { dummy };
+typedef enum opermodes operandenum;
diff --git a/usr.bin/gprof/sparc64.c b/usr.bin/gprof/sparc64.c
new file mode 100644
index 00000000000..4586923c014
--- /dev/null
+++ b/usr.bin/gprof/sparc64.c
@@ -0,0 +1,7 @@
+#include "gprof.h"
+
+void
+findcall(nltype *parentp, unsigned long p_lowpc, unsigned long p_highpc)
+{
+ /* not supported. */
+}
diff --git a/usr.bin/gprof/sparc64.h b/usr.bin/gprof/sparc64.h
new file mode 100644
index 00000000000..db57ac42bec
--- /dev/null
+++ b/usr.bin/gprof/sparc64.h
@@ -0,0 +1,51 @@
+/* $OpenBSD: sparc64.h,v 1.1 2002/05/08 16:46:35 art Exp $ */
+/* $NetBSD: sparc.h,v 1.3 1995/04/19 07:16:25 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)sparc.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * offset (in bytes) of the code from the entry address of a routine.
+ * (see asgnsamples for use and explanation.)
+ */
+#define OFFSET_OF_CODE 0
+#define UNITS_TO_CODE (OFFSET_OF_CODE / sizeof(UNIT))
+
+enum opermodes { dummy };
+typedef enum opermodes operandenum;