]>
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 | ||
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> | |
bd5635a1 RP |
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 | ||
029981e2 | 91 | void |
bd5635a1 RP |
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: | |
029981e2 | 102 | /* All the contents are part of a big block of memory (an obstack), |
bd5635a1 RP |
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 | } | |
bd5635a1 RP |
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 |