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