diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2002-05-08 16:46:36 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2002-05-08 16:46:36 +0000 |
commit | 584e4fed1fb6695c8603287739b1b68ef791f48c (patch) | |
tree | 4fe9f999dfd7e5221b0cb16b978e75faf7a98dee /usr.bin | |
parent | 37392dec62ee72737d0bdef8be7fa39faa75df0b (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/Makefile | 16 | ||||
-rw-r--r-- | usr.bin/gprof/alpha.c | 7 | ||||
-rw-r--r-- | usr.bin/gprof/alpha.h | 51 | ||||
-rw-r--r-- | usr.bin/gprof/aout.c | 224 | ||||
-rw-r--r-- | usr.bin/gprof/elf.c | 140 | ||||
-rw-r--r-- | usr.bin/gprof/gprof.c | 201 | ||||
-rw-r--r-- | usr.bin/gprof/gprof.h | 14 | ||||
-rw-r--r-- | usr.bin/gprof/hppa.c | 7 | ||||
-rw-r--r-- | usr.bin/gprof/hppa.h | 51 | ||||
-rw-r--r-- | usr.bin/gprof/i386.c | 16 | ||||
-rw-r--r-- | usr.bin/gprof/powerpc.c | 7 | ||||
-rw-r--r-- | usr.bin/gprof/powerpc.h | 51 | ||||
-rw-r--r-- | usr.bin/gprof/sparc64.c | 7 | ||||
-rw-r--r-- | usr.bin/gprof/sparc64.h | 51 |
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; |