[BACK]Return to aout.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / gprof

Annotation of src/usr.bin/gprof/aout.c, Revision 1.2

1.1       art         1: /*-
                      2:  * Copyright (c) 1983, 1993
                      3:  *     The Regents of the University of California.  All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
1.2     ! millert    13:  * 3. Neither the name of the University nor the names of its contributors
1.1       art        14:  *    may be used to endorse or promote products derived from this software
                     15:  *    without specific prior written permission.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     27:  * SUCH DAMAGE.
                     28:  */
                     29:
                     30: #include <sys/types.h>
                     31: #include <a.out.h>
                     32:
                     33: #include "gprof.h"
                     34:
                     35: static void getstrtab(FILE *, const char *);
                     36: static void getsymtab(FILE *, const char *);
                     37: static void gettextspace(FILE *);
                     38: static bool funcsymbol(struct nlist *);
                     39:
                     40: static char    *strtab;                /* string table in core */
                     41: static long    ssiz;                   /* size of the string table */
                     42: static struct  exec xbuf;              /* exec header of a.out */
                     43:
                     44: /* Things which get -E excluded by default. */
                     45: static char    *excludes[] = { "mcount", "__mcleanup", NULL };
                     46:
                     47: /*
                     48:  * Set up string and symbol tables from a.out.
                     49:  *     and optionally the text space.
                     50:  * On return symbol table is sorted by value.
                     51:  *
                     52:  * Returns 0 on success, -1 on failure.
                     53:  */
                     54: int
                     55: getnfile(const char *filename, char ***defaultEs)
                     56: {
                     57:        FILE    *nfile;
                     58:
                     59:        nfile = fopen( filename ,"r");
                     60:        if (nfile == NULL)
                     61:                err(1, "fopen: %s", filename);
                     62:
                     63:        fread(&xbuf, 1, sizeof(xbuf), nfile);
                     64:        if (N_BADMAG(xbuf)) {
                     65:                /* Bail out and let other binary formats try. */
                     66:                fclose(nfile);
                     67:                return (-1);
                     68:        }
                     69:        getstrtab(nfile, filename);
                     70:        getsymtab(nfile, filename);
                     71:        gettextspace(nfile);
                     72:        fclose(nfile);
                     73: #ifdef DEBUG
                     74:        if (debug & AOUTDEBUG) {
                     75:                int j;
                     76:
                     77:                for (j = 0; j < nname; j++) {
                     78:                        printf("[getnfile] 0X%08lx\t%s\n", nl[j].value,
                     79:                            nl[j].name);
                     80:                }
                     81:        }
                     82: #endif
                     83:     *defaultEs = excludes;
                     84:     return (0);
                     85: }
                     86:
                     87: static void
                     88: getstrtab(FILE *nfile, const char *filename)
                     89: {
                     90:        fseek(nfile, (long)(N_SYMOFF(xbuf) + xbuf.a_syms), 0);
                     91:        if (fread(&ssiz, sizeof (ssiz), 1, nfile) == 0)
                     92:                errx(1, "%s: no string table (old format?)" , filename );
                     93:        strtab = calloc(ssiz, 1);
                     94:        if (strtab == NULL)
                     95:                errx(1, "%s: no room for %d bytes of string table", filename,
                     96:                    ssiz);
                     97:        if (fread(strtab + sizeof(ssiz), ssiz - sizeof(ssiz), 1, nfile) != 1)
                     98:                errx(1, "%s: error reading string table", filename );
                     99: }
                    100:
                    101: /*
                    102:  * Read in symbol table
                    103:  */
                    104: static void
                    105: getsymtab(FILE *nfile, const char *filename)
                    106: {
                    107:        struct nlist nbuf;
                    108:        int askfor;
                    109:        long i;
                    110:
                    111:        /* pass1 - count symbols */
                    112:        fseek(nfile, (long)N_SYMOFF(xbuf), 0);
                    113:        nname = 0;
                    114:        for (i = xbuf.a_syms; i > 0; i -= sizeof(struct nlist)) {
                    115:                fread(&nbuf, sizeof(nbuf), 1, nfile);
                    116:                if (funcsymbol(&nbuf))
                    117:                        nname++;
                    118:        }
                    119:        if (nname == 0)
                    120:                errx(1, "%s: no symbols", filename);
                    121:
                    122:        askfor = nname + 1;
                    123:        nl = calloc(askfor , sizeof(nltype));
                    124:        if (nl == 0)
                    125:                errx(1, "No room for %d bytes of symbol table",
                    126:                    askfor * sizeof(nltype));
                    127:
                    128:        /* pass2 - read symbols */
                    129:        fseek(nfile, (long)N_SYMOFF(xbuf), 0);
                    130:        npe = nl;
                    131:        nname = 0;
                    132:        for (i = xbuf.a_syms; i > 0; i -= sizeof(struct nlist)) {
                    133:                fread(&nbuf, sizeof(nbuf), 1, nfile);
                    134:                if (!funcsymbol(&nbuf)) {
                    135: #ifdef DEBUG
                    136:                        if (debug & AOUTDEBUG) {
                    137:                                printf("[getsymtab] rejecting: 0x%x %s\n",
                    138:                                    nbuf.n_type, strtab + nbuf.n_un.n_strx);
                    139:                        }
                    140: #endif
                    141:                        continue;
                    142:                }
                    143:                npe->value = nbuf.n_value;
                    144:                npe->name = strtab + nbuf.n_un.n_strx;
                    145: #ifdef DEBUG
                    146:                if (debug & AOUTDEBUG) {
                    147:                        printf("[getsymtab] %d %s 0x%08lx\n",
                    148:                            nname, npe->name, npe->value);
                    149:                }
                    150: #endif
                    151:                npe++;
                    152:                nname++;
                    153:        }
                    154:        npe->value = -1;
                    155: }
                    156:
                    157: /*
                    158:  * read in the text space of an a.out file
                    159:  */
                    160: static void
                    161: gettextspace(FILE *nfile)
                    162: {
                    163:        if (cflag == 0)
                    164:                return;
                    165:        textspace = malloc(xbuf.a_text);
                    166:        if (textspace == 0) {
                    167:                warnx("ran out room for %d bytes of text space: can't do -c" ,
                    168:                  xbuf.a_text);
                    169:                return;
                    170:        }
                    171:        (void)fseek(nfile, N_TXTOFF(xbuf), 0);
                    172:        if (fread(textspace, 1, xbuf.a_text, nfile) != xbuf.a_text ) {
                    173:                warnx("couldn't read text space: can't do -c");
                    174:                free(textspace);
                    175:                textspace = 0;
                    176:                return;
                    177:        }
                    178: }
                    179:
                    180: static bool
                    181: funcsymbol(struct nlist *nlistp)
                    182: {
                    183:        char *name, c;
                    184:
                    185:        /*
                    186:         *      must be a text symbol,
                    187:         *      and static text symbols don't qualify if aflag set.
                    188:         */
                    189:        if (!((nlistp->n_type == (N_TEXT|N_EXT))
                    190:            || ((nlistp->n_type == N_TEXT) && (aflag == 0))))
                    191:                return FALSE;
                    192:
                    193:        /*
                    194:         *      name must start with an underscore if uflag is set.
                    195:         *      can't have any `funny' characters in name,
                    196:         *      where `funny' means `.' (.o file names)
                    197:         *      need to make an exception for sparc .mul & co.
                    198:         *      perhaps we should just drop this code entirely...
                    199:         */
                    200:        name = strtab + nlistp -> n_un.n_strx;
                    201: #ifdef sparc
                    202:        if (nlistp -> n_value & 3)
                    203:                return (FALSE);
                    204:        if (*name == '.') {
                    205:                char *p = name + 1;
                    206:                if (*p == 'u')
                    207:                        p++;
                    208:                if (strcmp(p, "mul") == 0 || strcmp(p, "div") == 0 ||
                    209:                    strcmp(p, "rem") == 0 )
                    210:                        return (TRUE);
                    211:        }
                    212: #endif
                    213:        while (c = *name++) {
                    214:                if (c == '.') {
                    215:                        return (FALSE);
                    216:                }
                    217:        }
                    218:
                    219:        return (TRUE);
                    220: }