|
|
1.1 ! root 1: /* Do various things to symbol tables (other than lookup)), for GDB. ! 2: Copyright (C) 1986, 1987 Free Software Foundation, Inc. ! 3: ! 4: GDB is distributed in the hope that it will be useful, but WITHOUT ANY ! 5: WARRANTY. No author or distributor accepts responsibility to anyone ! 6: for the consequences of using it or for whether it serves any ! 7: particular purpose or works at all, unless he says so in writing. ! 8: Refer to the GDB General Public License for full details. ! 9: ! 10: Everyone is granted permission to copy, modify and redistribute GDB, ! 11: but only under the conditions described in the GDB General Public ! 12: License. A copy of this license is supposed to have been given to you ! 13: along with GDB so you can know your rights and responsibilities. It ! 14: should be in a file named COPYING. Among other things, the copyright ! 15: notice and this notice must be preserved on all copies. ! 16: ! 17: In other words, go ahead and share GDB, but don't try to stop ! 18: anyone else from sharing it farther. Help stamp out software hoarding! ! 19: */ ! 20: ! 21: ! 22: #include "defs.h" ! 23: #include "initialize.h" ! 24: #include "symtab.h" ! 25: ! 26: #include <stdio.h> ! 27: #include <obstack.h> ! 28: ! 29: static void free_symtab (); ! 30: ! 31: START_FILE ! 32: ! 33: /* Free all the symtabs that are currently installed, ! 34: and all storage associated with them. ! 35: Leaves us in a consistent state with no symtabs installed. */ ! 36: ! 37: void ! 38: free_all_symtabs () ! 39: { ! 40: register struct symtab *s, *snext; ! 41: ! 42: /* All values will be invalid because their types will be! */ ! 43: ! 44: clear_value_history (); ! 45: clear_displays (); ! 46: clear_internalvars (); ! 47: clear_breakpoints (); ! 48: set_default_breakpoint (0, 0, 0, 0); ! 49: ! 50: current_source_symtab = 0; ! 51: ! 52: for (s = symtab_list; s; s = snext) ! 53: { ! 54: snext = s->next; ! 55: free_symtab (s); ! 56: } ! 57: symtab_list = 0; ! 58: obstack_free (symbol_obstack, 0); ! 59: obstack_init (symbol_obstack); ! 60: ! 61: if (misc_function_vector) ! 62: free (misc_function_vector); ! 63: misc_function_count = 0; ! 64: misc_function_vector = 0; ! 65: } ! 66: ! 67: /* Free a struct block <- B and all the symbols defined in that block. */ ! 68: ! 69: static void ! 70: free_symtab_block (b) ! 71: struct block *b; ! 72: { ! 73: register int i, n; ! 74: n = BLOCK_NSYMS (b); ! 75: for (i = 0; i < n; i++) ! 76: { ! 77: free (SYMBOL_NAME (BLOCK_SYM (b, i))); ! 78: free (BLOCK_SYM (b, i)); ! 79: } ! 80: free (b); ! 81: } ! 82: ! 83: /* Free all the storage associated with the struct symtab <- S. ! 84: Note that some symtabs have contents malloc'ed structure by structure, ! 85: while some have contents that all live inside one big block of memory, ! 86: and some share the contents of another symbol table and so you should ! 87: not free the contents on their behalf (except sometimes the linetable, ! 88: which maybe per symtab even when the rest is not). ! 89: It is s->free_code that says which alternative to use. */ ! 90: ! 91: static void ! 92: free_symtab (s) ! 93: register struct symtab *s; ! 94: { ! 95: register int i, n; ! 96: register struct blockvector *bv; ! 97: register struct type *type; ! 98: register struct typevector *tv; ! 99: ! 100: switch (s->free_code) ! 101: { ! 102: case free_nothing: ! 103: /* All the contents are part of a big block of memory ! 104: and some other symtab is in charge of freeing that block. ! 105: Therefore, do nothing. */ ! 106: break; ! 107: ! 108: case free_contents: ! 109: /* Here all the contents were malloc'ed structure by structure ! 110: and must be freed that way. */ ! 111: /* First free the blocks (and their symbols. */ ! 112: bv = BLOCKVECTOR (s); ! 113: n = BLOCKVECTOR_NBLOCKS (bv); ! 114: for (i = 0; i < n; i++) ! 115: free_symtab_block (BLOCKVECTOR_BLOCK (bv, i)); ! 116: /* Free the blockvector itself. */ ! 117: free (bv); ! 118: /* Free the type vector. */ ! 119: tv = TYPEVECTOR (s); ! 120: free (tv); ! 121: /* Also free the linetable. */ ! 122: ! 123: case free_linetable: ! 124: /* Everything will be freed either by our `free_ptr' ! 125: or by some other symbatb, except for our linetable. ! 126: Free that now. */ ! 127: free (LINETABLE (s)); ! 128: break; ! 129: } ! 130: ! 131: /* If there is a single block of memory to free, free it. */ ! 132: if (s->free_ptr) ! 133: free (s->free_ptr); ! 134: ! 135: if (s->line_charpos) ! 136: free (s->line_charpos); ! 137: free (s->filename); ! 138: free (s); ! 139: } ! 140: ! 141: /* Convert a raw symbol-segment to a struct symtab, ! 142: and relocate its internal pointers so that it is valid. */ ! 143: ! 144: /* This is how to relocate one pointer, given a name for it. ! 145: Works independent of the type of object pointed to. */ ! 146: #define RELOCATE(slot) (slot ? (* (char **) &slot += relocation) : 0) ! 147: ! 148: /* This is the inverse of RELOCATE. We use it when storing ! 149: a core address into a slot that has yet to be relocated. */ ! 150: #define UNRELOCATE(slot) (slot ? (* (char **) &slot -= relocation) : 0) ! 151: ! 152: /* During the process of relocation, this holds the amount to relocate by ! 153: (the address of the file's symtab data, in core in the debugger). */ ! 154: static int relocation; ! 155: ! 156: #define CORE_RELOCATE(slot) \ ! 157: ((slot) += (((slot) < data_start) ? text_relocation \ ! 158: : ((slot) < bss_start) ? data_relocation : bss_relocation)) ! 159: ! 160: #define TEXT_RELOCATE(slot) ((slot) += text_relocation) ! 161: ! 162: /* Relocation amounts for addresses in the program's core image. */ ! 163: static int text_relocation, data_relocation, bss_relocation; ! 164: ! 165: /* Boundaries that divide program core addresses into text, data and bss; ! 166: used to determine which relocation amount to use. */ ! 167: static int data_start, bss_start; ! 168: ! 169: static void relocate_typevector (); ! 170: static void relocate_blockvector (); ! 171: static void relocate_type (); ! 172: static void relocate_block (); ! 173: static void relocate_symbol (); ! 174: static void relocate_source (); ! 175: ! 176: /* Relocate a file's symseg so that all the pointers are valid C pointers. ! 177: Value is a `struct symtab'; but it is not suitable for direct ! 178: insertion into the `symtab_list' because it describes several files. */ ! 179: ! 180: static struct symtab * ! 181: relocate_symtab (root) ! 182: struct symbol_root *root; ! 183: { ! 184: struct symtab *sp = (struct symtab *) xmalloc (sizeof (struct symtab)); ! 185: bzero (sp, sizeof (struct symtab)); ! 186: ! 187: relocation = (int) root; ! 188: text_relocation = root->textrel; ! 189: data_relocation = root->datarel; ! 190: bss_relocation = root->bssrel; ! 191: data_start = root->databeg; ! 192: bss_start = root->bssbeg; ! 193: ! 194: sp->filename = root->filename; ! 195: sp->ldsymoff = root->ldsymoff; ! 196: sp->language = root->language; ! 197: sp->compilation = root->compilation; ! 198: sp->version = root->version; ! 199: sp->blockvector = root->blockvector; ! 200: sp->typevector = root->typevector; ! 201: ! 202: RELOCATE (TYPEVECTOR (sp)); ! 203: RELOCATE (BLOCKVECTOR (sp)); ! 204: RELOCATE (sp->version); ! 205: RELOCATE (sp->compilation); ! 206: RELOCATE (sp->filename); ! 207: ! 208: relocate_typevector (TYPEVECTOR (sp)); ! 209: relocate_blockvector (BLOCKVECTOR (sp)); ! 210: ! 211: return sp; ! 212: } ! 213: ! 214: static void ! 215: relocate_blockvector (blp) ! 216: register struct blockvector *blp; ! 217: { ! 218: register int nblocks = BLOCKVECTOR_NBLOCKS (blp); ! 219: register int i; ! 220: for (i = 0; i < nblocks; i++) ! 221: RELOCATE (BLOCKVECTOR_BLOCK (blp, i)); ! 222: for (i = 0; i < nblocks; i++) ! 223: relocate_block (BLOCKVECTOR_BLOCK (blp, i)); ! 224: } ! 225: ! 226: static void ! 227: relocate_block (bp) ! 228: register struct block *bp; ! 229: { ! 230: register int nsyms = BLOCK_NSYMS (bp); ! 231: register int i; ! 232: ! 233: TEXT_RELOCATE (BLOCK_START (bp)); ! 234: TEXT_RELOCATE (BLOCK_END (bp)); ! 235: ! 236: /* These two should not be recursively processed. ! 237: The superblock need not be because all blocks are ! 238: processed from relocate_blockvector. ! 239: The function need not be because it will be processed ! 240: under the block which is its scope. */ ! 241: RELOCATE (BLOCK_SUPERBLOCK (bp)); ! 242: RELOCATE (BLOCK_FUNCTION (bp)); ! 243: ! 244: for (i = 0; i < nsyms; i++) ! 245: RELOCATE (BLOCK_SYM (bp, i)); ! 246: ! 247: for (i = 0; i < nsyms; i++) ! 248: relocate_symbol (BLOCK_SYM (bp, i)); ! 249: } ! 250: ! 251: static void ! 252: relocate_symbol (sp) ! 253: register struct symbol *sp; ! 254: { ! 255: RELOCATE (SYMBOL_NAME (sp)); ! 256: if (SYMBOL_CLASS (sp) == LOC_BLOCK) ! 257: { ! 258: RELOCATE (SYMBOL_BLOCK_VALUE (sp)); ! 259: /* We can assume the block that belongs to this symbol ! 260: is not relocated yet, since it comes after ! 261: the block that contains this symbol. */ ! 262: BLOCK_FUNCTION (SYMBOL_BLOCK_VALUE (sp)) = sp; ! 263: UNRELOCATE (BLOCK_FUNCTION (SYMBOL_BLOCK_VALUE (sp))); ! 264: } ! 265: else if (SYMBOL_CLASS (sp) == LOC_STATIC) ! 266: CORE_RELOCATE (SYMBOL_VALUE (sp)); ! 267: else if (SYMBOL_CLASS (sp) == LOC_LABEL) ! 268: TEXT_RELOCATE (SYMBOL_VALUE (sp)); ! 269: RELOCATE (SYMBOL_TYPE (sp)); ! 270: } ! 271: ! 272: static void ! 273: relocate_typevector (tv) ! 274: struct typevector *tv; ! 275: { ! 276: register int ntypes = TYPEVECTOR_NTYPES (tv); ! 277: register int i; ! 278: ! 279: for (i = 0; i < ntypes; i++) ! 280: RELOCATE (TYPEVECTOR_TYPE (tv, i)); ! 281: for (i = 0; i < ntypes; i++) ! 282: relocate_type (TYPEVECTOR_TYPE (tv, i)); ! 283: } ! 284: ! 285: /* We cannot come up with an a priori spanning tree ! 286: for the network of types, since types can be used ! 287: for many symbols and also as components of other types. ! 288: Therefore, we need to be able to mark types that we ! 289: already have relocated (or are already in the middle of relocating) ! 290: as in a garbage collector. */ ! 291: ! 292: static void ! 293: relocate_type (tp) ! 294: register struct type *tp; ! 295: { ! 296: register int nfields = TYPE_NFIELDS (tp); ! 297: register int i; ! 298: ! 299: RELOCATE (TYPE_NAME (tp)); ! 300: RELOCATE (TYPE_TARGET_TYPE (tp)); ! 301: RELOCATE (TYPE_FIELDS (tp)); ! 302: RELOCATE (TYPE_POINTER_TYPE (tp)); ! 303: ! 304: for (i = 0; i < nfields; i++) ! 305: { ! 306: RELOCATE (TYPE_FIELD_TYPE (tp, i)); ! 307: RELOCATE (TYPE_FIELD_NAME (tp, i)); ! 308: } ! 309: } ! 310: ! 311: static void ! 312: relocate_sourcevector (svp) ! 313: register struct sourcevector *svp; ! 314: { ! 315: register int nfiles = svp->length; ! 316: register int i; ! 317: for (i = 0; i < nfiles; i++) ! 318: RELOCATE (svp->source[i]); ! 319: for (i = 0; i < nfiles; i++) ! 320: relocate_source (svp->source[i]); ! 321: } ! 322: ! 323: static void ! 324: relocate_source (sp) ! 325: register struct source *sp; ! 326: { ! 327: register int nitems = sp->contents.nitems; ! 328: register int i; ! 329: ! 330: RELOCATE (sp->name); ! 331: for (i = 0; i < nitems; i++) ! 332: if (sp->contents.item[i] > 0) ! 333: TEXT_RELOCATE (sp->contents.item[i]); ! 334: } ! 335: ! 336: /* Read symsegs from file named NAME open on DESC, ! 337: make symtabs from them, and return a chain of them. ! 338: These symtabs are not suitable for direct use in `symtab_list' ! 339: because each one describes a single object file, perhaps many source files. ! 340: `symbol_file_command' takes each of these, makes many real symtabs ! 341: from it, and then frees it. ! 342: ! 343: We assume DESC is prepositioned at the end of the string table, ! 344: just before the symsegs if there are any. */ ! 345: ! 346: struct symtab * ! 347: read_symsegs (desc, name) ! 348: int desc; ! 349: char *name; ! 350: { ! 351: struct symbol_root root; ! 352: register char *data; ! 353: register struct symtab *sp, *sp1, *chain = 0; ! 354: register int len; ! 355: ! 356: while (1) ! 357: { ! 358: len = myread (desc, &root, sizeof root); ! 359: if (len == 0 || root.format == 0) ! 360: break; ! 361: if (root.format != 1 || ! 362: root.length < sizeof root) ! 363: error ("Invalid symbol segment format code"); ! 364: data = (char *) xmalloc (root.length); ! 365: bcopy (&root, data, sizeof root); ! 366: len = myread (desc, data + sizeof root, ! 367: root.length - sizeof root); ! 368: sp = relocate_symtab (data); ! 369: RELOCATE (((struct symbol_root *)data)->sourcevector); ! 370: relocate_sourcevector (((struct symbol_root *)data)->sourcevector); ! 371: sp->next = chain; ! 372: chain = sp; ! 373: sp->linetable = (struct linetable *) ((struct symbol_root *)data)->sourcevector; ! 374: } ! 375: ! 376: return chain; ! 377: } ! 378: ! 379: static int block_depth (); ! 380: static void print_spaces (); ! 381: static void print_symbol (); ! 382: ! 383: print_symtabs (filename) ! 384: char *filename; ! 385: { ! 386: FILE *outfile; ! 387: register struct symtab *s; ! 388: register int i, j; ! 389: int len, line, blen; ! 390: register struct linetable *l; ! 391: struct blockvector *bv; ! 392: register struct block *b; ! 393: int depth; ! 394: struct cleanup *cleanups; ! 395: extern int fclose(); ! 396: ! 397: if (filename == 0) ! 398: error_no_arg ("file to write symbol data in"); ! 399: outfile = fopen (filename, "w"); ! 400: if (outfile == 0) ! 401: perror_with_name (filename); ! 402: ! 403: cleanups = make_cleanup (fclose, outfile); ! 404: immediate_quit++; ! 405: ! 406: for (s = symtab_list; s; s = s->next) ! 407: { ! 408: /* First print the line table. */ ! 409: fprintf (outfile, "Symtab for file %s\n\n", s->filename); ! 410: fprintf (outfile, "Line table:\n\n"); ! 411: l = LINETABLE (s); ! 412: len = l->nitems; ! 413: for (i = 0; i < len; i++) ! 414: { ! 415: if (l->item[i] < 0) ! 416: line = - l->item[i] - 1; ! 417: else ! 418: fprintf (outfile, " line %d at %x\n", ++line, l->item[i]); ! 419: } ! 420: /* Now print the block info. */ ! 421: fprintf (outfile, "\nBlockvector:\n\n"); ! 422: bv = BLOCKVECTOR (s); ! 423: len = BLOCKVECTOR_NBLOCKS (bv); ! 424: for (i = 0; i < len; i++) ! 425: { ! 426: b = BLOCKVECTOR_BLOCK (bv, i); ! 427: depth = block_depth (b) * 2; ! 428: print_spaces (depth, outfile); ! 429: fprintf (outfile, "block #%03d (object 0x%x) ", i, b); ! 430: fprintf (outfile, "[0x%x..0x%x]", BLOCK_START (b), BLOCK_END (b)); ! 431: if (BLOCK_SUPERBLOCK (b)) ! 432: fprintf (outfile, " (under 0x%x)", BLOCK_SUPERBLOCK (b)); ! 433: if (BLOCK_FUNCTION (b)) ! 434: fprintf (outfile, " %s", SYMBOL_NAME (BLOCK_FUNCTION (b))); ! 435: fputc ('\n', outfile); ! 436: blen = BLOCK_NSYMS (b); ! 437: for (j = 0; j < blen; j++) ! 438: { ! 439: print_symbol (BLOCK_SYM (b, j), depth + 1, outfile); ! 440: } ! 441: } ! 442: ! 443: fprintf (outfile, "\n\n"); ! 444: } ! 445: ! 446: immediate_quit--; ! 447: do_cleanups (cleanups); ! 448: } ! 449: ! 450: static void ! 451: print_symbol (symbol, depth, outfile) ! 452: struct symbol *symbol; ! 453: int depth; ! 454: FILE *outfile; ! 455: { ! 456: print_spaces (depth, outfile); ! 457: if (SYMBOL_NAMESPACE (symbol) == LABEL_NAMESPACE) ! 458: { ! 459: fprintf (outfile, "label %s at 0x%x", SYMBOL_NAME (symbol), ! 460: SYMBOL_VALUE (symbol)); ! 461: return; ! 462: } ! 463: if (SYMBOL_NAMESPACE (symbol) == STRUCT_NAMESPACE) ! 464: { ! 465: if (TYPE_NAME (SYMBOL_TYPE (symbol))) ! 466: { ! 467: type_print_1 (SYMBOL_TYPE (symbol), "", outfile, 1, depth); ! 468: } ! 469: else ! 470: { ! 471: fprintf (outfile, "%s %s = ", ! 472: (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_ENUM ! 473: ? "enum" ! 474: : (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_STRUCT ! 475: ? "struct" : "union")), ! 476: SYMBOL_NAME (symbol)); ! 477: type_print_1 (SYMBOL_TYPE (symbol), "", outfile, 1, depth); ! 478: } ! 479: fprintf (outfile, ";\n"); ! 480: } ! 481: else ! 482: { ! 483: if (SYMBOL_CLASS (symbol) == LOC_TYPEDEF) ! 484: fprintf (outfile, "typedef "); ! 485: if (SYMBOL_TYPE (symbol)) ! 486: { ! 487: type_print_1 (SYMBOL_TYPE (symbol), SYMBOL_NAME (symbol), ! 488: outfile, 1, depth); ! 489: fprintf (outfile, "; "); ! 490: } ! 491: else ! 492: fprintf (outfile, "%s ", SYMBOL_NAME (symbol)); ! 493: ! 494: switch (SYMBOL_CLASS (symbol)) ! 495: { ! 496: case LOC_CONST: ! 497: fprintf (outfile, "const %d (0x%x),", ! 498: SYMBOL_VALUE (symbol), SYMBOL_VALUE (symbol)); ! 499: break; ! 500: ! 501: case LOC_CONST_BYTES: ! 502: fprintf (outfile, "const %d hex bytes:", ! 503: TYPE_LENGTH (SYMBOL_TYPE (symbol))); ! 504: { ! 505: int i; ! 506: for (i = 0; i < TYPE_LENGTH (SYMBOL_TYPE (symbol)); i++) ! 507: fprintf (outfile, " %2x", SYMBOL_VALUE_BYTES (symbol) [i]); ! 508: fprintf (outfile, ","); ! 509: } ! 510: break; ! 511: ! 512: case LOC_STATIC: ! 513: fprintf (outfile, "static at 0x%x,", SYMBOL_VALUE (symbol)); ! 514: break; ! 515: ! 516: case LOC_REGISTER: ! 517: fprintf (outfile, "register %d,", SYMBOL_VALUE (symbol)); ! 518: break; ! 519: ! 520: case LOC_ARG: ! 521: fprintf (outfile, "arg at 0x%x,", SYMBOL_VALUE (symbol)); ! 522: break; ! 523: ! 524: case LOC_LOCAL: ! 525: fprintf (outfile, "local at 0x%x,", SYMBOL_VALUE (symbol)); ! 526: break; ! 527: ! 528: case LOC_TYPEDEF: ! 529: break; ! 530: ! 531: case LOC_LABEL: ! 532: fprintf (outfile, "label at 0x%x", SYMBOL_VALUE (symbol)); ! 533: break; ! 534: ! 535: case LOC_BLOCK: ! 536: fprintf (outfile, "block (object 0x%x) starting at 0x%x,", ! 537: SYMBOL_VALUE (symbol), ! 538: BLOCK_START (SYMBOL_BLOCK_VALUE (symbol))); ! 539: break; ! 540: } ! 541: } ! 542: fprintf (outfile, "\n"); ! 543: } ! 544: ! 545: /* Return the nexting depth of a block within other blocks in its symtab. */ ! 546: ! 547: static int ! 548: block_depth (block) ! 549: struct block *block; ! 550: { ! 551: register int i = 0; ! 552: while (block = BLOCK_SUPERBLOCK (block)) i++; ! 553: return i; ! 554: } ! 555: ! 556: static ! 557: initialize () ! 558: { ! 559: add_com ("printsyms", class_obscure, print_symtabs, ! 560: "Print dump of current symbol definitions to file OUTFILE."); ! 561: } ! 562: ! 563: END_FILE
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.