db_sym.c revision 4
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 Software.Distribution@CS.CMU.EDU 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 */ 83extern db_sym_t X_db_lookup(); 84extern db_sym_t X_db_search_symbol(); 85extern boolean_t X_db_line_at_pc(); 86extern void X_db_symbol_values(); 87 88/* 89 * Multiple symbol tables 90 */ 91#define MAXNOSYMTABS 3 /* mach, ux, emulator */ 92 93db_symtab_t db_symtabs[MAXNOSYMTABS] = {{0,},}; 94int db_nsymtab = 0; 95 96db_symtab_t *db_last_symtab; 97 98db_sym_t db_lookup(); /* forward */ 99 100/* 101 * Add symbol table, with given name, to list of symbol tables. 102 */ 103void 104db_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 */ 128static char * 129db_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 148boolean_t 149db_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 161boolean_t 162db_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 */ 182db_sym_t 183db_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 */ 230boolean_t db_qualify_ambiguous_names = FALSE; 231 232boolean_t 233db_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 */ 259db_sym_t 260db_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 */ 288void 289db_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 326unsigned int db_maxoff = 0x10000000; 327 328void 329db_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 356boolean_t 357db_line_at_pc( sym, filename, linenum, pc) 358{ 359 return X_db_line_at_pc( db_last_symtab, sym, filename, linenum, pc); 360} 361