]> Git Repo - binutils.git/blob - gdb/symmisc.c
ansi name abuse changes
[binutils.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.050078 seconds and 4 git commands to generate.