]>
Commit | Line | Data |
---|---|---|
bd5635a1 RP |
1 | /* Do various things to symbol tables (other than lookup)), for GDB. |
2 | Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of GDB. | |
5 | ||
4a35d6e9 | 6 | This program is free software; you can redistribute it and/or modify |
bd5635a1 | 7 | it under the terms of the GNU General Public License as published by |
4a35d6e9 FF |
8 | the Free Software Foundation; either version 2 of the License, or |
9 | (at your option) any later version. | |
bd5635a1 | 10 | |
4a35d6e9 | 11 | This program is distributed in the hope that it will be useful, |
bd5635a1 RP |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
4a35d6e9 FF |
17 | along with this program; if not, write to the Free Software |
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
bd5635a1 RP |
19 | |
20 | ||
4a35d6e9 | 21 | #include <stdio.h> |
bd5635a1 RP |
22 | #include "defs.h" |
23 | #include "param.h" | |
24 | #include "symtab.h" | |
4a35d6e9 FF |
25 | #include "bfd.h" |
26 | #include "symfile.h" | |
bd5635a1 RP |
27 | #include "breakpoint.h" |
28 | #include "command.h" | |
29 | ||
bd5635a1 | 30 | #include <obstack.h> |
bd5635a1 RP |
31 | \f |
32 | /* Free all the symtabs that are currently installed, | |
33 | and all storage associated with them. | |
34 | Leaves us in a consistent state with no symtabs installed. */ | |
35 | ||
36 | void | |
37 | free_all_symtabs () | |
38 | { | |
39 | register struct symtab *s, *snext; | |
40 | ||
41 | /* All values will be invalid because their types will be! */ | |
42 | ||
43 | clear_value_history (); | |
44 | clear_displays (); | |
45 | clear_internalvars (); | |
46 | #if defined (CLEAR_SOLIB) | |
47 | CLEAR_SOLIB (); | |
48 | #endif | |
49 | set_default_breakpoint (0, 0, 0, 0); | |
50 | ||
51 | current_source_symtab = 0; | |
52 | ||
53 | for (s = symtab_list; s; s = snext) | |
54 | { | |
55 | snext = s->next; | |
56 | free_symtab (s); | |
57 | } | |
58 | symtab_list = 0; | |
59 | obstack_free (symbol_obstack, 0); | |
60 | obstack_init (symbol_obstack); | |
61 | ||
62 | if (misc_function_vector) | |
63 | free (misc_function_vector); | |
64 | misc_function_count = 0; | |
65 | misc_function_vector = 0; | |
66 | clear_pc_function_cache(); | |
67 | } | |
68 | ||
69 | /* Free a struct block <- B and all the symbols defined in that block. */ | |
70 | ||
71 | static void | |
72 | free_symtab_block (b) | |
73 | struct block *b; | |
74 | { | |
75 | register int i, n; | |
76 | n = BLOCK_NSYMS (b); | |
77 | for (i = 0; i < n; i++) | |
78 | { | |
79 | free (SYMBOL_NAME (BLOCK_SYM (b, i))); | |
80 | free (BLOCK_SYM (b, i)); | |
81 | } | |
82 | free (b); | |
83 | } | |
84 | ||
85 | /* Free all the storage associated with the struct symtab <- S. | |
86 | Note that some symtabs have contents malloc'ed structure by structure, | |
87 | while some have contents that all live inside one big block of memory, | |
88 | and some share the contents of another symbol table and so you should | |
89 | not free the contents on their behalf (except sometimes the linetable, | |
90 | which maybe per symtab even when the rest is not). | |
91 | It is s->free_code that says which alternative to use. */ | |
92 | ||
029981e2 | 93 | void |
bd5635a1 RP |
94 | free_symtab (s) |
95 | register struct symtab *s; | |
96 | { | |
97 | register int i, n; | |
98 | register struct blockvector *bv; | |
bd5635a1 RP |
99 | |
100 | switch (s->free_code) | |
101 | { | |
102 | case free_nothing: | |
029981e2 | 103 | /* All the contents are part of a big block of memory (an obstack), |
bd5635a1 RP |
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); | |
bd5635a1 RP |
118 | /* Also free the linetable. */ |
119 | ||
120 | case free_linetable: | |
121 | /* Everything will be freed either by our `free_ptr' | |
122 | or by some other symbatb, except for our linetable. | |
123 | Free that now. */ | |
124 | free (LINETABLE (s)); | |
125 | break; | |
126 | } | |
127 | ||
128 | /* If there is a single block of memory to free, free it. */ | |
129 | if (s->free_ptr) | |
130 | free (s->free_ptr); | |
131 | ||
132 | /* Free source-related stuff */ | |
133 | if (s->line_charpos) | |
134 | free (s->line_charpos); | |
135 | if (s->fullname) | |
136 | free (s->fullname); | |
137 | free (s); | |
138 | } | |
bd5635a1 RP |
139 | \f |
140 | static int block_depth (); | |
141 | static void print_symbol (); | |
4a35d6e9 | 142 | static void print_partial_symbol (); |
bd5635a1 RP |
143 | |
144 | void | |
145 | print_symtabs (filename) | |
146 | char *filename; | |
147 | { | |
148 | FILE *outfile; | |
149 | register struct symtab *s; | |
150 | register int i, j; | |
151 | int len, blen; | |
152 | register struct linetable *l; | |
153 | struct blockvector *bv; | |
154 | register struct block *b; | |
155 | int depth; | |
156 | struct cleanup *cleanups; | |
157 | extern int fclose(); | |
158 | ||
159 | if (filename == 0) | |
160 | error_no_arg ("file to write symbol data in"); | |
161 | ||
162 | filename = tilde_expand (filename); | |
163 | make_cleanup (free, filename); | |
164 | ||
165 | outfile = fopen (filename, "w"); | |
166 | if (outfile == 0) | |
167 | perror_with_name (filename); | |
168 | ||
169 | cleanups = make_cleanup (fclose, outfile); | |
170 | immediate_quit++; | |
171 | ||
172 | for (s = symtab_list; s; s = s->next) | |
173 | { | |
174 | /* First print the line table. */ | |
4137c5fc | 175 | fprintf (outfile, "Symtab for file %s\n", s->filename); |
bd5635a1 | 176 | l = LINETABLE (s); |
4137c5fc JG |
177 | if (l) { |
178 | fprintf (outfile, "\nLine table:\n\n"); | |
179 | len = l->nitems; | |
180 | for (i = 0; i < len; i++) | |
181 | fprintf (outfile, " line %d at %x\n", l->item[i].line, | |
182 | l->item[i].pc); | |
183 | } | |
bd5635a1 RP |
184 | /* Now print the block info. */ |
185 | fprintf (outfile, "\nBlockvector:\n\n"); | |
186 | bv = BLOCKVECTOR (s); | |
187 | len = BLOCKVECTOR_NBLOCKS (bv); | |
188 | for (i = 0; i < len; i++) | |
189 | { | |
190 | b = BLOCKVECTOR_BLOCK (bv, i); | |
191 | depth = block_depth (b) * 2; | |
192 | print_spaces (depth, outfile); | |
193 | fprintf (outfile, "block #%03d (object 0x%x) ", i, b); | |
194 | fprintf (outfile, "[0x%x..0x%x]", BLOCK_START (b), BLOCK_END (b)); | |
195 | if (BLOCK_SUPERBLOCK (b)) | |
196 | fprintf (outfile, " (under 0x%x)", BLOCK_SUPERBLOCK (b)); | |
197 | if (BLOCK_FUNCTION (b)) | |
198 | fprintf (outfile, " %s", SYMBOL_NAME (BLOCK_FUNCTION (b))); | |
199 | fputc ('\n', outfile); | |
200 | blen = BLOCK_NSYMS (b); | |
201 | for (j = 0; j < blen; j++) | |
202 | { | |
203 | print_symbol (BLOCK_SYM (b, j), depth + 1, outfile); | |
204 | } | |
205 | } | |
206 | ||
207 | fprintf (outfile, "\n\n"); | |
208 | } | |
209 | ||
210 | immediate_quit--; | |
211 | do_cleanups (cleanups); | |
212 | } | |
213 | ||
214 | static void | |
215 | print_symbol (symbol, depth, outfile) | |
216 | struct symbol *symbol; | |
217 | int depth; | |
218 | FILE *outfile; | |
219 | { | |
220 | print_spaces (depth, outfile); | |
221 | if (SYMBOL_NAMESPACE (symbol) == LABEL_NAMESPACE) | |
222 | { | |
223 | fprintf (outfile, "label %s at 0x%x\n", SYMBOL_NAME (symbol), | |
224 | SYMBOL_VALUE_ADDRESS (symbol)); | |
225 | return; | |
226 | } | |
227 | if (SYMBOL_NAMESPACE (symbol) == STRUCT_NAMESPACE) | |
228 | { | |
229 | if (TYPE_NAME (SYMBOL_TYPE (symbol))) | |
230 | { | |
231 | type_print_1 (SYMBOL_TYPE (symbol), "", outfile, 1, depth); | |
232 | } | |
233 | else | |
234 | { | |
235 | fprintf (outfile, "%s %s = ", | |
236 | (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_ENUM | |
237 | ? "enum" | |
238 | : (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_STRUCT | |
239 | ? "struct" : "union")), | |
240 | SYMBOL_NAME (symbol)); | |
241 | type_print_1 (SYMBOL_TYPE (symbol), "", outfile, 1, depth); | |
242 | } | |
243 | fprintf (outfile, ";\n"); | |
244 | } | |
245 | else | |
246 | { | |
247 | if (SYMBOL_CLASS (symbol) == LOC_TYPEDEF) | |
248 | fprintf (outfile, "typedef "); | |
249 | if (SYMBOL_TYPE (symbol)) | |
250 | { | |
251 | type_print_1 (SYMBOL_TYPE (symbol), SYMBOL_NAME (symbol), | |
252 | outfile, 1, depth); | |
253 | fprintf (outfile, "; "); | |
254 | } | |
255 | else | |
256 | fprintf (outfile, "%s ", SYMBOL_NAME (symbol)); | |
257 | ||
258 | switch (SYMBOL_CLASS (symbol)) | |
259 | { | |
260 | case LOC_CONST: | |
261 | fprintf (outfile, "const %ld (0x%lx),", | |
262 | SYMBOL_VALUE (symbol), SYMBOL_VALUE (symbol)); | |
263 | break; | |
264 | ||
265 | case LOC_CONST_BYTES: | |
266 | fprintf (outfile, "const %u hex bytes:", | |
267 | TYPE_LENGTH (SYMBOL_TYPE (symbol))); | |
268 | { | |
269 | unsigned i; | |
270 | for (i = 0; i < TYPE_LENGTH (SYMBOL_TYPE (symbol)); i++) | |
271 | fprintf (outfile, " %2x", | |
272 | (unsigned)SYMBOL_VALUE_BYTES (symbol) [i]); | |
273 | fprintf (outfile, ","); | |
274 | } | |
275 | break; | |
276 | ||
277 | case LOC_STATIC: | |
278 | fprintf (outfile, "static at 0x%x,", SYMBOL_VALUE_ADDRESS (symbol)); | |
279 | break; | |
280 | ||
281 | case LOC_REGISTER: | |
282 | fprintf (outfile, "register %ld,", SYMBOL_VALUE (symbol)); | |
283 | break; | |
284 | ||
285 | case LOC_ARG: | |
286 | fprintf (outfile, "arg at 0x%lx,", SYMBOL_VALUE (symbol)); | |
287 | break; | |
288 | ||
289 | case LOC_LOCAL_ARG: | |
290 | fprintf (outfile, "arg at offset 0x%x from fp,", | |
291 | SYMBOL_VALUE (symbol)); | |
292 | ||
293 | case LOC_REF_ARG: | |
294 | fprintf (outfile, "reference arg at 0x%lx,", SYMBOL_VALUE (symbol)); | |
295 | break; | |
296 | ||
297 | case LOC_REGPARM: | |
298 | fprintf (outfile, "parameter register %ld,", SYMBOL_VALUE (symbol)); | |
299 | break; | |
300 | ||
301 | case LOC_LOCAL: | |
302 | fprintf (outfile, "local at 0x%lx,", SYMBOL_VALUE (symbol)); | |
303 | break; | |
304 | ||
305 | case LOC_TYPEDEF: | |
306 | break; | |
307 | ||
308 | case LOC_LABEL: | |
309 | fprintf (outfile, "label at 0x%lx", SYMBOL_VALUE_ADDRESS (symbol)); | |
310 | break; | |
311 | ||
312 | case LOC_BLOCK: | |
313 | fprintf (outfile, "block (object 0x%x) starting at 0x%x,", | |
314 | SYMBOL_BLOCK_VALUE (symbol), | |
315 | BLOCK_START (SYMBOL_BLOCK_VALUE (symbol))); | |
316 | break; | |
317 | ||
bd5635a1 RP |
318 | default: |
319 | fprintf (outfile, "botched symbol class %x", SYMBOL_CLASS (symbol)); | |
320 | break; | |
321 | } | |
322 | } | |
323 | fprintf (outfile, "\n"); | |
324 | } | |
325 | ||
4a35d6e9 FF |
326 | void |
327 | print_partial_symtabs (filename) | |
328 | char *filename; | |
329 | { | |
330 | FILE *outfile; | |
331 | struct partial_symtab *p; | |
332 | struct cleanup *cleanups; | |
333 | extern int fclose(); | |
334 | ||
335 | if (filename == 0) | |
336 | error_no_arg ("file to write partial symbol data in"); | |
337 | ||
338 | filename = tilde_expand (filename); | |
339 | make_cleanup (free, filename); | |
340 | ||
341 | outfile = fopen (filename, "w"); | |
342 | if (outfile == 0) | |
343 | perror_with_name (filename); | |
344 | ||
345 | cleanups = make_cleanup (fclose, outfile); | |
346 | immediate_quit++; | |
347 | ||
348 | for (p = partial_symtab_list; p; p = p->next) | |
349 | { | |
350 | fprintf_filtered (outfile, "Partial symtab for source file %s ", | |
351 | p->filename); | |
352 | fprintf_filtered (outfile, "(object 0x%x)\n\n", p); | |
353 | fprintf_filtered (outfile, " Full symbol table %s been read from %s\n", | |
354 | p->readin ? "has" : "has not yet", | |
355 | p->symfile_name); | |
356 | if (p->readin) | |
357 | fprintf_filtered (outfile, " Was read into symtab at 0x%x by function at 0x%x\n", | |
358 | p->symtab, p->read_symtab); | |
359 | fprintf_filtered (outfile, " Relocate symbols by 0x%x\n", p->addr); | |
360 | fprintf_filtered (outfile, " Symbols cover text addresses 0x%x-0x%x\n", | |
361 | p->textlow, p->texthigh); | |
362 | fprintf_filtered (outfile, " Depends on %d other partial symtabs.\n", | |
363 | p->number_of_dependencies); | |
364 | if (p->n_global_syms > 0) | |
365 | print_partial_symbol (global_psymbols.list + p->globals_offset, | |
366 | p->n_global_syms, "Global", outfile); | |
367 | if (p->n_static_syms > 0) | |
368 | print_partial_symbol (static_psymbols.list + p->statics_offset, | |
369 | p->n_static_syms, "Static", outfile); | |
370 | fprintf_filtered (outfile, "\n\n"); | |
371 | } | |
372 | ||
373 | immediate_quit--; | |
374 | do_cleanups (cleanups); | |
375 | } | |
376 | ||
377 | static void | |
378 | print_partial_symbol (p, count, what, outfile) | |
379 | struct partial_symbol *p; | |
380 | int count; | |
381 | char *what; | |
382 | FILE *outfile; | |
383 | { | |
384 | char *space; | |
385 | char *class; | |
386 | ||
387 | fprintf_filtered (outfile, " %s partial symbols:\n", what); | |
388 | while (count-- > 0) | |
389 | { | |
390 | fprintf_filtered (outfile, " `%s', ", SYMBOL_NAME(p)); | |
391 | switch (SYMBOL_NAMESPACE (p)) | |
392 | { | |
393 | case UNDEF_NAMESPACE: | |
394 | fputs_filtered ("undefined namespace, ", outfile); | |
395 | break; | |
396 | case VAR_NAMESPACE: | |
397 | /* This is the usual thing -- don't print it */ | |
398 | break; | |
399 | case STRUCT_NAMESPACE: | |
400 | fputs_filtered ("struct namespace, ", outfile); | |
401 | break; | |
402 | case LABEL_NAMESPACE: | |
403 | fputs_filtered ("label namespace, ", outfile); | |
404 | break; | |
405 | default: | |
406 | fputs_filtered ("<invalid namespace>, ", outfile); | |
407 | break; | |
408 | } | |
409 | switch (SYMBOL_CLASS (p)) | |
410 | { | |
411 | case LOC_UNDEF: | |
412 | fputs_filtered ("undefined", outfile); | |
413 | break; | |
414 | case LOC_CONST: | |
415 | fputs_filtered ("constant int", outfile); | |
416 | break; | |
417 | case LOC_STATIC: | |
418 | fputs_filtered ("static", outfile); | |
419 | break; | |
420 | case LOC_REGISTER: | |
421 | fputs_filtered ("register", outfile); | |
422 | break; | |
423 | case LOC_ARG: | |
424 | fputs_filtered ("pass by value", outfile); | |
425 | break; | |
426 | case LOC_REF_ARG: | |
427 | fputs_filtered ("pass by reference", outfile); | |
428 | break; | |
429 | case LOC_REGPARM: | |
430 | fputs_filtered ("register parameter", outfile); | |
431 | break; | |
432 | case LOC_LOCAL: | |
433 | fputs_filtered ("stack parameter", outfile); | |
434 | break; | |
435 | case LOC_TYPEDEF: | |
436 | fputs_filtered ("type", outfile); | |
437 | break; | |
438 | case LOC_LABEL: | |
439 | fputs_filtered ("label", outfile); | |
440 | break; | |
441 | case LOC_BLOCK: | |
442 | fputs_filtered ("function", outfile); | |
443 | break; | |
444 | case LOC_CONST_BYTES: | |
445 | fputs_filtered ("constant bytes", outfile); | |
446 | break; | |
447 | case LOC_LOCAL_ARG: | |
448 | fputs_filtered ("shuffled arg", outfile); | |
449 | break; | |
450 | default: | |
451 | fputs_filtered ("<invalid location>", outfile); | |
452 | break; | |
453 | } | |
454 | fputs_filtered (", ", outfile); | |
455 | fprintf_filtered (outfile, "0x%x\n", SYMBOL_VALUE (p)); | |
456 | p++; | |
457 | } | |
458 | } | |
459 | ||
bd5635a1 RP |
460 | /* Return the nexting depth of a block within other blocks in its symtab. */ |
461 | ||
462 | static int | |
463 | block_depth (block) | |
464 | struct block *block; | |
465 | { | |
466 | register int i = 0; | |
467 | while (block = BLOCK_SUPERBLOCK (block)) i++; | |
468 | return i; | |
469 | } | |
470 | \f | |
471 | /* | |
472 | * Free all partial_symtab storage. | |
473 | */ | |
474 | void | |
475 | free_all_psymtabs() | |
476 | { | |
477 | obstack_free (psymbol_obstack, 0); | |
478 | obstack_init (psymbol_obstack); | |
479 | partial_symtab_list = (struct partial_symtab *) 0; | |
480 | } | |
481 | \f | |
482 | void | |
483 | _initialize_symmisc () | |
484 | { | |
485 | symtab_list = (struct symtab *) 0; | |
486 | partial_symtab_list = (struct partial_symtab *) 0; | |
487 | ||
488 | add_com ("printsyms", class_obscure, print_symtabs, | |
489 | "Print dump of current symbol definitions to file OUTFILE."); | |
4a35d6e9 FF |
490 | add_com ("printpsyms", class_obscure, print_partial_symtabs, |
491 | "Print dump of current partial symbol definitions to file OUTFILE."); | |
bd5635a1 RP |
492 | } |
493 |