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