Remove the object file specific fields from the partial symbol table
[deliverable/binutils-gdb.git] / gdb / symmisc.c
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
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
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
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21 #include <stdio.h>
22 #include "defs.h"
23 #include "param.h"
24 #include "symtab.h"
25 #include "bfd.h"
26 #include "symfile.h"
27 #include "breakpoint.h"
28 #include "command.h"
29
30 #include <obstack.h>
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
93 void
94 free_symtab (s)
95 register struct symtab *s;
96 {
97 register int i, n;
98 register struct blockvector *bv;
99
100 switch (s->free_code)
101 {
102 case free_nothing:
103 /* All the contents are part of a big block of memory (an obstack),
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 /* 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 }
139 \f
140 static int block_depth ();
141 static void print_symbol ();
142 static void print_partial_symbol ();
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. */
175 fprintf (outfile, "Symtab for file %s\n\n", s->filename);
176 fprintf (outfile, "Line table:\n\n");
177 l = LINETABLE (s);
178 len = l->nitems;
179 for (i = 0; i < len; i++)
180 fprintf (outfile, " line %d at %x\n", l->item[i].line,
181 l->item[i].pc);
182 /* Now print the block info. */
183 fprintf (outfile, "\nBlockvector:\n\n");
184 bv = BLOCKVECTOR (s);
185 len = BLOCKVECTOR_NBLOCKS (bv);
186 for (i = 0; i < len; i++)
187 {
188 b = BLOCKVECTOR_BLOCK (bv, i);
189 depth = block_depth (b) * 2;
190 print_spaces (depth, outfile);
191 fprintf (outfile, "block #%03d (object 0x%x) ", i, b);
192 fprintf (outfile, "[0x%x..0x%x]", BLOCK_START (b), BLOCK_END (b));
193 if (BLOCK_SUPERBLOCK (b))
194 fprintf (outfile, " (under 0x%x)", BLOCK_SUPERBLOCK (b));
195 if (BLOCK_FUNCTION (b))
196 fprintf (outfile, " %s", SYMBOL_NAME (BLOCK_FUNCTION (b)));
197 fputc ('\n', outfile);
198 blen = BLOCK_NSYMS (b);
199 for (j = 0; j < blen; j++)
200 {
201 print_symbol (BLOCK_SYM (b, j), depth + 1, outfile);
202 }
203 }
204
205 fprintf (outfile, "\n\n");
206 }
207
208 immediate_quit--;
209 do_cleanups (cleanups);
210 }
211
212 static void
213 print_symbol (symbol, depth, outfile)
214 struct symbol *symbol;
215 int depth;
216 FILE *outfile;
217 {
218 print_spaces (depth, outfile);
219 if (SYMBOL_NAMESPACE (symbol) == LABEL_NAMESPACE)
220 {
221 fprintf (outfile, "label %s at 0x%x\n", SYMBOL_NAME (symbol),
222 SYMBOL_VALUE_ADDRESS (symbol));
223 return;
224 }
225 if (SYMBOL_NAMESPACE (symbol) == STRUCT_NAMESPACE)
226 {
227 if (TYPE_NAME (SYMBOL_TYPE (symbol)))
228 {
229 type_print_1 (SYMBOL_TYPE (symbol), "", outfile, 1, depth);
230 }
231 else
232 {
233 fprintf (outfile, "%s %s = ",
234 (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_ENUM
235 ? "enum"
236 : (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_STRUCT
237 ? "struct" : "union")),
238 SYMBOL_NAME (symbol));
239 type_print_1 (SYMBOL_TYPE (symbol), "", outfile, 1, depth);
240 }
241 fprintf (outfile, ";\n");
242 }
243 else
244 {
245 if (SYMBOL_CLASS (symbol) == LOC_TYPEDEF)
246 fprintf (outfile, "typedef ");
247 if (SYMBOL_TYPE (symbol))
248 {
249 type_print_1 (SYMBOL_TYPE (symbol), SYMBOL_NAME (symbol),
250 outfile, 1, depth);
251 fprintf (outfile, "; ");
252 }
253 else
254 fprintf (outfile, "%s ", SYMBOL_NAME (symbol));
255
256 switch (SYMBOL_CLASS (symbol))
257 {
258 case LOC_CONST:
259 fprintf (outfile, "const %ld (0x%lx),",
260 SYMBOL_VALUE (symbol), SYMBOL_VALUE (symbol));
261 break;
262
263 case LOC_CONST_BYTES:
264 fprintf (outfile, "const %u hex bytes:",
265 TYPE_LENGTH (SYMBOL_TYPE (symbol)));
266 {
267 unsigned i;
268 for (i = 0; i < TYPE_LENGTH (SYMBOL_TYPE (symbol)); i++)
269 fprintf (outfile, " %2x",
270 (unsigned)SYMBOL_VALUE_BYTES (symbol) [i]);
271 fprintf (outfile, ",");
272 }
273 break;
274
275 case LOC_STATIC:
276 fprintf (outfile, "static at 0x%x,", SYMBOL_VALUE_ADDRESS (symbol));
277 break;
278
279 case LOC_REGISTER:
280 fprintf (outfile, "register %ld,", SYMBOL_VALUE (symbol));
281 break;
282
283 case LOC_ARG:
284 fprintf (outfile, "arg at 0x%lx,", SYMBOL_VALUE (symbol));
285 break;
286
287 case LOC_LOCAL_ARG:
288 fprintf (outfile, "arg at offset 0x%x from fp,",
289 SYMBOL_VALUE (symbol));
290
291 case LOC_REF_ARG:
292 fprintf (outfile, "reference arg at 0x%lx,", SYMBOL_VALUE (symbol));
293 break;
294
295 case LOC_REGPARM:
296 fprintf (outfile, "parameter register %ld,", SYMBOL_VALUE (symbol));
297 break;
298
299 case LOC_LOCAL:
300 fprintf (outfile, "local at 0x%lx,", SYMBOL_VALUE (symbol));
301 break;
302
303 case LOC_TYPEDEF:
304 break;
305
306 case LOC_LABEL:
307 fprintf (outfile, "label at 0x%lx", SYMBOL_VALUE_ADDRESS (symbol));
308 break;
309
310 case LOC_BLOCK:
311 fprintf (outfile, "block (object 0x%x) starting at 0x%x,",
312 SYMBOL_BLOCK_VALUE (symbol),
313 BLOCK_START (SYMBOL_BLOCK_VALUE (symbol)));
314 break;
315
316 default:
317 fprintf (outfile, "botched symbol class %x", SYMBOL_CLASS (symbol));
318 break;
319 }
320 }
321 fprintf (outfile, "\n");
322 }
323
324 void
325 print_partial_symtabs (filename)
326 char *filename;
327 {
328 FILE *outfile;
329 struct partial_symtab *p;
330 struct cleanup *cleanups;
331 extern int fclose();
332
333 if (filename == 0)
334 error_no_arg ("file to write partial symbol data in");
335
336 filename = tilde_expand (filename);
337 make_cleanup (free, filename);
338
339 outfile = fopen (filename, "w");
340 if (outfile == 0)
341 perror_with_name (filename);
342
343 cleanups = make_cleanup (fclose, outfile);
344 immediate_quit++;
345
346 for (p = partial_symtab_list; p; p = p->next)
347 {
348 fprintf_filtered (outfile, "Partial symtab for source file %s ",
349 p->filename);
350 fprintf_filtered (outfile, "(object 0x%x)\n\n", p);
351 fprintf_filtered (outfile, " Full symbol table %s been read from %s\n",
352 p->readin ? "has" : "has not yet",
353 p->symfile_name);
354 if (p->readin)
355 fprintf_filtered (outfile, " Was read into symtab at 0x%x by function at 0x%x\n",
356 p->symtab, p->read_symtab);
357 fprintf_filtered (outfile, " Relocate symbols by 0x%x\n", p->addr);
358 fprintf_filtered (outfile, " Symbols cover text addresses 0x%x-0x%x\n",
359 p->textlow, p->texthigh);
360 fprintf_filtered (outfile, " Depends on %d other partial symtabs.\n",
361 p->number_of_dependencies);
362 if (p->n_global_syms > 0)
363 print_partial_symbol (global_psymbols.list + p->globals_offset,
364 p->n_global_syms, "Global", outfile);
365 if (p->n_static_syms > 0)
366 print_partial_symbol (static_psymbols.list + p->statics_offset,
367 p->n_static_syms, "Static", outfile);
368 fprintf_filtered (outfile, "\n\n");
369 }
370
371 immediate_quit--;
372 do_cleanups (cleanups);
373 }
374
375 static void
376 print_partial_symbol (p, count, what, outfile)
377 struct partial_symbol *p;
378 int count;
379 char *what;
380 FILE *outfile;
381 {
382 char *space;
383 char *class;
384
385 fprintf_filtered (outfile, " %s partial symbols:\n", what);
386 while (count-- > 0)
387 {
388 fprintf_filtered (outfile, " `%s', ", SYMBOL_NAME(p));
389 switch (SYMBOL_NAMESPACE (p))
390 {
391 case UNDEF_NAMESPACE:
392 fputs_filtered ("undefined namespace, ", outfile);
393 break;
394 case VAR_NAMESPACE:
395 /* This is the usual thing -- don't print it */
396 break;
397 case STRUCT_NAMESPACE:
398 fputs_filtered ("struct namespace, ", outfile);
399 break;
400 case LABEL_NAMESPACE:
401 fputs_filtered ("label namespace, ", outfile);
402 break;
403 default:
404 fputs_filtered ("<invalid namespace>, ", outfile);
405 break;
406 }
407 switch (SYMBOL_CLASS (p))
408 {
409 case LOC_UNDEF:
410 fputs_filtered ("undefined", outfile);
411 break;
412 case LOC_CONST:
413 fputs_filtered ("constant int", outfile);
414 break;
415 case LOC_STATIC:
416 fputs_filtered ("static", outfile);
417 break;
418 case LOC_REGISTER:
419 fputs_filtered ("register", outfile);
420 break;
421 case LOC_ARG:
422 fputs_filtered ("pass by value", outfile);
423 break;
424 case LOC_REF_ARG:
425 fputs_filtered ("pass by reference", outfile);
426 break;
427 case LOC_REGPARM:
428 fputs_filtered ("register parameter", outfile);
429 break;
430 case LOC_LOCAL:
431 fputs_filtered ("stack parameter", outfile);
432 break;
433 case LOC_TYPEDEF:
434 fputs_filtered ("type", outfile);
435 break;
436 case LOC_LABEL:
437 fputs_filtered ("label", outfile);
438 break;
439 case LOC_BLOCK:
440 fputs_filtered ("function", outfile);
441 break;
442 case LOC_CONST_BYTES:
443 fputs_filtered ("constant bytes", outfile);
444 break;
445 case LOC_LOCAL_ARG:
446 fputs_filtered ("shuffled arg", outfile);
447 break;
448 default:
449 fputs_filtered ("<invalid location>", outfile);
450 break;
451 }
452 fputs_filtered (", ", outfile);
453 fprintf_filtered (outfile, "0x%x\n", SYMBOL_VALUE (p));
454 p++;
455 }
456 }
457
458 /* Return the nexting depth of a block within other blocks in its symtab. */
459
460 static int
461 block_depth (block)
462 struct block *block;
463 {
464 register int i = 0;
465 while (block = BLOCK_SUPERBLOCK (block)) i++;
466 return i;
467 }
468 \f
469 /*
470 * Free all partial_symtab storage.
471 */
472 void
473 free_all_psymtabs()
474 {
475 obstack_free (psymbol_obstack, 0);
476 obstack_init (psymbol_obstack);
477 partial_symtab_list = (struct partial_symtab *) 0;
478 }
479 \f
480 void
481 _initialize_symmisc ()
482 {
483 symtab_list = (struct symtab *) 0;
484 partial_symtab_list = (struct partial_symtab *) 0;
485
486 add_com ("printsyms", class_obscure, print_symtabs,
487 "Print dump of current symbol definitions to file OUTFILE.");
488 add_com ("printpsyms", class_obscure, print_partial_symtabs,
489 "Print dump of current partial symbol definitions to file OUTFILE.");
490 }
491
This page took 0.03976 seconds and 5 git commands to generate.