Annotation of Net2/ddb/db_sym.c, revision 1.1.1.2

1.1       root        1: /* 
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990 Carnegie Mellon University
                      4:  * All Rights Reserved.
                      5:  * 
                      6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
                     11:  * 
                     12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     15:  * 
                     16:  * Carnegie Mellon requests users of this software to return to
                     17:  * 
                     18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
                     22:  * 
                     23:  * any improvements or extensions that they make and grant Carnegie the
                     24:  * rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  * HISTORY
                     28:  * $Log: db_sym.c,v $
1.1.1.2 ! root       29:  * Revision 1.1.1.1  1993/03/21 09:46:27  cgd
        !            30:  * initial import of 386bsd-0.1 sources
        !            31:  *
1.1       root       32:  * Revision 1.1  1992/03/25  21:45:27  pace
                     33:  * Initial revision
                     34:  *
                     35:  * Revision 2.5  91/02/05  17:07:07  mrt
                     36:  *     Changed to new Mach copyright
                     37:  *     [91/01/31  16:19:17  mrt]
                     38:  * 
                     39:  * Revision 2.4  90/10/25  14:44:05  rwd
                     40:  *     Changed db_printsym to print unsigned.
                     41:  *     [90/10/19            rpd]
                     42:  * 
                     43:  * Revision 2.3  90/09/09  23:19:56  rpd
                     44:  *     Avoid totally incorrect guesses of symbol names for small values.
                     45:  *     [90/08/30  17:39:48  af]
                     46:  * 
                     47:  * Revision 2.2  90/08/27  21:52:18  dbg
                     48:  *     Removed nlist.h.  Fixed some type declarations.
                     49:  *     Qualifier character is ':'.
                     50:  *     [90/08/20            dbg]
                     51:  *     Modularized symtab info into a new db_symtab_t type.
                     52:  *     Modified db_add_symbol_table  and others accordingly.
                     53:  *     Defined db_sym_t, a new (opaque) type used to represent
                     54:  *     symbols.  This should support all sort of future symtable
                     55:  *     formats. Functions like db_qualify take a db_sym_t now.
                     56:  *     New db_symbol_values() function to explode the content
                     57:  *     of a db_sym_t.
                     58:  *     db_search_symbol() replaces db_find_sym_and_offset(), which is
                     59:  *     now a macro defined in our (new) header file.  This new
                     60:  *     function accepts more restrictive searches, which are
                     61:  *     entirely delegated to the symtab-specific code.
                     62:  *     Accordingly, db_printsym() accepts a strategy parameter.
                     63:  *     New db_line_at_pc() function.
                     64:  *     Renamed misleading db_eqsym into db_eqname.
                     65:  *     [90/08/20  10:47:06  af]
                     66:  * 
                     67:  *     Created.
                     68:  *     [90/07/25            dbg]
                     69:  * 
                     70:  * Revision 2.1  90/07/26  16:43:52  dbg
                     71:  * Created.
                     72:  * 
                     73:  */
                     74: /*
                     75:  *     Author: David B. Golub, Carnegie Mellon University
                     76:  *     Date:   7/90
                     77:  */
                     78: #include "param.h"
                     79: #include "proc.h"
                     80: #include <machine/db_machdep.h>
                     81: #include <ddb/db_sym.h>
                     82: 
                     83: /*
                     84:  * We import from the symbol-table dependent routines:
                     85:  */
                     86: extern db_sym_t        X_db_lookup();
                     87: extern db_sym_t        X_db_search_symbol();
                     88: extern boolean_t X_db_line_at_pc();
                     89: extern void    X_db_symbol_values();
                     90: 
                     91: /*
                     92:  * Multiple symbol tables
                     93:  */
                     94: #define        MAXNOSYMTABS    3       /* mach, ux, emulator */
                     95: 
                     96: db_symtab_t    db_symtabs[MAXNOSYMTABS] = {{0,},};
                     97: int db_nsymtab = 0;
                     98: 
                     99: db_symtab_t    *db_last_symtab;
                    100: 
                    101: db_sym_t       db_lookup();    /* forward */
                    102: 
                    103: /*
                    104:  * Add symbol table, with given name, to list of symbol tables.
                    105:  */
                    106: void
                    107: db_add_symbol_table(start, end, name, ref)
                    108:        char *start;
                    109:        char *end;
                    110:        char *name;
                    111:        char *ref;
                    112: {
                    113:        if (db_nsymtab >= MAXNOSYMTABS) {
                    114:                printf ("No slots left for %s symbol table", name);
                    115:                panic ("db_sym.c: db_add_symbol_table");
                    116:        }
                    117: 
                    118:        db_symtabs[db_nsymtab].start = start;
                    119:        db_symtabs[db_nsymtab].end = end;
                    120:        db_symtabs[db_nsymtab].name = name;
                    121:        db_symtabs[db_nsymtab].private = ref;
                    122:        db_nsymtab++;
                    123: }
                    124: 
                    125: /*
                    126:  *  db_qualify("vm_map", "ux") returns "unix:vm_map".
                    127:  *
                    128:  *  Note: return value points to static data whose content is
                    129:  *  overwritten by each call... but in practice this seems okay.
                    130:  */
                    131: static char *
                    132: db_qualify(sym, symtabname)
                    133:        db_sym_t        sym;
                    134:        register char   *symtabname;
                    135: {
                    136:        char            *symname;
                    137:        static char     tmp[256];
                    138:        register char   *s;
                    139: 
                    140:        db_symbol_values(sym, &symname, 0);
                    141:        s = tmp;
                    142:        while (*s++ = *symtabname++) {
                    143:        }
                    144:        s[-1] = ':';
                    145:        while (*s++ = *symname++) {
                    146:        }
                    147:        return tmp;
                    148: }
                    149: 
                    150: 
                    151: boolean_t
                    152: db_eqname(src, dst, c)
                    153:        char *src;
                    154:        char *dst;
                    155:        char c;
                    156: {
                    157:        if (!strcmp(src, dst))
                    158:            return (TRUE);
                    159:        if (src[0] == c)
                    160:            return (!strcmp(src+1,dst));
                    161:        return (FALSE);
                    162: }
                    163: 
                    164: boolean_t
                    165: db_value_of_name(name, valuep)
                    166:        char            *name;
                    167:        db_expr_t       *valuep;
                    168: {
                    169:        db_sym_t        sym;
                    170: 
                    171:        sym = db_lookup(name);
                    172:        if (sym == DB_SYM_NULL)
                    173:            return (FALSE);
                    174:        db_symbol_values(sym, &name, valuep);
                    175:        return (TRUE);
                    176: }
                    177: 
                    178: 
                    179: /*
                    180:  * Lookup a symbol.
                    181:  * If the symbol has a qualifier (e.g., ux:vm_map),
                    182:  * then only the specified symbol table will be searched;
                    183:  * otherwise, all symbol tables will be searched.
                    184:  */
                    185: db_sym_t
                    186: db_lookup(symstr)
                    187:        char *symstr;
                    188: {
                    189:        db_sym_t sp;
                    190:        register int i;
                    191:        int symtab_start = 0;
                    192:        int symtab_end = db_nsymtab;
                    193:        register char *cp;
                    194: 
                    195:        /*
                    196:         * Look for, remove, and remember any symbol table specifier.
                    197:         */
                    198:        for (cp = symstr; *cp; cp++) {
                    199:                if (*cp == ':') {
                    200:                        *cp = '\0';
                    201:                        for (i = 0; i < db_nsymtab; i++) {
                    202:                                if (! strcmp(symstr, db_symtabs[i].name)) {
                    203:                                        symtab_start = i;
                    204:                                        symtab_end = i + 1;
                    205:                                        break;
                    206:                                }
                    207:                        }
                    208:                        *cp = ':';
                    209:                        if (i == db_nsymtab) {
                    210:                                db_error("invalid symbol table name");
                    211:                        }
                    212:                        symstr = cp+1;
                    213:                }
                    214:        }
                    215: 
                    216:        /*
                    217:         * Look in the specified set of symbol tables.
                    218:         * Return on first match.
                    219:         */
                    220:        for (i = symtab_start; i < symtab_end; i++) {
                    221:                if (sp = X_db_lookup(&db_symtabs[i], symstr)) {
                    222:                        db_last_symtab = &db_symtabs[i];
                    223:                        return sp;
                    224:                }
                    225:        }
                    226:        return 0;
                    227: }
                    228: 
                    229: /*
                    230:  * Does this symbol name appear in more than one symbol table?
                    231:  * Used by db_symbol_values to decide whether to qualify a symbol.
                    232:  */
                    233: boolean_t db_qualify_ambiguous_names = FALSE;
                    234: 
                    235: boolean_t
                    236: db_symbol_is_ambiguous(sym)
                    237:        db_sym_t        sym;
                    238: {
                    239:        char            *sym_name;
                    240:        register int    i;
                    241:        register
                    242:        boolean_t       found_once = FALSE;
                    243: 
                    244:        if (!db_qualify_ambiguous_names)
                    245:                return FALSE;
                    246: 
                    247:        db_symbol_values(sym, &sym_name, 0);
                    248:        for (i = 0; i < db_nsymtab; i++) {
                    249:                if (X_db_lookup(&db_symtabs[i], sym_name)) {
                    250:                        if (found_once)
                    251:                                return TRUE;
                    252:                        found_once = TRUE;
                    253:                }
                    254:        }
                    255:        return FALSE;
                    256: }
                    257: 
                    258: /*
                    259:  * Find the closest symbol to val, and return its name
                    260:  * and the difference between val and the symbol found.
                    261:  */
                    262: db_sym_t
                    263: db_search_symbol( val, strategy, offp)
                    264:        register db_addr_t      val;
                    265:        db_strategy_t           strategy;
                    266:        db_expr_t               *offp;
                    267: {
                    268:        register
                    269:        unsigned int    diff;
                    270:        unsigned int    newdiff;
                    271:        register int    i;
                    272:        db_sym_t        ret = DB_SYM_NULL, sym;
                    273: 
                    274:        newdiff = diff = ~0;
                    275:        db_last_symtab = 0;
                    276:        for (i = 0; i < db_nsymtab; i++) {
                    277:            sym = X_db_search_symbol(&db_symtabs[i], val, strategy, &newdiff);
                    278:            if (newdiff < diff) {
                    279:                db_last_symtab = &db_symtabs[i];
                    280:                diff = newdiff;
                    281:                ret = sym;
                    282:            }
                    283:        }
                    284:        *offp = diff;
                    285:        return ret;
                    286: }
                    287: 
                    288: /*
                    289:  * Return name and value of a symbol
                    290:  */
                    291: void
                    292: db_symbol_values(sym, namep, valuep)
                    293:        db_sym_t        sym;
                    294:        char            **namep;
                    295:        db_expr_t       *valuep;
                    296: {
                    297:        db_expr_t       value;
                    298: 
                    299:        if (sym == DB_SYM_NULL) {
                    300:                *namep = 0;
                    301:                return;
                    302:        }
                    303: 
                    304:        X_db_symbol_values(sym, namep, &value);
                    305: 
                    306:        if (db_symbol_is_ambiguous(sym))
                    307:                *namep = db_qualify(sym, db_last_symtab->name);
                    308:        if (valuep)
                    309:                *valuep = value;
                    310: }
                    311: 
                    312: 
                    313: /*
                    314:  * Print a the closest symbol to value
                    315:  *
                    316:  * After matching the symbol according to the given strategy
                    317:  * we print it in the name+offset format, provided the symbol's
                    318:  * value is close enough (eg smaller than db_maxoff).
                    319:  * We also attempt to print [filename:linenum] when applicable
                    320:  * (eg for procedure names).
                    321:  *
                    322:  * If we could not find a reasonable name+offset representation,
                    323:  * then we just print the value in hex.  Small values might get
                    324:  * bogus symbol associations, e.g. 3 might get some absolute
                    325:  * value like _INCLUDE_VERSION or something, therefore we do
                    326:  * not accept symbols whose value is zero (and use plain hex).
                    327:  */
                    328: 
                    329: unsigned int   db_maxoff = 0x10000000;
                    330: 
                    331: void
                    332: db_printsym(off, strategy)
                    333:        db_expr_t       off;
                    334:        db_strategy_t   strategy;
                    335: {
                    336:        db_expr_t       d;
                    337:        char            *filename;
                    338:        char            *name;
                    339:        db_expr_t       value;
                    340:        int             linenum;
                    341:        db_sym_t        cursym;
                    342: 
                    343:        cursym = db_search_symbol(off, strategy, &d);
                    344:        db_symbol_values(cursym, &name, &value);
                    345:        if (name == 0 || d >= db_maxoff || value == 0) {
                    346:                db_printf("%#n", off);
                    347:                return;
                    348:        }
                    349:        db_printf("%s", name);
                    350:        if (d)
                    351:                db_printf("+%#r", d);
                    352:        if (strategy == DB_STGY_PROC) {
                    353:                if (db_line_at_pc(cursym, &filename, &linenum, off))
                    354:                        db_printf(" [%s:%d]", filename, linenum);
                    355:        }
                    356: }
                    357: 
                    358: 
                    359: boolean_t
                    360: db_line_at_pc( sym, filename, linenum, pc)
                    361: {
                    362:        return X_db_line_at_pc( db_last_symtab, sym, filename, linenum, pc);
                    363: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.