Change GDB over to GNU General Public License version 2.
[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 GDB 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 1, or (at your option)
9 any later version.
10
11 GDB 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 GDB; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21 #include "defs.h"
22 #include "param.h"
23 #include "symtab.h"
24 #include "breakpoint.h"
25 #include "command.h"
26
27 #include <stdio.h>
28 #include <obstack.h>
29 \f
30 /* Free all the symtabs that are currently installed,
31 and all storage associated with them.
32 Leaves us in a consistent state with no symtabs installed. */
33
34 void
35 free_all_symtabs ()
36 {
37 register struct symtab *s, *snext;
38
39 /* All values will be invalid because their types will be! */
40
41 clear_value_history ();
42 clear_displays ();
43 clear_internalvars ();
44 #if defined (CLEAR_SOLIB)
45 CLEAR_SOLIB ();
46 #endif
47 set_default_breakpoint (0, 0, 0, 0);
48
49 current_source_symtab = 0;
50
51 for (s = symtab_list; s; s = snext)
52 {
53 snext = s->next;
54 free_symtab (s);
55 }
56 symtab_list = 0;
57 obstack_free (symbol_obstack, 0);
58 obstack_init (symbol_obstack);
59
60 if (misc_function_vector)
61 free (misc_function_vector);
62 misc_function_count = 0;
63 misc_function_vector = 0;
64 clear_pc_function_cache();
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 void
92 free_symtab (s)
93 register struct symtab *s;
94 {
95 register int i, n;
96 register struct blockvector *bv;
97 register struct typevector *tv;
98
99 switch (s->free_code)
100 {
101 case free_nothing:
102 /* All the contents are part of a big block of memory (an obstack),
103 and some other symtab is in charge of freeing that block.
104 Therefore, do nothing. */
105 break;
106
107 case free_contents:
108 /* Here all the contents were malloc'ed structure by structure
109 and must be freed that way. */
110 /* First free the blocks (and their symbols. */
111 bv = BLOCKVECTOR (s);
112 n = BLOCKVECTOR_NBLOCKS (bv);
113 for (i = 0; i < n; i++)
114 free_symtab_block (BLOCKVECTOR_BLOCK (bv, i));
115 /* Free the blockvector itself. */
116 free (bv);
117 /* Free the type vector. */
118 tv = TYPEVECTOR (s);
119 free (tv);
120 /* Also free the linetable. */
121
122 case free_linetable:
123 /* Everything will be freed either by our `free_ptr'
124 or by some other symbatb, except for our linetable.
125 Free that now. */
126 free (LINETABLE (s));
127 break;
128 }
129
130 /* If there is a single block of memory to free, free it. */
131 if (s->free_ptr)
132 free (s->free_ptr);
133
134 /* Free source-related stuff */
135 if (s->line_charpos)
136 free (s->line_charpos);
137 if (s->fullname)
138 free (s->fullname);
139 free (s);
140 }
141 \f
142 static int block_depth ();
143 static void print_symbol ();
144
145 void
146 print_symtabs (filename)
147 char *filename;
148 {
149 FILE *outfile;
150 register struct symtab *s;
151 register int i, j;
152 int len, blen;
153 register struct linetable *l;
154 struct blockvector *bv;
155 register struct block *b;
156 int depth;
157 struct cleanup *cleanups;
158 extern int fclose();
159
160 if (filename == 0)
161 error_no_arg ("file to write symbol data in");
162
163 filename = tilde_expand (filename);
164 make_cleanup (free, filename);
165
166 outfile = fopen (filename, "w");
167 if (outfile == 0)
168 perror_with_name (filename);
169
170 cleanups = make_cleanup (fclose, outfile);
171 immediate_quit++;
172
173 for (s = symtab_list; s; s = s->next)
174 {
175 /* First print the line table. */
176 fprintf (outfile, "Symtab for file %s\n\n", s->filename);
177 fprintf (outfile, "Line table:\n\n");
178 l = LINETABLE (s);
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 /* Now print the block info. */
184 fprintf (outfile, "\nBlockvector:\n\n");
185 bv = BLOCKVECTOR (s);
186 len = BLOCKVECTOR_NBLOCKS (bv);
187 for (i = 0; i < len; i++)
188 {
189 b = BLOCKVECTOR_BLOCK (bv, i);
190 depth = block_depth (b) * 2;
191 print_spaces (depth, outfile);
192 fprintf (outfile, "block #%03d (object 0x%x) ", i, b);
193 fprintf (outfile, "[0x%x..0x%x]", BLOCK_START (b), BLOCK_END (b));
194 if (BLOCK_SUPERBLOCK (b))
195 fprintf (outfile, " (under 0x%x)", BLOCK_SUPERBLOCK (b));
196 if (BLOCK_FUNCTION (b))
197 fprintf (outfile, " %s", SYMBOL_NAME (BLOCK_FUNCTION (b)));
198 fputc ('\n', outfile);
199 blen = BLOCK_NSYMS (b);
200 for (j = 0; j < blen; j++)
201 {
202 print_symbol (BLOCK_SYM (b, j), depth + 1, outfile);
203 }
204 }
205
206 fprintf (outfile, "\n\n");
207 }
208
209 immediate_quit--;
210 do_cleanups (cleanups);
211 }
212
213 static void
214 print_symbol (symbol, depth, outfile)
215 struct symbol *symbol;
216 int depth;
217 FILE *outfile;
218 {
219 print_spaces (depth, outfile);
220 if (SYMBOL_NAMESPACE (symbol) == LABEL_NAMESPACE)
221 {
222 fprintf (outfile, "label %s at 0x%x\n", SYMBOL_NAME (symbol),
223 SYMBOL_VALUE_ADDRESS (symbol));
224 return;
225 }
226 if (SYMBOL_NAMESPACE (symbol) == STRUCT_NAMESPACE)
227 {
228 if (TYPE_NAME (SYMBOL_TYPE (symbol)))
229 {
230 type_print_1 (SYMBOL_TYPE (symbol), "", outfile, 1, depth);
231 }
232 else
233 {
234 fprintf (outfile, "%s %s = ",
235 (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_ENUM
236 ? "enum"
237 : (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_STRUCT
238 ? "struct" : "union")),
239 SYMBOL_NAME (symbol));
240 type_print_1 (SYMBOL_TYPE (symbol), "", outfile, 1, depth);
241 }
242 fprintf (outfile, ";\n");
243 }
244 else
245 {
246 if (SYMBOL_CLASS (symbol) == LOC_TYPEDEF)
247 fprintf (outfile, "typedef ");
248 if (SYMBOL_TYPE (symbol))
249 {
250 type_print_1 (SYMBOL_TYPE (symbol), SYMBOL_NAME (symbol),
251 outfile, 1, depth);
252 fprintf (outfile, "; ");
253 }
254 else
255 fprintf (outfile, "%s ", SYMBOL_NAME (symbol));
256
257 switch (SYMBOL_CLASS (symbol))
258 {
259 case LOC_CONST:
260 fprintf (outfile, "const %ld (0x%lx),",
261 SYMBOL_VALUE (symbol), SYMBOL_VALUE (symbol));
262 break;
263
264 case LOC_CONST_BYTES:
265 fprintf (outfile, "const %u hex bytes:",
266 TYPE_LENGTH (SYMBOL_TYPE (symbol)));
267 {
268 unsigned i;
269 for (i = 0; i < TYPE_LENGTH (SYMBOL_TYPE (symbol)); i++)
270 fprintf (outfile, " %2x",
271 (unsigned)SYMBOL_VALUE_BYTES (symbol) [i]);
272 fprintf (outfile, ",");
273 }
274 break;
275
276 case LOC_STATIC:
277 fprintf (outfile, "static at 0x%x,", SYMBOL_VALUE_ADDRESS (symbol));
278 break;
279
280 case LOC_REGISTER:
281 fprintf (outfile, "register %ld,", SYMBOL_VALUE (symbol));
282 break;
283
284 case LOC_ARG:
285 fprintf (outfile, "arg at 0x%lx,", SYMBOL_VALUE (symbol));
286 break;
287
288 case LOC_LOCAL_ARG:
289 fprintf (outfile, "arg at offset 0x%x from fp,",
290 SYMBOL_VALUE (symbol));
291
292 case LOC_REF_ARG:
293 fprintf (outfile, "reference arg at 0x%lx,", SYMBOL_VALUE (symbol));
294 break;
295
296 case LOC_REGPARM:
297 fprintf (outfile, "parameter register %ld,", SYMBOL_VALUE (symbol));
298 break;
299
300 case LOC_LOCAL:
301 fprintf (outfile, "local at 0x%lx,", SYMBOL_VALUE (symbol));
302 break;
303
304 case LOC_TYPEDEF:
305 break;
306
307 case LOC_LABEL:
308 fprintf (outfile, "label at 0x%lx", SYMBOL_VALUE_ADDRESS (symbol));
309 break;
310
311 case LOC_BLOCK:
312 fprintf (outfile, "block (object 0x%x) starting at 0x%x,",
313 SYMBOL_BLOCK_VALUE (symbol),
314 BLOCK_START (SYMBOL_BLOCK_VALUE (symbol)));
315 break;
316
317 case LOC_EXTERNAL:
318 fprintf (outfile, "external at 0x%x", SYMBOL_VALUE_ADDRESS (symbol));
319 break;
320
321 default:
322 fprintf (outfile, "botched symbol class %x", SYMBOL_CLASS (symbol));
323 break;
324 }
325 }
326 fprintf (outfile, "\n");
327 }
328
329 /* Return the nexting depth of a block within other blocks in its symtab. */
330
331 static int
332 block_depth (block)
333 struct block *block;
334 {
335 register int i = 0;
336 while (block = BLOCK_SUPERBLOCK (block)) i++;
337 return i;
338 }
339 \f
340 /*
341 * Free all partial_symtab storage.
342 */
343 void
344 free_all_psymtabs()
345 {
346 obstack_free (psymbol_obstack, 0);
347 obstack_init (psymbol_obstack);
348 partial_symtab_list = (struct partial_symtab *) 0;
349 }
350 \f
351 void
352 _initialize_symmisc ()
353 {
354 symtab_list = (struct symtab *) 0;
355 partial_symtab_list = (struct partial_symtab *) 0;
356
357 add_com ("printsyms", class_obscure, print_symtabs,
358 "Print dump of current symbol definitions to file OUTFILE.");
359 }
360
This page took 0.036693 seconds and 4 git commands to generate.