| File: | obj-scan-build/../ddb/db_sym.c |
| Location: | line 416, column 2 |
| Description: | Access to field 'type' results in a dereference of a null pointer (loaded from variable 'stab') |
| 1 | /* | |||||
| 2 | * Mach Operating System | |||||
| 3 | * Copyright (c) 1992,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 "AS IS" | |||||
| 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 Mellon | |||||
| 24 | * the rights to redistribute these changes. | |||||
| 25 | */ | |||||
| 26 | /* | |||||
| 27 | * Author: David B. Golub, Carnegie Mellon University | |||||
| 28 | * Date: 7/90 | |||||
| 29 | */ | |||||
| 30 | ||||||
| 31 | #if MACH_KDB1 | |||||
| 32 | ||||||
| 33 | #include <string.h> | |||||
| 34 | #include <mach/std_types.h> | |||||
| 35 | #include <machine/db_machdep.h> | |||||
| 36 | #include <ddb/db_command.h> | |||||
| 37 | #include <ddb/db_output.h> | |||||
| 38 | #include <ddb/db_sym.h> | |||||
| 39 | #include <ddb/db_task_thread.h> | |||||
| 40 | #include <ddb/db_aout.h> | |||||
| 41 | #include <ddb/db_elf.h> | |||||
| 42 | ||||||
| 43 | #include <vm/vm_map.h> /* vm_map_t */ | |||||
| 44 | ||||||
| 45 | /* | |||||
| 46 | * Multiple symbol tables | |||||
| 47 | */ | |||||
| 48 | #define MAXNOSYMTABS5 5 /* mach, bootstrap, ux, emulator, 1 spare */ | |||||
| 49 | ||||||
| 50 | db_symtab_t db_symtabs[MAXNOSYMTABS5] = {{0,},}; | |||||
| 51 | int db_nsymtab = 0; | |||||
| 52 | ||||||
| 53 | db_symtab_t *db_last_symtab; | |||||
| 54 | ||||||
| 55 | /* | |||||
| 56 | * Add symbol table, with given name, to list of symbol tables. | |||||
| 57 | */ | |||||
| 58 | boolean_t | |||||
| 59 | db_add_symbol_table( | |||||
| 60 | int type, | |||||
| 61 | char *start, | |||||
| 62 | char *end, | |||||
| 63 | char *name, | |||||
| 64 | char *ref, | |||||
| 65 | char *map_pointer) | |||||
| 66 | { | |||||
| 67 | db_symtab_t *st; | |||||
| 68 | extern vm_map_t kernel_map; | |||||
| 69 | ||||||
| 70 | if (db_nsymtab >= MAXNOSYMTABS5) | |||||
| 71 | return (FALSE((boolean_t) 0)); | |||||
| 72 | ||||||
| 73 | st = &db_symtabs[db_nsymtab]; | |||||
| 74 | st->type = type; | |||||
| 75 | st->start = start; | |||||
| 76 | st->end = end; | |||||
| 77 | st->private = ref; | |||||
| 78 | st->map_pointer = (map_pointer == (char *)kernel_map)? 0: map_pointer; | |||||
| 79 | strncpy(st->name, name, sizeof st->name - 1); | |||||
| 80 | st->name[sizeof st->name - 1] = '\0'; | |||||
| 81 | ||||||
| 82 | db_nsymtab++; | |||||
| 83 | ||||||
| 84 | return (TRUE((boolean_t) 1)); | |||||
| 85 | } | |||||
| 86 | ||||||
| 87 | /* | |||||
| 88 | * db_qualify("vm_map", "ux") returns "ux::vm_map". | |||||
| 89 | * | |||||
| 90 | * Note: return value points to static data whose content is | |||||
| 91 | * overwritten by each call... but in practice this seems okay. | |||||
| 92 | */ | |||||
| 93 | static char * __attribute__ ((pure)) | |||||
| 94 | db_qualify(symname, symtabname) | |||||
| 95 | const char *symname; | |||||
| 96 | const char *symtabname; | |||||
| 97 | { | |||||
| 98 | static char tmp[256]; | |||||
| 99 | char *s; | |||||
| 100 | ||||||
| 101 | s = tmp; | |||||
| 102 | while ((*s++ = *symtabname++)) { | |||||
| 103 | } | |||||
| 104 | s[-1] = ':'; | |||||
| 105 | *s++ = ':'; | |||||
| 106 | while ((*s++ = *symname++)) { | |||||
| 107 | } | |||||
| 108 | return tmp; | |||||
| 109 | } | |||||
| 110 | ||||||
| 111 | ||||||
| 112 | boolean_t | |||||
| 113 | db_eqname( const char* src, const char* dst, char c ) | |||||
| 114 | { | |||||
| 115 | if (!strcmp(src, dst)) | |||||
| 116 | return (TRUE((boolean_t) 1)); | |||||
| 117 | if (src[0] == c) | |||||
| 118 | return (!strcmp(src+1,dst)); | |||||
| 119 | return (FALSE((boolean_t) 0)); | |||||
| 120 | } | |||||
| 121 | ||||||
| 122 | boolean_t | |||||
| 123 | db_value_of_name( | |||||
| 124 | char *name, | |||||
| 125 | db_expr_t *valuep) | |||||
| 126 | { | |||||
| 127 | db_sym_t sym; | |||||
| 128 | ||||||
| 129 | sym = db_lookup(name); | |||||
| 130 | if (sym == DB_SYM_NULL((db_sym_t)0)) | |||||
| 131 | return (FALSE((boolean_t) 0)); | |||||
| 132 | db_symbol_values(0, sym, &name, valuep); | |||||
| 133 | ||||||
| 134 | db_free_symbol(sym); | |||||
| 135 | return (TRUE((boolean_t) 1)); | |||||
| 136 | } | |||||
| 137 | ||||||
| 138 | /* | |||||
| 139 | * Lookup a symbol. | |||||
| 140 | * If the symbol has a qualifier (e.g., ux::vm_map), | |||||
| 141 | * then only the specified symbol table will be searched; | |||||
| 142 | * otherwise, all symbol tables will be searched. | |||||
| 143 | */ | |||||
| 144 | db_sym_t | |||||
| 145 | db_lookup(char *symstr) | |||||
| 146 | { | |||||
| 147 | db_sym_t sp; | |||||
| 148 | int i; | |||||
| 149 | int symtab_start = 0; | |||||
| 150 | int symtab_end = db_nsymtab; | |||||
| 151 | char *cp; | |||||
| 152 | ||||||
| 153 | /* | |||||
| 154 | * Look for, remove, and remember any symbol table specifier. | |||||
| 155 | */ | |||||
| 156 | for (cp = symstr; *cp; cp++) { | |||||
| 157 | if (*cp == ':' && cp[1] == ':') { | |||||
| 158 | *cp = '\0'; | |||||
| 159 | for (i = 0; i < db_nsymtab; i++) { | |||||
| 160 | if (! strcmp(symstr, db_symtabs[i].name)) { | |||||
| 161 | symtab_start = i; | |||||
| 162 | symtab_end = i + 1; | |||||
| 163 | break; | |||||
| 164 | } | |||||
| 165 | } | |||||
| 166 | *cp = ':'; | |||||
| 167 | if (i == db_nsymtab) | |||||
| 168 | db_error("Invalid symbol table name\n"); | |||||
| 169 | symstr = cp+2; | |||||
| 170 | } | |||||
| 171 | } | |||||
| 172 | ||||||
| 173 | /* | |||||
| 174 | * Look in the specified set of symbol tables. | |||||
| 175 | * Return on first match. | |||||
| 176 | */ | |||||
| 177 | for (i = symtab_start; i < symtab_end; i++) { | |||||
| 178 | if ((sp = X_db_lookup(&db_symtabs[i], symstr)x_db[(&db_symtabs[i])->type].lookup(&db_symtabs[i] ,symstr))) { | |||||
| 179 | db_last_symtab = &db_symtabs[i]; | |||||
| 180 | return sp; | |||||
| 181 | } | |||||
| 182 | db_free_symbol(sp); | |||||
| 183 | } | |||||
| 184 | return 0; | |||||
| 185 | } | |||||
| 186 | ||||||
| 187 | /* | |||||
| 188 | * Common utility routine to parse a symbol string into a file | |||||
| 189 | * name, a symbol name and line number. | |||||
| 190 | * This routine is called from X_db_lookup if the object dependent | |||||
| 191 | * handler supports qualified search with a file name or a line number. | |||||
| 192 | * It parses the symbol string, and call an object dependent routine | |||||
| 193 | * with parsed file name, symbol name and line number. | |||||
| 194 | */ | |||||
| 195 | db_sym_t | |||||
| 196 | db_sym_parse_and_lookup( | |||||
| 197 | db_sym_t (*func)(), | |||||
| 198 | db_symtab_t *symtab, | |||||
| 199 | char *symstr) | |||||
| 200 | { | |||||
| 201 | char *p; | |||||
| 202 | int n; | |||||
| 203 | int n_name; | |||||
| 204 | int line_number; | |||||
| 205 | char *file_name = 0; | |||||
| 206 | char *sym_name = 0; | |||||
| 207 | char *component[3]; | |||||
| 208 | db_sym_t found = DB_SYM_NULL((db_sym_t)0); | |||||
| 209 | ||||||
| 210 | /* | |||||
| 211 | * disassemble the symbol into components: | |||||
| 212 | * [file_name:]symbol[:line_nubmer] | |||||
| 213 | */ | |||||
| 214 | component[0] = symstr; | |||||
| 215 | component[1] = component[2] = 0; | |||||
| 216 | for (p = symstr, n = 1; *p; p++) { | |||||
| 217 | if (*p == ':') { | |||||
| 218 | if (n >= 3) | |||||
| 219 | break; | |||||
| 220 | *p = 0; | |||||
| 221 | component[n++] = p+1; | |||||
| 222 | } | |||||
| 223 | } | |||||
| 224 | if (*p != 0) | |||||
| 225 | goto out; | |||||
| 226 | line_number = 0; | |||||
| 227 | n_name = n; | |||||
| 228 | p = component[n-1]; | |||||
| 229 | if (*p >= '0' && *p <= '9') { | |||||
| 230 | if (n == 1) | |||||
| 231 | goto out; | |||||
| 232 | for (line_number = 0; *p; p++) { | |||||
| 233 | if (*p < '0' || *p > '9') | |||||
| 234 | goto out; | |||||
| 235 | line_number = line_number*10 + *p - '0'; | |||||
| 236 | } | |||||
| 237 | n_name--; | |||||
| 238 | } else if (n >= 3) | |||||
| 239 | goto out; | |||||
| 240 | if (n_name == 1) { | |||||
| 241 | for (p = component[0]; *p && *p != '.'; p++); | |||||
| 242 | if (*p == '.') { | |||||
| 243 | file_name = component[0]; | |||||
| 244 | sym_name = 0; | |||||
| 245 | } else { | |||||
| 246 | file_name = 0; | |||||
| 247 | sym_name = component[0]; | |||||
| 248 | } | |||||
| 249 | } else { | |||||
| 250 | file_name = component[0]; | |||||
| 251 | sym_name = component[1]; | |||||
| 252 | } | |||||
| 253 | found = func(symtab, file_name, sym_name, line_number); | |||||
| 254 | ||||||
| 255 | out: | |||||
| 256 | while (--n >= 1) | |||||
| 257 | component[n][-1] = ':'; | |||||
| 258 | return(found); | |||||
| 259 | } | |||||
| 260 | ||||||
| 261 | /* | |||||
| 262 | * Does this symbol name appear in more than one symbol table? | |||||
| 263 | * Used by db_symbol_values to decide whether to qualify a symbol. | |||||
| 264 | */ | |||||
| 265 | boolean_t db_qualify_ambiguous_names = FALSE((boolean_t) 0); | |||||
| 266 | ||||||
| 267 | boolean_t | |||||
| 268 | db_name_is_ambiguous(char *sym_name) | |||||
| 269 | { | |||||
| 270 | int i; | |||||
| 271 | boolean_t found_once = FALSE((boolean_t) 0); | |||||
| 272 | ||||||
| 273 | if (!db_qualify_ambiguous_names) | |||||
| 274 | return FALSE((boolean_t) 0); | |||||
| 275 | ||||||
| 276 | for (i = 0; i < db_nsymtab; i++) { | |||||
| 277 | db_sym_t sp = X_db_lookup(&db_symtabs[i], sym_name)x_db[(&db_symtabs[i])->type].lookup(&db_symtabs[i] ,sym_name); | |||||
| 278 | if (sp) { | |||||
| 279 | if (found_once) | |||||
| 280 | { | |||||
| 281 | db_free_symbol(sp); | |||||
| 282 | return TRUE((boolean_t) 1); | |||||
| 283 | } | |||||
| 284 | found_once = TRUE((boolean_t) 1); | |||||
| 285 | } | |||||
| 286 | db_free_symbol(sp); | |||||
| 287 | } | |||||
| 288 | return FALSE((boolean_t) 0); | |||||
| 289 | } | |||||
| 290 | ||||||
| 291 | /* | |||||
| 292 | * Find the closest symbol to val, and return its name | |||||
| 293 | * and the difference between val and the symbol found. | |||||
| 294 | * | |||||
| 295 | * Logic change. If the task argument is non NULL and a | |||||
| 296 | * matching symbol is found in a symbol table which explicitly | |||||
| 297 | * specifies its map to be task->map, that symbol will have | |||||
| 298 | * precedence over any symbol from a symbol table will a null | |||||
| 299 | * map. This allows overlapping kernel/user maps to work correctly. | |||||
| 300 | * | |||||
| 301 | */ | |||||
| 302 | db_sym_t | |||||
| 303 | db_search_task_symbol( | |||||
| 304 | db_addr_t val, | |||||
| 305 | db_strategy_t strategy, | |||||
| 306 | db_addr_t *offp, /* better be unsigned */ | |||||
| 307 | task_t task) | |||||
| 308 | { | |||||
| 309 | db_sym_t ret; | |||||
| 310 | ||||||
| 311 | if (task != TASK_NULL((task_t) 0)) | |||||
| 312 | ret = db_search_in_task_symbol(val, strategy, offp, task); | |||||
| 313 | else | |||||
| 314 | { | |||||
| 315 | ret = db_search_in_task_symbol(val, strategy, offp, task); | |||||
| 316 | /* | |||||
| 317 | db_search_in_task_symbol will return success with | |||||
| 318 | a very large offset when it should have failed. | |||||
| 319 | */ | |||||
| 320 | if (ret == DB_SYM_NULL((db_sym_t)0) || (*offp) > 0x1000000) | |||||
| 321 | { | |||||
| 322 | db_free_symbol(ret); | |||||
| 323 | task = db_current_task()(((active_threads[(0)]))? (active_threads[(0)])->task: ((task_t ) 0)); | |||||
| 324 | ret = db_search_in_task_symbol(val, strategy, offp, task); | |||||
| 325 | } | |||||
| 326 | } | |||||
| 327 | ||||||
| 328 | return ret; | |||||
| 329 | } | |||||
| 330 | ||||||
| 331 | db_sym_t | |||||
| 332 | db_search_in_task_symbol( | |||||
| 333 | db_addr_t val, | |||||
| 334 | db_strategy_t strategy, | |||||
| 335 | db_addr_t *offp, | |||||
| 336 | task_t task) | |||||
| 337 | { | |||||
| 338 | vm_size_t diff; | |||||
| 339 | vm_size_t newdiff; | |||||
| 340 | int i; | |||||
| 341 | db_symtab_t *sp; | |||||
| 342 | db_sym_t ret = DB_SYM_NULL((db_sym_t)0), sym; | |||||
| 343 | vm_map_t map_for_val; | |||||
| 344 | ||||||
| 345 | map_for_val = (task == TASK_NULL((task_t) 0))? VM_MAP_NULL((vm_map_t) 0): task->map; | |||||
| 346 | newdiff = diff = ~0; | |||||
| 347 | db_last_symtab = (db_symtab_t *) 0; | |||||
| 348 | for (sp = &db_symtabs[0], i = 0; i < db_nsymtab; sp++, i++) | |||||
| 349 | { | |||||
| 350 | newdiff = ~0; | |||||
| 351 | if ((vm_map_t)sp->map_pointer == VM_MAP_NULL((vm_map_t) 0) || | |||||
| 352 | (vm_map_t)sp->map_pointer == map_for_val) | |||||
| 353 | { | |||||
| 354 | sym = X_db_search_symbol(sp, val, strategy, (db_expr_t*)&newdiff)x_db[(sp)->type].search_symbol(sp,val,strategy,(db_expr_t* )&newdiff); | |||||
| 355 | if (sym == DB_SYM_NULL((db_sym_t)0)) | |||||
| 356 | continue; | |||||
| 357 | if (db_last_symtab == (db_symtab_t *) 0) | |||||
| 358 | { /* first hit */ | |||||
| 359 | db_last_symtab = sp; | |||||
| 360 | diff = newdiff; | |||||
| 361 | db_free_symbol(ret); | |||||
| 362 | ret = sym; | |||||
| 363 | continue; | |||||
| 364 | } | |||||
| 365 | if ((vm_map_t) sp->map_pointer == VM_MAP_NULL((vm_map_t) 0) && | |||||
| 366 | (vm_map_t) db_last_symtab->map_pointer == VM_MAP_NULL((vm_map_t) 0) && | |||||
| 367 | newdiff < diff ) | |||||
| 368 | { /* closer null map match */ | |||||
| 369 | db_last_symtab = sp; | |||||
| 370 | diff = newdiff; | |||||
| 371 | db_free_symbol(ret); | |||||
| 372 | ret = sym; | |||||
| 373 | continue; | |||||
| 374 | } | |||||
| 375 | if ((vm_map_t) sp->map_pointer != VM_MAP_NULL((vm_map_t) 0) && | |||||
| 376 | (newdiff < 0x100000) && | |||||
| 377 | ((vm_map_t) db_last_symtab->map_pointer == VM_MAP_NULL((vm_map_t) 0) || | |||||
| 378 | newdiff < diff )) | |||||
| 379 | { /* update if new is in matching map and symbol is "close", | |||||
| 380 | and | |||||
| 381 | old is VM_MAP_NULL or old in is matching map but is further away | |||||
| 382 | */ | |||||
| 383 | db_last_symtab = sp; | |||||
| 384 | diff = newdiff; | |||||
| 385 | db_free_symbol(ret); | |||||
| 386 | ret = sym; | |||||
| 387 | continue; | |||||
| 388 | } | |||||
| 389 | } | |||||
| 390 | } | |||||
| 391 | ||||||
| 392 | *offp = diff; | |||||
| 393 | return ret; | |||||
| 394 | } | |||||
| 395 | ||||||
| 396 | /* | |||||
| 397 | * Return name and value of a symbol | |||||
| 398 | */ | |||||
| 399 | void | |||||
| 400 | db_symbol_values( | |||||
| 401 | db_symtab_t *stab, | |||||
| 402 | db_sym_t sym, | |||||
| 403 | char **namep, | |||||
| 404 | db_expr_t *valuep) | |||||
| 405 | { | |||||
| 406 | db_expr_t value; | |||||
| 407 | char *name; | |||||
| 408 | ||||||
| 409 | if (sym == DB_SYM_NULL((db_sym_t)0)) { | |||||
| 410 | *namep = 0; | |||||
| 411 | return; | |||||
| 412 | } | |||||
| 413 | if (stab == 0) | |||||
| 414 | stab = db_last_symtab; | |||||
| 415 | ||||||
| 416 | X_db_symbol_values(stab, sym, &name, &value)x_db[(stab)->type].symbol_values(stab,sym,&name,&value ); | |||||
| ||||||
| 417 | ||||||
| 418 | if (db_name_is_ambiguous(name)) | |||||
| 419 | *namep = db_qualify(name, db_last_symtab->name); | |||||
| 420 | else | |||||
| 421 | *namep = name; | |||||
| 422 | if (valuep) | |||||
| 423 | *valuep = value; | |||||
| 424 | } | |||||
| 425 | ||||||
| 426 | ||||||
| 427 | /* | |||||
| 428 | * Print the closest symbol to value | |||||
| 429 | * | |||||
| 430 | * After matching the symbol according to the given strategy | |||||
| 431 | * we print it in the name+offset format, provided the symbol's | |||||
| 432 | * value is close enough (eg smaller than db_maxoff). | |||||
| 433 | * We also attempt to print [filename:linenum] when applicable | |||||
| 434 | * (eg for procedure names). | |||||
| 435 | * | |||||
| 436 | * If we could not find a reasonable name+offset representation, | |||||
| 437 | * then we just print the value in hex. Small values might get | |||||
| 438 | * bogus symbol associations, e.g. 3 might get some absolute | |||||
| 439 | * value like _INCLUDE_VERSION or something, therefore we do | |||||
| 440 | * not accept symbols whose value is zero (and use plain hex). | |||||
| 441 | */ | |||||
| 442 | ||||||
| 443 | unsigned long db_maxoff = 0x4000; | |||||
| 444 | ||||||
| 445 | void | |||||
| 446 | db_task_printsym(off, strategy, task) | |||||
| 447 | db_addr_t off; | |||||
| 448 | db_strategy_t strategy; | |||||
| 449 | task_t task; | |||||
| 450 | { | |||||
| 451 | db_addr_t d; | |||||
| 452 | char *filename; | |||||
| 453 | char *name; | |||||
| 454 | db_expr_t value; | |||||
| 455 | int linenum; | |||||
| 456 | db_sym_t cursym; | |||||
| 457 | ||||||
| 458 | cursym = db_search_task_symbol(off, strategy, &d, task); | |||||
| 459 | db_symbol_values(0, cursym, &name, &value); | |||||
| 460 | if (name == 0 || d >= db_maxoff || value == 0 || *name == 0) { | |||||
| 461 | db_printf("%#n", off); | |||||
| 462 | db_free_symbol(cursym); | |||||
| 463 | return; | |||||
| 464 | } | |||||
| 465 | db_printf("%s", name); | |||||
| 466 | if (d) | |||||
| 467 | db_printf("+0x%x", d); | |||||
| 468 | if (strategy == DB_STGY_PROC2) { | |||||
| 469 | if (db_line_at_pc(cursym, &filename, &linenum, off)) { | |||||
| 470 | db_printf(" [%s", filename); | |||||
| 471 | if (linenum > 0) | |||||
| 472 | db_printf(":%d", linenum); | |||||
| 473 | db_printf("]"); | |||||
| 474 | } | |||||
| 475 | } | |||||
| 476 | db_free_symbol(cursym); | |||||
| 477 | } | |||||
| 478 | ||||||
| 479 | void | |||||
| 480 | db_printsym(off, strategy) | |||||
| 481 | db_expr_t off; | |||||
| 482 | db_strategy_t strategy; | |||||
| 483 | { | |||||
| 484 | db_task_printsym(off, strategy, TASK_NULL((task_t) 0)); | |||||
| ||||||
| 485 | } | |||||
| 486 | ||||||
| 487 | boolean_t | |||||
| 488 | db_line_at_pc( sym, filename, linenum, pc) | |||||
| 489 | db_sym_t sym; | |||||
| 490 | char **filename; | |||||
| 491 | int *linenum; | |||||
| 492 | db_addr_t pc; | |||||
| 493 | { | |||||
| 494 | return (db_last_symtab) ? | |||||
| 495 | X_db_line_at_pc( db_last_symtab, sym, filename, linenum, pc)x_db[(db_last_symtab)->type].line_at_pc(db_last_symtab,sym ,filename,linenum,pc) : | |||||
| 496 | FALSE((boolean_t) 0); | |||||
| 497 | } | |||||
| 498 | ||||||
| 499 | void db_free_symbol(db_sym_t s) | |||||
| 500 | { | |||||
| 501 | return (db_last_symtab) ? | |||||
| 502 | X_db_free_symbol( db_last_symtab, s)x_db[(db_last_symtab)->type].free_symbol(s) : | |||||
| 503 | FALSE((boolean_t) 0); | |||||
| 504 | } | |||||
| 505 | ||||||
| 506 | /* | |||||
| 507 | * Switch into symbol-table specific routines | |||||
| 508 | */ | |||||
| 509 | ||||||
| 510 | void dummy_db_free_symbol(db_sym_t symbol) { } | |||||
| 511 | boolean_t dummy_db_sym_init(char *a, char *b, char *c, char *d) { | |||||
| 512 | return FALSE((boolean_t) 0); | |||||
| 513 | } | |||||
| 514 | ||||||
| 515 | ||||||
| 516 | struct db_sym_switch x_db[] = { | |||||
| 517 | ||||||
| 518 | /* BSD a.out format (really, sdb/dbx(1) symtabs) */ | |||||
| 519 | #ifdef DB_NO_AOUT | |||||
| 520 | { 0,}, | |||||
| 521 | #else /* DB_NO_AOUT */ | |||||
| 522 | { aout_db_sym_init, aout_db_lookup, aout_db_search_symbol, | |||||
| 523 | aout_db_line_at_pc, aout_db_symbol_values, dummy_db_free_symbol }, | |||||
| 524 | #endif /* DB_NO_AOUT */ | |||||
| 525 | ||||||
| 526 | { 0,}, | |||||
| 527 | ||||||
| 528 | /* Machdep, not inited here */ | |||||
| 529 | { 0,}, | |||||
| 530 | ||||||
| 531 | #ifdef DB_NO_ELF | |||||
| 532 | { 0,}, | |||||
| 533 | #else /* DB_NO_ELF */ | |||||
| 534 | { dummy_db_sym_init, elf_db_lookup, elf_db_search_symbol, | |||||
| 535 | elf_db_line_at_pc, elf_db_symbol_values, dummy_db_free_symbol }, | |||||
| 536 | #endif /* DB_NO_ELF */ | |||||
| 537 | ||||||
| 538 | }; | |||||
| 539 | ||||||
| 540 | #endif /* MACH_KDB */ |