|
|
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.