* buildsym.c: Break out initial malloc sizes.
[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", s->filename);
176 l = LINETABLE (s);
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 }
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
318 default:
319 fprintf (outfile, "botched symbol class %x", SYMBOL_CLASS (symbol));
320 break;
321 }
322 }
323 fprintf (outfile, "\n");
324 }
325
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
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.");
490 add_com ("printpsyms", class_obscure, print_partial_symtabs,
491 "Print dump of current partial symbol definitions to file OUTFILE.");
492 }
493
This page took 0.039127 seconds and 5 git commands to generate.