[BACK]Return to db_aout.c CVS log [TXT][DIR] Up to [local] / sys / ddb

Annotation of sys/ddb/db_aout.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: db_aout.c,v 1.30 2006/07/06 18:12:50 miod Exp $       */
                      2: /*     $NetBSD: db_aout.c,v 1.29 2000/07/07 21:55:18 jhawk Exp $       */
                      3:
                      4: /*
                      5:  * Mach Operating System
                      6:  * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
                      7:  * All Rights Reserved.
                      8:  *
                      9:  * Permission to use, copy, modify and distribute this software and its
                     10:  * documentation is hereby granted, provided that both the copyright
                     11:  * notice and this permission notice appear in all copies of the
                     12:  * software, derivative works or modified versions, and any portions
                     13:  * thereof, and that both notices appear in supporting documentation.
                     14:  *
                     15:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     16:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     17:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     18:  *
                     19:  * Carnegie Mellon requests users of this software to return to
                     20:  *
                     21:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     22:  *  School of Computer Science
                     23:  *  Carnegie Mellon University
                     24:  *  Pittsburgh PA 15213-3890
                     25:  *
                     26:  * any improvements or extensions that they make and grant Carnegie Mellon
                     27:  * the rights to redistribute these changes.
                     28:  */
                     29:
                     30: #include <sys/types.h>
                     31: #include <sys/param.h>
                     32: #include <sys/systm.h>
                     33: #include <sys/proc.h>
                     34:
                     35: #include <machine/db_machdep.h>                /* data types */
                     36:
                     37: #include <ddb/db_sym.h>
                     38: #include <ddb/db_output.h>
                     39: #include <ddb/db_extern.h>
                     40:
                     41: #ifdef DB_AOUT_SYMBOLS
                     42:
                     43: #include <ddb/db_aout.h>
                     44:
                     45: boolean_t      db_aout_sym_init(int, void *, void *, const char *);
                     46: db_sym_t       db_aout_lookup(db_symtab_t *, char *);
                     47: db_sym_t       db_aout_search_symbol(db_symtab_t *, db_addr_t,
                     48:                    db_strategy_t, db_expr_t *);
                     49: void           db_aout_symbol_values(db_symtab_t *, db_sym_t,
                     50:                    char **, db_expr_t *);
                     51: boolean_t      db_aout_line_at_pc(db_symtab_t *, db_sym_t,
                     52:                    char **, int *, db_expr_t);
                     53: boolean_t      db_aout_sym_numargs(db_symtab_t *, db_sym_t, int *,
                     54:                    char **);
                     55: void           db_aout_forall(db_symtab_t *,
                     56:                    db_forall_func_t db_forall_func, void *);
                     57:
                     58: db_symformat_t db_symformat_aout = {
                     59:        "a.out",
                     60:        db_aout_sym_init,
                     61:        db_aout_lookup,
                     62:        db_aout_search_symbol,
                     63:        db_aout_symbol_values,
                     64:        db_aout_line_at_pc,
                     65:        db_aout_sym_numargs,
                     66:        db_aout_forall
                     67: };
                     68:
                     69: /*
                     70:  * An a.out symbol table as loaded into the kernel debugger:
                     71:  *
                     72:  * symtab      -> size of symbol entries, in bytes
                     73:  * sp          -> first symbol entry
                     74:  *                ...
                     75:  * ep          -> last symbol entry + 1
                     76:  * strtab      == start of string table
                     77:  *                size of string table in bytes,
                     78:  *                including this word
                     79:  *             -> strings
                     80:  */
                     81: static char *strtab;
                     82: static int slen;
                     83:
                     84: #define X_db_getname(t, s)     (s->n_un.n_strx ? t->end + s->n_un.n_strx : NULL)
                     85:
                     86: /*
                     87:  * Find the symbol table and strings; tell ddb about them.
                     88:  *
                     89:  * symsize:    size of symbol table
                     90:  * vsymtab:    pointer to end of string table
                     91:  * vesymtab:   pointer to end of string table, for checking - rounded up to
                     92:  *                 integer boundry
                     93:  */
                     94: boolean_t
                     95: db_aout_sym_init(int symsize, void *vsymtab, void *vesymtab, const char *name)
                     96: {
                     97:        struct nlist    *sym_start, *sym_end;
                     98:        struct nlist    *sp;
                     99:        int bad = 0;
                    100:        char *estrtab;
                    101:
                    102:        /*
                    103:         * XXX - ddb_init should take arguments.
                    104:         *       Fixup the arguments.
                    105:         */
                    106:        symsize = *(long *)vsymtab;
                    107:        vsymtab = (void *)((long *)vsymtab + 1);
                    108:
                    109:
                    110:        if (ALIGNED_POINTER(vsymtab, long) == 0) {
                    111:                printf("[ %s symbol table has bad start address %p ]\n",
                    112:                    name, vsymtab);
                    113:                return (FALSE);
                    114:        }
                    115:
                    116:        /*
                    117:         * Find pointers to the start and end of the symbol entries,
                    118:         * given a pointer to the start of the symbol table.
                    119:         */
                    120:        sym_start = (struct nlist *)vsymtab;
                    121:        sym_end   = (struct nlist *)((char *)sym_start + symsize);
                    122:
                    123:        strtab = (char *)sym_end;
                    124:        if (ALIGNED_POINTER(strtab, int) == 0) {
                    125:                printf("[ %s symbol table has bad string table address %p ]\n",
                    126:                    name, strtab);
                    127:                return (FALSE);
                    128:        }
                    129:        slen = *(int *)strtab;
                    130:
                    131:        estrtab = strtab + slen;
                    132:
                    133: #define        round_to_size(x) \
                    134:     (((vaddr_t)(x) + sizeof(vsize_t) - 1) & ~(sizeof(vsize_t) - 1))
                    135:
                    136:        if (round_to_size(estrtab) != round_to_size(vesymtab)) {
                    137:                printf("[ %s a.out symbol table not valid ]\n", name);
                    138:                return (FALSE);
                    139:         }
                    140: #undef round_to_size
                    141:
                    142:        for (sp = sym_start; sp < sym_end; sp++) {
                    143:                int strx;
                    144:                strx = sp->n_un.n_strx;
                    145:                if (strx != 0) {
                    146:                        if (strx > slen) {
                    147:                                printf("[ %s has bad a.out string table index "
                    148:                                    "(0x%x) ]\n",
                    149:                                    name, strx);
                    150:                                bad = 1;
                    151:                                continue;
                    152:                        }
                    153:                }
                    154:        }
                    155:
                    156:        if (bad)
                    157:                return (FALSE);
                    158:
                    159:        if (db_add_symbol_table((char *)sym_start, (char *)sym_end, name,
                    160:            NULL) !=  -1) {
                    161:                 printf("[ using %ld bytes of %s a.out symbol table ]\n",
                    162:                     (long)vesymtab - (long)vsymtab, name);
                    163:                return (TRUE);
                    164:         }
                    165:
                    166:        return (FALSE);
                    167: }
                    168:
                    169: db_sym_t
                    170: db_aout_lookup(db_symtab_t *stab, char *symstr)
                    171: {
                    172:        struct nlist *sp, *ep;
                    173:        char *n_name;
                    174:
                    175:        sp = (struct nlist *)stab->start;
                    176:        ep = (struct nlist *)stab->end;
                    177:
                    178:        for (; sp < ep; sp++) {
                    179:                if ((n_name = X_db_getname(stab, sp)) == 0)
                    180:                        continue;
                    181:                if ((sp->n_type & N_STAB) == 0 &&
                    182:                    db_eqname(n_name, symstr, '_'))
                    183:                        return ((db_sym_t)sp);
                    184:        }
                    185:        return ((db_sym_t)0);
                    186: }
                    187:
                    188: db_sym_t
                    189: db_aout_search_symbol(db_symtab_t *symtab, db_addr_t off,
                    190:     db_strategy_t strategy, db_expr_t *diffp)
                    191: {
                    192:        unsigned int    diff = *diffp;
                    193:        struct nlist    *symp = 0;
                    194:        struct nlist    *sp, *ep;
                    195:
                    196:        sp = (struct nlist *)symtab->start;
                    197:        ep = (struct nlist *)symtab->end;
                    198:
                    199:        for (; sp < ep; sp++) {
                    200:                if ((sp->n_type & N_STAB) != 0 ||
                    201:                    (sp->n_type & N_TYPE) == N_FN)
                    202:                        continue;
                    203:                if (X_db_getname(symtab, sp) == 0)
                    204:                        continue;
                    205:                if (off >= sp->n_value) {
                    206:                        if (off - sp->n_value < diff) {
                    207:                                diff = off - sp->n_value;
                    208:                                symp = sp;
                    209:                                if (diff == 0 && ((strategy == DB_STGY_PROC &&
                    210:                                    sp->n_type == (N_TEXT|N_EXT)) ||
                    211:                                    (strategy == DB_STGY_ANY &&
                    212:                                    (sp->n_type & N_EXT))))
                    213:                                        break;
                    214:                        } else if (off - sp->n_value == diff) {
                    215:                                if (symp == 0)
                    216:                                        symp = sp;
                    217:                                else if ((symp->n_type & N_EXT) == 0 &&
                    218:                                    (sp->n_type & N_EXT) != 0)
                    219:                                        symp = sp;      /* pick the ext. sym */
                    220:                        }
                    221:                }
                    222:        }
                    223:        if (symp == 0) {
                    224:                *diffp = off;
                    225:        } else {
                    226:                *diffp = diff;
                    227:        }
                    228:        return ((db_sym_t)symp);
                    229: }
                    230:
                    231: /*
                    232:  * Return the name and value for a symbol.
                    233:  */
                    234: void
                    235: db_aout_symbol_values(db_symtab_t *symtab, db_sym_t sym, char **namep,
                    236:     db_expr_t *valuep)
                    237: {
                    238:        struct nlist *sp;
                    239:
                    240:        sp = (struct nlist *)sym;
                    241:        if (namep)
                    242:                *namep = X_db_getname(symtab, sp);
                    243:        if (valuep)
                    244:                *valuep = sp->n_value;
                    245: }
                    246:
                    247:
                    248: boolean_t
                    249: db_aout_line_at_pc(db_symtab_t *symtab, db_sym_t cursym, char **filename,
                    250:     int *linenum, db_expr_t off)
                    251: {
                    252:        struct nlist    *sp, *ep;
                    253:        unsigned long   sodiff = -1UL, lndiff = -1UL, ln = 0;
                    254:        char            *fname = NULL;
                    255:
                    256:        sp = (struct nlist *)symtab->start;
                    257:        ep = (struct nlist *)symtab->end;
                    258:
                    259: /* XXX - gcc specific */
                    260: #define NEWSRC(str)    ((str) != NULL && \
                    261:     (str)[0] == 'g' && strcmp((str), "gcc_compiled.") == 0)
                    262:
                    263:        for (; sp < ep; sp++) {
                    264:
                    265:                /*
                    266:                 * Prevent bogus linenumbers in case module not compiled
                    267:                 * with debugging options
                    268:                 */
                    269: #if 0
                    270:                if (sp->n_value <= off && (off - sp->n_value) <= sodiff &&
                    271:                    NEWSRC(X_db_getname(symtab, sp))) {
                    272: #endif
                    273:                if ((sp->n_type & N_TYPE) == N_FN ||
                    274:                    NEWSRC(X_db_getname(symtab, sp))) {
                    275:                        sodiff = lndiff = -1UL;
                    276:                        ln = 0;
                    277:                        fname = NULL;
                    278:                }
                    279:
                    280:                if (sp->n_type == N_SO) {
                    281:                        if (sp->n_value <= off &&
                    282:                            (off - sp->n_value) < sodiff) {
                    283:                                sodiff = off - sp->n_value;
                    284:                                fname = X_db_getname(symtab, sp);
                    285:                        }
                    286:                        continue;
                    287:                }
                    288:
                    289:                if (sp->n_type != N_SLINE)
                    290:                        continue;
                    291:
                    292:                if (sp->n_value > off)
                    293:                        break;
                    294:
                    295:                if (off - sp->n_value < lndiff) {
                    296:                        lndiff = off - sp->n_value;
                    297:                        ln = sp->n_desc;
                    298:                }
                    299:        }
                    300:
                    301:        if (fname != NULL && ln != 0) {
                    302:                *filename = fname;
                    303:                *linenum = ln;
                    304:                return (TRUE);
                    305:        }
                    306:
                    307:        return (FALSE);
                    308: }
                    309:
                    310: boolean_t
                    311: db_aout_sym_numargs(db_symtab_t *symtab, db_sym_t cursym, int *nargp,
                    312:     char **argnamep)
                    313: {
                    314:        struct nlist    *sp, *ep;
                    315:        u_long          addr;
                    316:        int             maxnarg = *nargp, nargs = 0;
                    317:        char            *n_name;
                    318:
                    319:        if (cursym == NULL)
                    320:                return (FALSE);
                    321:
                    322:        addr = ((struct nlist *)cursym)->n_value;
                    323:        sp = (struct nlist *)symtab->start;
                    324:        ep = (struct nlist *)symtab->end;
                    325:
                    326:        for (; sp < ep; sp++) {
                    327:                if (sp->n_type == N_FUN && sp->n_value == addr) {
                    328:                        while (++sp < ep && sp->n_type == N_PSYM) {
                    329:                                if (nargs >= maxnarg)
                    330:                                        break;
                    331:                                nargs++;
                    332:                                n_name = X_db_getname(symtab, sp);
                    333:                                *argnamep++ = n_name ? n_name : "???";
                    334:                                {
                    335:                                        /* XXX - remove trailers */
                    336:                                        char *cp = *(argnamep - 1);
                    337:
                    338:                                        while (*cp != '\0' && *cp != ':')
                    339:                                                cp++;
                    340:                                        if (*cp == ':') *cp = '\0';
                    341:                                }
                    342:                        }
                    343:                        *nargp = nargs;
                    344:                        return (TRUE);
                    345:                }
                    346:        }
                    347:        return (FALSE);
                    348: }
                    349:
                    350: void
                    351: db_aout_forall(db_symtab_t *stab, db_forall_func_t db_forall_func, void *arg)
                    352: {
                    353:        static char suffix[2];
                    354:        struct nlist *sp, *ep;
                    355:
                    356:        sp = (struct nlist *)stab->start;
                    357:        ep = (struct nlist *)stab->end;
                    358:
                    359:        for (; sp < ep; sp++) {
                    360:                if (X_db_getname(stab, sp) == 0)
                    361:                        continue;
                    362:                if ((sp->n_type & N_STAB) == 0) {
                    363:                        suffix[1] = '\0';
                    364:                        switch(sp->n_type & N_TYPE) {
                    365:                        case N_ABS:
                    366:                                suffix[0] = '@';
                    367:                                break;
                    368:                        case N_TEXT:
                    369:                                suffix[0] = '*';
                    370:                                break;
                    371:                        case N_DATA:
                    372:                                suffix[0] = '+';
                    373:                                break;
                    374:                        case N_BSS:
                    375:                                suffix[0] = '-';
                    376:                                break;
                    377:                        case N_FN:
                    378:                                suffix[0] = '/';
                    379:                                break;
                    380:                        default:
                    381:                                suffix[0] = '\0';
                    382:                        }
                    383:                        (*db_forall_func)(stab, (db_sym_t)sp,
                    384:                            X_db_getname(stab, sp), suffix, '_', arg);
                    385:                }
                    386:        }
                    387:        return;
                    388: }
                    389:
                    390:
                    391: #endif /* DB_AOUT_SYMBOLS */

CVSweb