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

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

1.1       nbrk        1: /*     $OpenBSD: db_sym.c,v 1.32 2006/03/13 06:23:20 jsg Exp $ */
                      2: /*     $NetBSD: db_sym.c,v 1.24 2000/08/11 22:50:47 tv 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/param.h>
                     31: #include <sys/proc.h>
                     32: #include <sys/systm.h>
                     33:
                     34: #include <machine/db_machdep.h>
                     35:
                     36: #include <ddb/db_lex.h>
                     37: #include <ddb/db_sym.h>
                     38: #include <ddb/db_output.h>
                     39: #include <ddb/db_extern.h>
                     40: #include <ddb/db_command.h>
                     41:
                     42: /*
                     43:  * Multiple symbol tables
                     44:  */
                     45: #ifndef MAXLKMS
                     46: #define MAXLKMS 20
                     47: #endif
                     48:
                     49: #ifndef MAXNOSYMTABS
                     50: #define        MAXNOSYMTABS    MAXLKMS+1       /* Room for kernel + LKM's */
                     51: #endif
                     52:
                     53: db_symtab_t    db_symtabs[MAXNOSYMTABS] = {{0,},};
                     54:
                     55: db_symtab_t    *db_last_symtab;
                     56:
                     57: static db_forall_func_t db_sift;
                     58:
                     59: extern char end[];
                     60:
                     61: /*
                     62:  * Put the most picky symbol table formats at the top!
                     63:  */
                     64: const db_symformat_t *db_symformats[] = {
                     65: #ifdef DB_ELF_SYMBOLS
                     66:        &db_symformat_elf,
                     67: #endif
                     68: #ifdef DB_AOUT_SYMBOLS
                     69:        &db_symformat_aout,
                     70: #endif
                     71:        NULL,
                     72: };
                     73:
                     74: const db_symformat_t *db_symformat;
                     75:
                     76: boolean_t      X_db_sym_init(int, void *, void *, const char *);
                     77: db_sym_t       X_db_lookup(db_symtab_t *, char *);
                     78: db_sym_t       X_db_search_symbol(db_symtab_t *, db_addr_t,
                     79:                    db_strategy_t, db_expr_t *);
                     80: void           X_db_symbol_values(db_symtab_t *, db_sym_t, char **,
                     81:                    db_expr_t *);
                     82: boolean_t      X_db_line_at_pc(db_symtab_t *, db_sym_t, char **,
                     83:                    int *, db_expr_t);
                     84: int            X_db_sym_numargs(db_symtab_t *, db_sym_t, int *,
                     85:                    char **);
                     86:
                     87: /*
                     88:  * Initialize the kernel debugger by initializing the master symbol
                     89:  * table.  Note that if initializing the master symbol table fails,
                     90:  * no other symbol tables can be loaded.
                     91:  */
                     92: #if 0
                     93: void
                     94: ddb_init(int symsize, void *vss, void *vse)
                     95: {
                     96:        const db_symformat_t **symf;
                     97:        const char *name = "bsd";
                     98:
                     99:        if (symsize <= 0) {
                    100:                printf(" [ no symbols available ]\n");
                    101:                return;
                    102:        }
                    103:
                    104:        /*
                    105:         * Do this check now for the master symbol table to avoid printing
                    106:         * the message N times.
                    107:         */
                    108:        if (ALIGNED_POINTER(vss, long) == 0) {
                    109:                printf("[ %s symbol table has bad start address %p ]\n",
                    110:                    name, vss);
                    111:                return;
                    112:        }
                    113:
                    114:        for (symf = db_symformats; *symf != NULL; symf++) {
                    115:                db_symformat = *symf;
                    116:                if (X_db_sym_init(symsize, vss, vse, name) == TRUE)
                    117:                        return;
                    118:        }
                    119:
                    120:        db_symformat = NULL;
                    121:        printf("[ no symbol table formats found ]\n");
                    122: }
                    123: #else
                    124: void
                    125: ddb_init(void)
                    126: {
                    127:        const db_symformat_t **symf;
                    128:        const char *name = "bsd";
                    129:        extern char *esym;
                    130: #if defined(__sparc64__) || defined(__mips__)
                    131:        extern char *ssym;
                    132: #endif
                    133:        char *xssym, *xesym;
                    134:
                    135:        xesym = esym;
                    136: #if defined(__sparc64__) || defined(__mips__)
                    137:        xssym = ssym;
                    138: #else
                    139:        xssym = (char *)&end;
                    140: #endif
                    141:        /*
                    142:         * Do this check now for the master symbol table to avoid printing
                    143:         * the message N times.
                    144:         */
                    145:        if ((((vaddr_t)xssym) & (sizeof(long) - 1)) != 0) {
                    146:                printf("[ %s symbol table has bad start address %p ]\n",
                    147:                    name, xssym);
                    148:                return;
                    149:        }
                    150:
                    151:        if (xesym != NULL && xesym != xssym)
                    152:                for (symf = db_symformats; *symf != NULL; symf++) {
                    153:                        db_symformat = *symf;
                    154:                        if (X_db_sym_init((vaddr_t)xesym - (vaddr_t)xssym,
                    155:                            xssym, xesym, name) == TRUE)
                    156:                        return;
                    157:                }
                    158:
                    159:        db_symformat = NULL;
                    160:        printf("[ no symbol table formats found ]\n");
                    161: }
                    162: #endif
                    163:
                    164: /*
                    165:  * Add symbol table, with given name, to list of symbol tables.
                    166:  */
                    167: int
                    168: db_add_symbol_table(char *start, char *end, const char *name, char *ref)
                    169: {
                    170:        int slot;
                    171:
                    172:        for (slot = 0; slot < MAXNOSYMTABS; slot++) {
                    173:                if (db_symtabs[slot].name == NULL)
                    174:                        break;
                    175:        }
                    176:        if (slot >= MAXNOSYMTABS) {
                    177:                db_printf("No slots left for %s symbol table", name);
                    178:                return(-1);
                    179:        }
                    180:
                    181:        db_symtabs[slot].start = start;
                    182:        db_symtabs[slot].end = end;
                    183:        db_symtabs[slot].name = name;
                    184:        db_symtabs[slot].private = ref;
                    185:
                    186:        return(slot);
                    187: }
                    188:
                    189: /*
                    190:  * Delete a symbol table. Caller is responsible for freeing storage.
                    191:  */
                    192: void
                    193: db_del_symbol_table(char *name)
                    194: {
                    195:        int slot;
                    196:
                    197:        for (slot = 0; slot < MAXNOSYMTABS; slot++) {
                    198:                if (db_symtabs[slot].name &&
                    199:                    ! strcmp(db_symtabs[slot].name, name))
                    200:                        break;
                    201:        }
                    202:        if (slot >= MAXNOSYMTABS) {
                    203:                db_printf("Unable to find symbol table slot for %s.", name);
                    204:                return;
                    205:        }
                    206:
                    207:        db_symtabs[slot].start = 0;
                    208:        db_symtabs[slot].end = 0;
                    209:        db_symtabs[slot].name = 0;
                    210:        db_symtabs[slot].private = 0;
                    211: }
                    212:
                    213: /*
                    214:  *  db_qualify("vm_map", "bsd") returns "bsd:vm_map".
                    215:  *
                    216:  *  Note: return value points to static data whose content is
                    217:  *  overwritten by each call... but in practice this seems okay.
                    218:  */
                    219: char *
                    220: db_qualify(db_sym_t sym, const char *symtabname)
                    221: {
                    222:        char            *symname;
                    223:        static char     tmp[256];
                    224:        char    *s;
                    225:
                    226:        db_symbol_values(sym, &symname, 0);
                    227:        s = tmp;
                    228:        while ((*s++ = *symtabname++) != '\0')
                    229:                ;
                    230:        s[-1] = ':';
                    231:        while ((*s++ = *symname++) != '\0')
                    232:                ;
                    233:        return tmp;
                    234: }
                    235:
                    236:
                    237: boolean_t
                    238: db_eqname(char *src, char *dst, int c)
                    239: {
                    240:        if (!strcmp(src, dst))
                    241:            return (TRUE);
                    242:        if (src[0] == c)
                    243:            return (!strcmp(src+1,dst));
                    244:        return (FALSE);
                    245: }
                    246:
                    247: boolean_t
                    248: db_value_of_name(char *name, db_expr_t *valuep)
                    249: {
                    250:        db_sym_t        sym;
                    251:
                    252:        sym = db_lookup(name);
                    253:        if (sym == DB_SYM_NULL)
                    254:            return (FALSE);
                    255:        db_symbol_values(sym, &name, valuep);
                    256:        return (TRUE);
                    257: }
                    258:
                    259:
                    260: /*
                    261:  * Lookup a symbol.
                    262:  * If the symbol has a qualifier (e.g., ux:vm_map),
                    263:  * then only the specified symbol table will be searched;
                    264:  * otherwise, all symbol tables will be searched.
                    265:  */
                    266: db_sym_t
                    267: db_lookup(char *symstr)
                    268: {
                    269:        db_sym_t sp;
                    270:        int i;
                    271:        int symtab_start = 0;
                    272:        int symtab_end = MAXNOSYMTABS;
                    273:        char *cp;
                    274:
                    275:        /*
                    276:         * Look for, remove, and remember any symbol table specifier.
                    277:         */
                    278:        for (cp = symstr; *cp; cp++) {
                    279:                if (*cp == ':') {
                    280:                        *cp = '\0';
                    281:                        for (i = 0; i < MAXNOSYMTABS; i++) {
                    282:                                if (db_symtabs[i].name &&
                    283:                                    ! strcmp(symstr, db_symtabs[i].name)) {
                    284:                                        symtab_start = i;
                    285:                                        symtab_end = i + 1;
                    286:                                        break;
                    287:                                }
                    288:                        }
                    289:                        *cp = ':';
                    290:                        if (i == MAXNOSYMTABS) {
                    291:                                db_error("invalid symbol table name");
                    292:                                /*NOTREACHED*/
                    293:                        }
                    294:                        symstr = cp+1;
                    295:                }
                    296:        }
                    297:
                    298:        /*
                    299:         * Look in the specified set of symbol tables.
                    300:         * Return on first match.
                    301:         */
                    302:        for (i = symtab_start; i < symtab_end; i++) {
                    303:                if (db_symtabs[i].name &&
                    304:                    (sp = X_db_lookup(&db_symtabs[i], symstr))) {
                    305:                        db_last_symtab = &db_symtabs[i];
                    306:                        return sp;
                    307:                }
                    308:        }
                    309:        return 0;
                    310: }
                    311:
                    312: /* Private structure for passing args to db_sift() from db_sifting(). */
                    313: struct db_sift_args {
                    314:        char    *symstr;
                    315:        int     mode;
                    316: };
                    317:
                    318: /*
                    319:  * Does the work of db_sifting(), called once for each
                    320:  * symbol via X_db_forall(), prints out symbols matching
                    321:  * criteria.
                    322:  */
                    323: static void
                    324: db_sift(db_symtab_t *stab, db_sym_t sym, char *name, char *suffix, int prefix,
                    325:     void *arg)
                    326: {
                    327:        char c, sc;
                    328:        char *find, *p;
                    329:        size_t len;
                    330:        struct db_sift_args *dsa;
                    331:
                    332:        dsa = (struct db_sift_args*)arg;
                    333:
                    334:        find = dsa->symstr;     /* String we're looking for. */
                    335:        p = name;               /* String we're searching within. */
                    336:
                    337:        /* Matching algorithm cribbed from strstr(), which is not
                    338:           in the kernel. */
                    339:        if ((c = *find++) != 0) {
                    340:                len = strlen(find);
                    341:                do {
                    342:                        do {
                    343:                                if ((sc = *p++) == 0)
                    344:                                        return;
                    345:                        } while (sc != c);
                    346:                } while (strncmp(p, find, len) != 0);
                    347:        }
                    348:        if (dsa->mode=='F')     /* ala ls -F */
                    349:                db_printf("%s%s ", name, suffix);
                    350:        else
                    351:                db_printf("%s ", name);
                    352: }
                    353:
                    354: /*
                    355:  * "Sift" for a partial symbol.
                    356:  * Named for the Sun OpenPROM command ("sifting").
                    357:  * If the symbol has a qualifier (e.g., ux:vm_map),
                    358:  * then only the specified symbol table will be searched;
                    359:  * otherwise, all symbol tables will be searched..
                    360:  *
                    361:  * "mode" is how-to-display, set from modifiers.
                    362:  */
                    363: void
                    364: db_sifting(char *symstr, int mode)
                    365: {
                    366:        char *cp;
                    367:        int i;
                    368:        int symtab_start = 0;
                    369:        int symtab_end = MAXNOSYMTABS;
                    370:        struct db_sift_args dsa;
                    371:
                    372:        /*
                    373:         * Look for, remove, and remember any symbol table specifier.
                    374:         */
                    375:        for (cp = symstr; *cp; cp++) {
                    376:                if (*cp == ':') {
                    377:                        *cp = '\0';
                    378:                        for (i = 0; i < MAXNOSYMTABS; i++) {
                    379:                                if (db_symtabs[i].name &&
                    380:                                    ! strcmp(symstr, db_symtabs[i].name)) {
                    381:                                        symtab_start = i;
                    382:                                        symtab_end = i + 1;
                    383:                                        break;
                    384:                                }
                    385:                        }
                    386:                        *cp = ':';
                    387:                        if (i == MAXNOSYMTABS) {
                    388:                                db_error("invalid symbol table name");
                    389:                                /*NOTREACHED*/
                    390:                        }
                    391:                        symstr = cp+1;
                    392:                }
                    393:        }
                    394:
                    395:        /* Pass args to db_sift(). */
                    396:        dsa.symstr = symstr;
                    397:        dsa.mode = mode;
                    398:
                    399:        /*
                    400:         * Look in the specified set of symbol tables.
                    401:         */
                    402:        for (i = symtab_start; i < symtab_end; i++)
                    403:                if (db_symtabs[i].name) {
                    404:                        db_printf("Sifting table %s:\n", db_symtabs[i].name);
                    405:                        X_db_forall(&db_symtabs[i], db_sift, &dsa);
                    406:                }
                    407:
                    408:        return;
                    409: }
                    410:
                    411:
                    412: /*
                    413:  * Does this symbol name appear in more than one symbol table?
                    414:  * Used by db_symbol_values to decide whether to qualify a symbol.
                    415:  */
                    416: boolean_t db_qualify_ambiguous_names = FALSE;
                    417:
                    418: boolean_t
                    419: db_symbol_is_ambiguous(db_sym_t sym)
                    420: {
                    421:        char            *sym_name;
                    422:        int     i;
                    423:        boolean_t       found_once = FALSE;
                    424:
                    425:        if (!db_qualify_ambiguous_names)
                    426:                return FALSE;
                    427:
                    428:        db_symbol_values(sym, &sym_name, 0);
                    429:        for (i = 0; i < MAXNOSYMTABS; i++) {
                    430:                if (db_symtabs[i].name &&
                    431:                    X_db_lookup(&db_symtabs[i], sym_name)) {
                    432:                        if (found_once)
                    433:                                return TRUE;
                    434:                        found_once = TRUE;
                    435:                }
                    436:        }
                    437:        return FALSE;
                    438: }
                    439:
                    440: /*
                    441:  * Find the closest symbol to val, and return its name
                    442:  * and the difference between val and the symbol found.
                    443:  */
                    444: db_sym_t
                    445: db_search_symbol(db_addr_t val, db_strategy_t strategy, db_expr_t *offp)
                    446: {
                    447:        unsigned int    diff;
                    448:        db_expr_t       newdiff;
                    449:        int             i;
                    450:        db_sym_t        ret = DB_SYM_NULL, sym;
                    451:
                    452:        newdiff = diff = ~0;
                    453:        db_last_symtab = 0;
                    454:        for (i = 0; i < MAXNOSYMTABS; i++) {
                    455:            if (!db_symtabs[i].name)
                    456:                continue;
                    457:            sym = X_db_search_symbol(&db_symtabs[i], val, strategy, &newdiff);
                    458:            if (newdiff < diff) {
                    459:                db_last_symtab = &db_symtabs[i];
                    460:                diff = newdiff;
                    461:                ret = sym;
                    462:            }
                    463:        }
                    464:        *offp = diff;
                    465:        return ret;
                    466: }
                    467:
                    468: /*
                    469:  * Return name and value of a symbol
                    470:  */
                    471: void
                    472: db_symbol_values(db_sym_t sym, char **namep, db_expr_t *valuep)
                    473: {
                    474:        db_expr_t       value;
                    475:
                    476:        if (sym == DB_SYM_NULL) {
                    477:                *namep = 0;
                    478:                return;
                    479:        }
                    480:
                    481:        X_db_symbol_values(db_last_symtab, sym, namep, &value);
                    482:
                    483:        if (db_symbol_is_ambiguous(sym))
                    484:                *namep = db_qualify(sym, db_last_symtab->name);
                    485:        if (valuep)
                    486:                *valuep = value;
                    487: }
                    488:
                    489:
                    490: /*
                    491:  * Print a the closest symbol to value
                    492:  *
                    493:  * After matching the symbol according to the given strategy
                    494:  * we print it in the name+offset format, provided the symbol's
                    495:  * value is close enough (eg smaller than db_maxoff).
                    496:  * We also attempt to print [filename:linenum] when applicable
                    497:  * (eg for procedure names).
                    498:  *
                    499:  * If we could not find a reasonable name+offset representation,
                    500:  * then we just print the value in hex.  Small values might get
                    501:  * bogus symbol associations, e.g. 3 might get some absolute
                    502:  * value like _INCLUDE_VERSION or something, therefore we do
                    503:  * not accept symbols whose value is zero (and use plain hex).
                    504:  * Also, avoid printing as "end+0x????" which is useless.
                    505:  * The variable db_lastsym is used instead of "end" in case we
                    506:  * add support for symbols in loadable driver modules.
                    507:  */
                    508: unsigned long  db_lastsym = (unsigned long)end;
                    509: unsigned int   db_maxoff = 0x10000000;
                    510:
                    511:
                    512: void
                    513: db_printsym(db_expr_t off, db_strategy_t strategy,
                    514:     int (*pr)(const char *, ...))
                    515: {
                    516:        db_expr_t       d;
                    517:        char            *filename;
                    518:        char            *name;
                    519:        db_expr_t       value;
                    520:        int             linenum;
                    521:        db_sym_t        cursym;
                    522:        char            buf[DB_FORMAT_BUF_SIZE];
                    523:
                    524:        if (off <= db_lastsym) {
                    525:                cursym = db_search_symbol(off, strategy, &d);
                    526:                db_symbol_values(cursym, &name, &value);
                    527:                if (name && (d < db_maxoff) && value) {
                    528:                        (*pr)("%s", name);
                    529:                        if (d) {
                    530:                                (*pr)("+%s", db_format(buf, sizeof(buf),
                    531:                                    d, DB_FORMAT_R, 1, 0));
                    532:                        }
                    533:                        if (strategy == DB_STGY_PROC) {
                    534:                                if (db_line_at_pc(cursym, &filename, &linenum, off))
                    535:                                        (*pr)(" [%s:%d]", filename, linenum);
                    536:                        }
                    537:                        return;
                    538:                }
                    539:        }
                    540:
                    541:        (*pr)("%s", db_format(buf, sizeof(buf), off, DB_FORMAT_N, 1, 0));
                    542:        return;
                    543: }
                    544:
                    545:
                    546: boolean_t
                    547: db_line_at_pc(db_sym_t sym, char **filename, int *linenum, db_expr_t pc)
                    548: {
                    549:        return X_db_line_at_pc(db_last_symtab, sym, filename, linenum, pc);
                    550: }
                    551:
                    552: int
                    553: db_sym_numargs(db_sym_t sym, int *nargp, char **argnames)
                    554: {
                    555:        return X_db_sym_numargs(db_last_symtab, sym, nargp, argnames);
                    556: }
                    557:
                    558: boolean_t
                    559: X_db_sym_init(int symsize, void *vss, void *vse, const char *name)
                    560: {
                    561:
                    562:        if (db_symformat != NULL)
                    563:                return ((*db_symformat->sym_init)(symsize, vss, vse, name));
                    564:        return (FALSE);
                    565: }
                    566:
                    567: db_sym_t
                    568: X_db_lookup(db_symtab_t *stab, char *symstr)
                    569: {
                    570:
                    571:        if (db_symformat != NULL)
                    572:                return ((*db_symformat->sym_lookup)(stab, symstr));
                    573:        return ((db_sym_t)0);
                    574: }
                    575:
                    576: db_sym_t
                    577: X_db_search_symbol(db_symtab_t *stab, db_addr_t off, db_strategy_t strategy,
                    578:     db_expr_t *diffp)
                    579: {
                    580:
                    581:        if (db_symformat != NULL)
                    582:                return ((*db_symformat->sym_search)(stab, off, strategy,
                    583:                    diffp));
                    584:        return ((db_sym_t)0);
                    585: }
                    586:
                    587: void
                    588: X_db_symbol_values(db_symtab_t *stab, db_sym_t sym, char **namep,
                    589:     db_expr_t *valuep)
                    590: {
                    591:
                    592:        if (db_symformat != NULL)
                    593:                (*db_symformat->sym_value)(stab, sym, namep, valuep);
                    594: }
                    595:
                    596: boolean_t
                    597: X_db_line_at_pc(db_symtab_t *stab, db_sym_t cursym, char **filename,
                    598:     int *linenum, db_expr_t off)
                    599: {
                    600:
                    601:        if (db_symformat != NULL)
                    602:                return ((*db_symformat->sym_line_at_pc)(stab, cursym,
                    603:                    filename, linenum, off));
                    604:        return (FALSE);
                    605: }
                    606:
                    607: boolean_t
                    608: X_db_sym_numargs(db_symtab_t *stab, db_sym_t cursym, int *nargp,
                    609:     char **argnamep)
                    610: {
                    611:
                    612:        if (db_symformat != NULL)
                    613:                return ((*db_symformat->sym_numargs)(stab, cursym, nargp,
                    614:                    argnamep));
                    615:        return (FALSE);
                    616: }
                    617:
                    618: void
                    619: X_db_forall(db_symtab_t *stab, db_forall_func_t db_forall_func, void *arg)
                    620: {
                    621:        if (db_symformat != NULL)
                    622:                (*db_symformat->sym_forall)(stab, db_forall_func, arg);
                    623: }

CVSweb