1e93f7393Sniklas /* Do various things to symbol tables (other than lookup), for GDB.
2b725ae77Skettenis
3b725ae77Skettenis Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
4b725ae77Skettenis 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004 Free Software
5b725ae77Skettenis Foundation, Inc.
6e93f7393Sniklas
7e93f7393Sniklas This file is part of GDB.
8e93f7393Sniklas
9e93f7393Sniklas This program is free software; you can redistribute it and/or modify
10e93f7393Sniklas it under the terms of the GNU General Public License as published by
11e93f7393Sniklas the Free Software Foundation; either version 2 of the License, or
12e93f7393Sniklas (at your option) any later version.
13e93f7393Sniklas
14e93f7393Sniklas This program is distributed in the hope that it will be useful,
15e93f7393Sniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
16e93f7393Sniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17e93f7393Sniklas GNU General Public License for more details.
18e93f7393Sniklas
19e93f7393Sniklas You should have received a copy of the GNU General Public License
20e93f7393Sniklas along with this program; if not, write to the Free Software
21b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
22b725ae77Skettenis Boston, MA 02111-1307, USA. */
23e93f7393Sniklas
24e93f7393Sniklas #include "defs.h"
25e93f7393Sniklas #include "symtab.h"
26e93f7393Sniklas #include "gdbtypes.h"
27e93f7393Sniklas #include "bfd.h"
28e93f7393Sniklas #include "symfile.h"
29e93f7393Sniklas #include "objfiles.h"
30e93f7393Sniklas #include "breakpoint.h"
31e93f7393Sniklas #include "command.h"
32b725ae77Skettenis #include "gdb_obstack.h"
33e93f7393Sniklas #include "language.h"
34e93f7393Sniklas #include "bcache.h"
35b725ae77Skettenis #include "block.h"
36b725ae77Skettenis #include "gdb_regex.h"
37b725ae77Skettenis #include "dictionary.h"
38e93f7393Sniklas
39e93f7393Sniklas #include "gdb_string.h"
40b725ae77Skettenis #include "readline/readline.h"
41e93f7393Sniklas
42e93f7393Sniklas #ifndef DEV_TTY
43e93f7393Sniklas #define DEV_TTY "/dev/tty"
44e93f7393Sniklas #endif
45e93f7393Sniklas
46e93f7393Sniklas /* Unfortunately for debugging, stderr is usually a macro. This is painful
47e93f7393Sniklas when calling functions that take FILE *'s from the debugger.
48e93f7393Sniklas So we make a variable which has the same value and which is accessible when
49e93f7393Sniklas debugging GDB with itself. Because stdin et al need not be constants,
50e93f7393Sniklas we initialize them in the _initialize_symmisc function at the bottom
51e93f7393Sniklas of the file. */
52e93f7393Sniklas FILE *std_in;
53e93f7393Sniklas FILE *std_out;
54e93f7393Sniklas FILE *std_err;
55e93f7393Sniklas
56e93f7393Sniklas /* Prototypes for local functions */
57e93f7393Sniklas
58b725ae77Skettenis static void dump_symtab (struct objfile *, struct symtab *,
59b725ae77Skettenis struct ui_file *);
60e93f7393Sniklas
61b725ae77Skettenis static void dump_psymtab (struct objfile *, struct partial_symtab *,
62b725ae77Skettenis struct ui_file *);
63e93f7393Sniklas
64b725ae77Skettenis static void dump_msymbols (struct objfile *, struct ui_file *);
65e93f7393Sniklas
66b725ae77Skettenis static void dump_objfile (struct objfile *);
67e93f7393Sniklas
68b725ae77Skettenis static int block_depth (struct block *);
69e93f7393Sniklas
70b725ae77Skettenis static void print_partial_symbols (struct partial_symbol **, int,
71b725ae77Skettenis char *, struct ui_file *);
72e93f7393Sniklas
73b725ae77Skettenis static void free_symtab_block (struct objfile *, struct block *);
74b725ae77Skettenis
75b725ae77Skettenis void _initialize_symmisc (void);
76b725ae77Skettenis
77b725ae77Skettenis struct print_symbol_args
78b725ae77Skettenis {
79e93f7393Sniklas struct symbol *symbol;
80e93f7393Sniklas int depth;
81b725ae77Skettenis struct ui_file *outfile;
82e93f7393Sniklas };
83e93f7393Sniklas
84b725ae77Skettenis static int print_symbol (void *);
85e93f7393Sniklas
86b725ae77Skettenis static void free_symtab_block (struct objfile *, struct block *);
87e93f7393Sniklas
88b725ae77Skettenis
89e93f7393Sniklas /* Free a struct block <- B and all the symbols defined in that block. */
90e93f7393Sniklas
91b725ae77Skettenis /* FIXME: carlton/2003-04-28: I don't believe this is currently ever
92b725ae77Skettenis used. */
93b725ae77Skettenis
94e93f7393Sniklas static void
free_symtab_block(struct objfile * objfile,struct block * b)95b725ae77Skettenis free_symtab_block (struct objfile *objfile, struct block *b)
96e93f7393Sniklas {
97b725ae77Skettenis struct dict_iterator iter;
98b725ae77Skettenis struct symbol *sym;
99b725ae77Skettenis
100b725ae77Skettenis ALL_BLOCK_SYMBOLS (b, iter, sym)
101e93f7393Sniklas {
102*63addd46Skettenis xfree (DEPRECATED_SYMBOL_NAME (sym));
103*63addd46Skettenis xfree (sym);
104e93f7393Sniklas }
105b725ae77Skettenis
106b725ae77Skettenis dict_free (BLOCK_DICT (b));
107*63addd46Skettenis xfree (b);
108e93f7393Sniklas }
109e93f7393Sniklas
110e93f7393Sniklas /* Free all the storage associated with the struct symtab <- S.
111e93f7393Sniklas Note that some symtabs have contents malloc'ed structure by structure,
112e93f7393Sniklas while some have contents that all live inside one big block of memory,
113e93f7393Sniklas and some share the contents of another symbol table and so you should
114e93f7393Sniklas not free the contents on their behalf (except sometimes the linetable,
115e93f7393Sniklas which maybe per symtab even when the rest is not).
116e93f7393Sniklas It is s->free_code that says which alternative to use. */
117e93f7393Sniklas
118e93f7393Sniklas void
free_symtab(struct symtab * s)119b725ae77Skettenis free_symtab (struct symtab *s)
120e93f7393Sniklas {
121b725ae77Skettenis int i, n;
122b725ae77Skettenis struct blockvector *bv;
123e93f7393Sniklas
124e93f7393Sniklas switch (s->free_code)
125e93f7393Sniklas {
126e93f7393Sniklas case free_nothing:
127e93f7393Sniklas /* All the contents are part of a big block of memory (an obstack),
128e93f7393Sniklas and some other symtab is in charge of freeing that block.
129e93f7393Sniklas Therefore, do nothing. */
130e93f7393Sniklas break;
131e93f7393Sniklas
132e93f7393Sniklas case free_contents:
133e93f7393Sniklas /* Here all the contents were malloc'ed structure by structure
134e93f7393Sniklas and must be freed that way. */
135e93f7393Sniklas /* First free the blocks (and their symbols. */
136e93f7393Sniklas bv = BLOCKVECTOR (s);
137e93f7393Sniklas n = BLOCKVECTOR_NBLOCKS (bv);
138e93f7393Sniklas for (i = 0; i < n; i++)
139e93f7393Sniklas free_symtab_block (s->objfile, BLOCKVECTOR_BLOCK (bv, i));
140e93f7393Sniklas /* Free the blockvector itself. */
141*63addd46Skettenis xfree (bv);
142e93f7393Sniklas /* Also free the linetable. */
143e93f7393Sniklas
144e93f7393Sniklas case free_linetable:
145b725ae77Skettenis /* Everything will be freed either by our `free_func'
146e93f7393Sniklas or by some other symtab, except for our linetable.
147e93f7393Sniklas Free that now. */
148e93f7393Sniklas if (LINETABLE (s))
149*63addd46Skettenis xfree (LINETABLE (s));
150e93f7393Sniklas break;
151e93f7393Sniklas }
152e93f7393Sniklas
153e93f7393Sniklas /* If there is a single block of memory to free, free it. */
154b725ae77Skettenis if (s->free_func != NULL)
155b725ae77Skettenis s->free_func (s);
156e93f7393Sniklas
157e93f7393Sniklas /* Free source-related stuff */
158e93f7393Sniklas if (s->line_charpos != NULL)
159*63addd46Skettenis xfree (s->line_charpos);
160e93f7393Sniklas if (s->fullname != NULL)
161*63addd46Skettenis xfree (s->fullname);
162b725ae77Skettenis if (s->debugformat != NULL)
163*63addd46Skettenis xfree (s->debugformat);
164*63addd46Skettenis xfree (s);
165e93f7393Sniklas }
166e93f7393Sniklas
167e93f7393Sniklas void
print_symbol_bcache_statistics(void)168b725ae77Skettenis print_symbol_bcache_statistics (void)
169e93f7393Sniklas {
170e93f7393Sniklas struct objfile *objfile;
171e93f7393Sniklas
172e93f7393Sniklas immediate_quit++;
173e93f7393Sniklas ALL_OBJFILES (objfile)
174e93f7393Sniklas {
175e93f7393Sniklas printf_filtered ("Byte cache statistics for '%s':\n", objfile->name);
176b725ae77Skettenis print_bcache_statistics (objfile->psymbol_cache, "partial symbol cache");
177e93f7393Sniklas }
178e93f7393Sniklas immediate_quit--;
179e93f7393Sniklas }
180e93f7393Sniklas
181e93f7393Sniklas void
print_objfile_statistics(void)182b725ae77Skettenis print_objfile_statistics (void)
183e93f7393Sniklas {
184e93f7393Sniklas struct objfile *objfile;
185b725ae77Skettenis struct symtab *s;
186b725ae77Skettenis struct partial_symtab *ps;
187b725ae77Skettenis int i, linetables, blockvectors;
188e93f7393Sniklas
189e93f7393Sniklas immediate_quit++;
190e93f7393Sniklas ALL_OBJFILES (objfile)
191e93f7393Sniklas {
192e93f7393Sniklas printf_filtered ("Statistics for '%s':\n", objfile->name);
193e93f7393Sniklas if (OBJSTAT (objfile, n_stabs) > 0)
194e93f7393Sniklas printf_filtered (" Number of \"stab\" symbols read: %d\n",
195e93f7393Sniklas OBJSTAT (objfile, n_stabs));
196e93f7393Sniklas if (OBJSTAT (objfile, n_minsyms) > 0)
197b725ae77Skettenis printf_filtered (" Number of \"minimal\" symbols read: %d\n",
198e93f7393Sniklas OBJSTAT (objfile, n_minsyms));
199e93f7393Sniklas if (OBJSTAT (objfile, n_psyms) > 0)
200b725ae77Skettenis printf_filtered (" Number of \"partial\" symbols read: %d\n",
201e93f7393Sniklas OBJSTAT (objfile, n_psyms));
202e93f7393Sniklas if (OBJSTAT (objfile, n_syms) > 0)
203b725ae77Skettenis printf_filtered (" Number of \"full\" symbols read: %d\n",
204e93f7393Sniklas OBJSTAT (objfile, n_syms));
205e93f7393Sniklas if (OBJSTAT (objfile, n_types) > 0)
206b725ae77Skettenis printf_filtered (" Number of \"types\" defined: %d\n",
207e93f7393Sniklas OBJSTAT (objfile, n_types));
208b725ae77Skettenis i = 0;
209b725ae77Skettenis ALL_OBJFILE_PSYMTABS (objfile, ps)
210b725ae77Skettenis {
211b725ae77Skettenis if (ps->readin == 0)
212b725ae77Skettenis i++;
213b725ae77Skettenis }
214b725ae77Skettenis printf_filtered (" Number of psym tables (not yet expanded): %d\n", i);
215b725ae77Skettenis i = linetables = blockvectors = 0;
216b725ae77Skettenis ALL_OBJFILE_SYMTABS (objfile, s)
217b725ae77Skettenis {
218b725ae77Skettenis i++;
219b725ae77Skettenis if (s->linetable != NULL)
220b725ae77Skettenis linetables++;
221b725ae77Skettenis if (s->primary == 1)
222b725ae77Skettenis blockvectors++;
223b725ae77Skettenis }
224b725ae77Skettenis printf_filtered (" Number of symbol tables: %d\n", i);
225b725ae77Skettenis printf_filtered (" Number of symbol tables with line tables: %d\n",
226b725ae77Skettenis linetables);
227b725ae77Skettenis printf_filtered (" Number of symbol tables with blockvectors: %d\n",
228b725ae77Skettenis blockvectors);
229b725ae77Skettenis
230e93f7393Sniklas if (OBJSTAT (objfile, sz_strtab) > 0)
231e93f7393Sniklas printf_filtered (" Space used by a.out string tables: %d\n",
232e93f7393Sniklas OBJSTAT (objfile, sz_strtab));
233b725ae77Skettenis printf_filtered (" Total memory used for objfile obstack: %d\n",
234b725ae77Skettenis obstack_memory_used (&objfile->objfile_obstack));
235e93f7393Sniklas printf_filtered (" Total memory used for psymbol cache: %d\n",
236b725ae77Skettenis bcache_memory_used (objfile->psymbol_cache));
237b725ae77Skettenis printf_filtered (" Total memory used for macro cache: %d\n",
238b725ae77Skettenis bcache_memory_used (objfile->macro_cache));
239e93f7393Sniklas }
240e93f7393Sniklas immediate_quit--;
241e93f7393Sniklas }
242e93f7393Sniklas
243e93f7393Sniklas static void
dump_objfile(struct objfile * objfile)244b725ae77Skettenis dump_objfile (struct objfile *objfile)
245e93f7393Sniklas {
246e93f7393Sniklas struct symtab *symtab;
247e93f7393Sniklas struct partial_symtab *psymtab;
248e93f7393Sniklas
249e93f7393Sniklas printf_filtered ("\nObject file %s: ", objfile->name);
250e93f7393Sniklas printf_filtered ("Objfile at ");
251b725ae77Skettenis gdb_print_host_address (objfile, gdb_stdout);
252e93f7393Sniklas printf_filtered (", bfd at ");
253b725ae77Skettenis gdb_print_host_address (objfile->obfd, gdb_stdout);
254e93f7393Sniklas printf_filtered (", %d minsyms\n\n",
255e93f7393Sniklas objfile->minimal_symbol_count);
256e93f7393Sniklas
257e93f7393Sniklas if (objfile->psymtabs)
258e93f7393Sniklas {
259e93f7393Sniklas printf_filtered ("Psymtabs:\n");
260e93f7393Sniklas for (psymtab = objfile->psymtabs;
261e93f7393Sniklas psymtab != NULL;
262e93f7393Sniklas psymtab = psymtab->next)
263e93f7393Sniklas {
264e93f7393Sniklas printf_filtered ("%s at ",
265e93f7393Sniklas psymtab->filename);
266b725ae77Skettenis gdb_print_host_address (psymtab, gdb_stdout);
267e93f7393Sniklas printf_filtered (", ");
268e93f7393Sniklas if (psymtab->objfile != objfile)
269e93f7393Sniklas {
270e93f7393Sniklas printf_filtered ("NOT ON CHAIN! ");
271e93f7393Sniklas }
272e93f7393Sniklas wrap_here (" ");
273e93f7393Sniklas }
274e93f7393Sniklas printf_filtered ("\n\n");
275e93f7393Sniklas }
276e93f7393Sniklas
277e93f7393Sniklas if (objfile->symtabs)
278e93f7393Sniklas {
279e93f7393Sniklas printf_filtered ("Symtabs:\n");
280e93f7393Sniklas for (symtab = objfile->symtabs;
281e93f7393Sniklas symtab != NULL;
282e93f7393Sniklas symtab = symtab->next)
283e93f7393Sniklas {
284e93f7393Sniklas printf_filtered ("%s at ", symtab->filename);
285b725ae77Skettenis gdb_print_host_address (symtab, gdb_stdout);
286e93f7393Sniklas printf_filtered (", ");
287e93f7393Sniklas if (symtab->objfile != objfile)
288e93f7393Sniklas {
289e93f7393Sniklas printf_filtered ("NOT ON CHAIN! ");
290e93f7393Sniklas }
291e93f7393Sniklas wrap_here (" ");
292e93f7393Sniklas }
293e93f7393Sniklas printf_filtered ("\n\n");
294e93f7393Sniklas }
295e93f7393Sniklas }
296e93f7393Sniklas
297e93f7393Sniklas /* Print minimal symbols from this objfile. */
298e93f7393Sniklas
299e93f7393Sniklas static void
dump_msymbols(struct objfile * objfile,struct ui_file * outfile)300b725ae77Skettenis dump_msymbols (struct objfile *objfile, struct ui_file *outfile)
301e93f7393Sniklas {
302e93f7393Sniklas struct minimal_symbol *msymbol;
303e93f7393Sniklas int index;
304e93f7393Sniklas char ms_type;
305e93f7393Sniklas
306e93f7393Sniklas fprintf_filtered (outfile, "\nObject file %s:\n\n", objfile->name);
307e93f7393Sniklas if (objfile->minimal_symbol_count == 0)
308e93f7393Sniklas {
309e93f7393Sniklas fprintf_filtered (outfile, "No minimal symbols found.\n");
310e93f7393Sniklas return;
311e93f7393Sniklas }
312e93f7393Sniklas for (index = 0, msymbol = objfile->msymbols;
313b725ae77Skettenis DEPRECATED_SYMBOL_NAME (msymbol) != NULL; msymbol++, index++)
314e93f7393Sniklas {
315e93f7393Sniklas switch (msymbol->type)
316e93f7393Sniklas {
317e93f7393Sniklas case mst_unknown:
318e93f7393Sniklas ms_type = 'u';
319e93f7393Sniklas break;
320e93f7393Sniklas case mst_text:
321e93f7393Sniklas ms_type = 'T';
322e93f7393Sniklas break;
323e93f7393Sniklas case mst_solib_trampoline:
324e93f7393Sniklas ms_type = 'S';
325e93f7393Sniklas break;
326e93f7393Sniklas case mst_data:
327e93f7393Sniklas ms_type = 'D';
328e93f7393Sniklas break;
329e93f7393Sniklas case mst_bss:
330e93f7393Sniklas ms_type = 'B';
331e93f7393Sniklas break;
332e93f7393Sniklas case mst_abs:
333e93f7393Sniklas ms_type = 'A';
334e93f7393Sniklas break;
335e93f7393Sniklas case mst_file_text:
336e93f7393Sniklas ms_type = 't';
337e93f7393Sniklas break;
338e93f7393Sniklas case mst_file_data:
339e93f7393Sniklas ms_type = 'd';
340e93f7393Sniklas break;
341e93f7393Sniklas case mst_file_bss:
342e93f7393Sniklas ms_type = 'b';
343e93f7393Sniklas break;
344e93f7393Sniklas default:
345e93f7393Sniklas ms_type = '?';
346e93f7393Sniklas break;
347e93f7393Sniklas }
348b725ae77Skettenis fprintf_filtered (outfile, "[%2d] %c ", index, ms_type);
349b725ae77Skettenis print_address_numeric (SYMBOL_VALUE_ADDRESS (msymbol), 1, outfile);
350b725ae77Skettenis fprintf_filtered (outfile, " %s", DEPRECATED_SYMBOL_NAME (msymbol));
351b725ae77Skettenis if (SYMBOL_BFD_SECTION (msymbol))
352b725ae77Skettenis fprintf_filtered (outfile, " section %s",
353b725ae77Skettenis bfd_section_name (objfile->obfd,
354b725ae77Skettenis SYMBOL_BFD_SECTION (msymbol)));
355e93f7393Sniklas if (SYMBOL_DEMANGLED_NAME (msymbol) != NULL)
356e93f7393Sniklas {
357e93f7393Sniklas fprintf_filtered (outfile, " %s", SYMBOL_DEMANGLED_NAME (msymbol));
358e93f7393Sniklas }
359e93f7393Sniklas #ifdef SOFUN_ADDRESS_MAYBE_MISSING
360e93f7393Sniklas if (msymbol->filename)
361e93f7393Sniklas fprintf_filtered (outfile, " %s", msymbol->filename);
362e93f7393Sniklas #endif
363e93f7393Sniklas fputs_filtered ("\n", outfile);
364e93f7393Sniklas }
365e93f7393Sniklas if (objfile->minimal_symbol_count != index)
366e93f7393Sniklas {
367e93f7393Sniklas warning ("internal error: minimal symbol count %d != %d",
368e93f7393Sniklas objfile->minimal_symbol_count, index);
369e93f7393Sniklas }
370e93f7393Sniklas fprintf_filtered (outfile, "\n");
371e93f7393Sniklas }
372e93f7393Sniklas
373e93f7393Sniklas static void
dump_psymtab(struct objfile * objfile,struct partial_symtab * psymtab,struct ui_file * outfile)374b725ae77Skettenis dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
375b725ae77Skettenis struct ui_file *outfile)
376e93f7393Sniklas {
377e93f7393Sniklas int i;
378e93f7393Sniklas
379e93f7393Sniklas fprintf_filtered (outfile, "\nPartial symtab for source file %s ",
380e93f7393Sniklas psymtab->filename);
381e93f7393Sniklas fprintf_filtered (outfile, "(object ");
382b725ae77Skettenis gdb_print_host_address (psymtab, outfile);
383e93f7393Sniklas fprintf_filtered (outfile, ")\n\n");
384e93f7393Sniklas fprintf_unfiltered (outfile, " Read from object file %s (",
385e93f7393Sniklas objfile->name);
386b725ae77Skettenis gdb_print_host_address (objfile, outfile);
387e93f7393Sniklas fprintf_unfiltered (outfile, ")\n");
388e93f7393Sniklas
389e93f7393Sniklas if (psymtab->readin)
390e93f7393Sniklas {
391e93f7393Sniklas fprintf_filtered (outfile,
392e93f7393Sniklas " Full symtab was read (at ");
393b725ae77Skettenis gdb_print_host_address (psymtab->symtab, outfile);
394e93f7393Sniklas fprintf_filtered (outfile, " by function at ");
395b725ae77Skettenis gdb_print_host_address (psymtab->read_symtab, outfile);
396e93f7393Sniklas fprintf_filtered (outfile, ")\n");
397e93f7393Sniklas }
398e93f7393Sniklas
399e93f7393Sniklas fprintf_filtered (outfile, " Relocate symbols by ");
400e93f7393Sniklas for (i = 0; i < psymtab->objfile->num_sections; ++i)
401e93f7393Sniklas {
402e93f7393Sniklas if (i != 0)
403e93f7393Sniklas fprintf_filtered (outfile, ", ");
404e93f7393Sniklas wrap_here (" ");
405e93f7393Sniklas print_address_numeric (ANOFFSET (psymtab->section_offsets, i),
406e93f7393Sniklas 1,
407e93f7393Sniklas outfile);
408e93f7393Sniklas }
409e93f7393Sniklas fprintf_filtered (outfile, "\n");
410e93f7393Sniklas
411e93f7393Sniklas fprintf_filtered (outfile, " Symbols cover text addresses ");
412e93f7393Sniklas print_address_numeric (psymtab->textlow, 1, outfile);
413e93f7393Sniklas fprintf_filtered (outfile, "-");
414e93f7393Sniklas print_address_numeric (psymtab->texthigh, 1, outfile);
415e93f7393Sniklas fprintf_filtered (outfile, "\n");
416e93f7393Sniklas fprintf_filtered (outfile, " Depends on %d other partial symtabs.\n",
417e93f7393Sniklas psymtab->number_of_dependencies);
418e93f7393Sniklas for (i = 0; i < psymtab->number_of_dependencies; i++)
419e93f7393Sniklas {
420e93f7393Sniklas fprintf_filtered (outfile, " %d ", i);
421b725ae77Skettenis gdb_print_host_address (psymtab->dependencies[i], outfile);
422e93f7393Sniklas fprintf_filtered (outfile, " %s\n",
423e93f7393Sniklas psymtab->dependencies[i]->filename);
424e93f7393Sniklas }
425e93f7393Sniklas if (psymtab->n_global_syms > 0)
426e93f7393Sniklas {
427e93f7393Sniklas print_partial_symbols (objfile->global_psymbols.list
428e93f7393Sniklas + psymtab->globals_offset,
429e93f7393Sniklas psymtab->n_global_syms, "Global", outfile);
430e93f7393Sniklas }
431e93f7393Sniklas if (psymtab->n_static_syms > 0)
432e93f7393Sniklas {
433e93f7393Sniklas print_partial_symbols (objfile->static_psymbols.list
434e93f7393Sniklas + psymtab->statics_offset,
435e93f7393Sniklas psymtab->n_static_syms, "Static", outfile);
436e93f7393Sniklas }
437e93f7393Sniklas fprintf_filtered (outfile, "\n");
438e93f7393Sniklas }
439e93f7393Sniklas
440e93f7393Sniklas static void
dump_symtab(struct objfile * objfile,struct symtab * symtab,struct ui_file * outfile)441b725ae77Skettenis dump_symtab (struct objfile *objfile, struct symtab *symtab,
442b725ae77Skettenis struct ui_file *outfile)
443e93f7393Sniklas {
444b725ae77Skettenis int i;
445b725ae77Skettenis struct dict_iterator iter;
446e93f7393Sniklas int len, blen;
447b725ae77Skettenis struct linetable *l;
448e93f7393Sniklas struct blockvector *bv;
449b725ae77Skettenis struct symbol *sym;
450b725ae77Skettenis struct block *b;
451e93f7393Sniklas int depth;
452e93f7393Sniklas
453e93f7393Sniklas fprintf_filtered (outfile, "\nSymtab for file %s\n", symtab->filename);
454b725ae77Skettenis if (symtab->dirname)
455b725ae77Skettenis fprintf_filtered (outfile, "Compilation directory is %s\n",
456b725ae77Skettenis symtab->dirname);
457e93f7393Sniklas fprintf_filtered (outfile, "Read from object file %s (", objfile->name);
458b725ae77Skettenis gdb_print_host_address (objfile, outfile);
459e93f7393Sniklas fprintf_filtered (outfile, ")\n");
460e93f7393Sniklas fprintf_filtered (outfile, "Language: %s\n", language_str (symtab->language));
461e93f7393Sniklas
462e93f7393Sniklas /* First print the line table. */
463e93f7393Sniklas l = LINETABLE (symtab);
464e93f7393Sniklas if (l)
465e93f7393Sniklas {
466e93f7393Sniklas fprintf_filtered (outfile, "\nLine table:\n\n");
467e93f7393Sniklas len = l->nitems;
468e93f7393Sniklas for (i = 0; i < len; i++)
469e93f7393Sniklas {
470e93f7393Sniklas fprintf_filtered (outfile, " line %d at ", l->item[i].line);
471e93f7393Sniklas print_address_numeric (l->item[i].pc, 1, outfile);
472e93f7393Sniklas fprintf_filtered (outfile, "\n");
473e93f7393Sniklas }
474e93f7393Sniklas }
475e93f7393Sniklas /* Now print the block info, but only for primary symtabs since we will
476e93f7393Sniklas print lots of duplicate info otherwise. */
477e93f7393Sniklas if (symtab->primary)
478e93f7393Sniklas {
479e93f7393Sniklas fprintf_filtered (outfile, "\nBlockvector:\n\n");
480e93f7393Sniklas bv = BLOCKVECTOR (symtab);
481e93f7393Sniklas len = BLOCKVECTOR_NBLOCKS (bv);
482e93f7393Sniklas for (i = 0; i < len; i++)
483e93f7393Sniklas {
484e93f7393Sniklas b = BLOCKVECTOR_BLOCK (bv, i);
485e93f7393Sniklas depth = block_depth (b) * 2;
486e93f7393Sniklas print_spaces (depth, outfile);
487e93f7393Sniklas fprintf_filtered (outfile, "block #%03d, object at ", i);
488b725ae77Skettenis gdb_print_host_address (b, outfile);
489e93f7393Sniklas if (BLOCK_SUPERBLOCK (b))
490e93f7393Sniklas {
491e93f7393Sniklas fprintf_filtered (outfile, " under ");
492b725ae77Skettenis gdb_print_host_address (BLOCK_SUPERBLOCK (b), outfile);
493e93f7393Sniklas }
494b725ae77Skettenis /* drow/2002-07-10: We could save the total symbols count
495b725ae77Skettenis even if we're using a hashtable, but nothing else but this message
496b725ae77Skettenis wants it. */
497b725ae77Skettenis fprintf_filtered (outfile, ", %d syms/buckets in ",
498b725ae77Skettenis dict_size (BLOCK_DICT (b)));
499e93f7393Sniklas print_address_numeric (BLOCK_START (b), 1, outfile);
500e93f7393Sniklas fprintf_filtered (outfile, "..");
501e93f7393Sniklas print_address_numeric (BLOCK_END (b), 1, outfile);
502e93f7393Sniklas if (BLOCK_FUNCTION (b))
503e93f7393Sniklas {
504b725ae77Skettenis fprintf_filtered (outfile, ", function %s", DEPRECATED_SYMBOL_NAME (BLOCK_FUNCTION (b)));
505e93f7393Sniklas if (SYMBOL_DEMANGLED_NAME (BLOCK_FUNCTION (b)) != NULL)
506e93f7393Sniklas {
507e93f7393Sniklas fprintf_filtered (outfile, ", %s",
508e93f7393Sniklas SYMBOL_DEMANGLED_NAME (BLOCK_FUNCTION (b)));
509e93f7393Sniklas }
510e93f7393Sniklas }
511e93f7393Sniklas if (BLOCK_GCC_COMPILED (b))
512e93f7393Sniklas fprintf_filtered (outfile, ", compiled with gcc%d", BLOCK_GCC_COMPILED (b));
513e93f7393Sniklas fprintf_filtered (outfile, "\n");
514b725ae77Skettenis /* Now print each symbol in this block (in no particular order, if
515b725ae77Skettenis we're using a hashtable). */
516b725ae77Skettenis ALL_BLOCK_SYMBOLS (b, iter, sym)
517e93f7393Sniklas {
518e93f7393Sniklas struct print_symbol_args s;
519b725ae77Skettenis s.symbol = sym;
520e93f7393Sniklas s.depth = depth + 1;
521e93f7393Sniklas s.outfile = outfile;
522e93f7393Sniklas catch_errors (print_symbol, &s, "Error printing symbol:\n",
523e93f7393Sniklas RETURN_MASK_ALL);
524e93f7393Sniklas }
525e93f7393Sniklas }
526e93f7393Sniklas fprintf_filtered (outfile, "\n");
527e93f7393Sniklas }
528e93f7393Sniklas else
529e93f7393Sniklas {
530e93f7393Sniklas fprintf_filtered (outfile, "\nBlockvector same as previous symtab\n\n");
531e93f7393Sniklas }
532e93f7393Sniklas }
533e93f7393Sniklas
534e93f7393Sniklas void
maintenance_print_symbols(char * args,int from_tty)535b725ae77Skettenis maintenance_print_symbols (char *args, int from_tty)
536e93f7393Sniklas {
537e93f7393Sniklas char **argv;
538b725ae77Skettenis struct ui_file *outfile;
539e93f7393Sniklas struct cleanup *cleanups;
540e93f7393Sniklas char *symname = NULL;
541e93f7393Sniklas char *filename = DEV_TTY;
542e93f7393Sniklas struct objfile *objfile;
543e93f7393Sniklas struct symtab *s;
544e93f7393Sniklas
545e93f7393Sniklas dont_repeat ();
546e93f7393Sniklas
547e93f7393Sniklas if (args == NULL)
548e93f7393Sniklas {
549e93f7393Sniklas error ("\
550e93f7393Sniklas Arguments missing: an output file name and an optional symbol file name");
551e93f7393Sniklas }
552e93f7393Sniklas else if ((argv = buildargv (args)) == NULL)
553e93f7393Sniklas {
554e93f7393Sniklas nomem (0);
555e93f7393Sniklas }
556b725ae77Skettenis cleanups = make_cleanup_freeargv (argv);
557e93f7393Sniklas
558e93f7393Sniklas if (argv[0] != NULL)
559e93f7393Sniklas {
560e93f7393Sniklas filename = argv[0];
561e93f7393Sniklas /* If a second arg is supplied, it is a source file name to match on */
562e93f7393Sniklas if (argv[1] != NULL)
563e93f7393Sniklas {
564e93f7393Sniklas symname = argv[1];
565e93f7393Sniklas }
566e93f7393Sniklas }
567e93f7393Sniklas
568e93f7393Sniklas filename = tilde_expand (filename);
569b725ae77Skettenis make_cleanup (xfree, filename);
570e93f7393Sniklas
571e93f7393Sniklas outfile = gdb_fopen (filename, FOPEN_WT);
572e93f7393Sniklas if (outfile == 0)
573e93f7393Sniklas perror_with_name (filename);
574b725ae77Skettenis make_cleanup_ui_file_delete (outfile);
575e93f7393Sniklas
576e93f7393Sniklas immediate_quit++;
577e93f7393Sniklas ALL_SYMTABS (objfile, s)
578b725ae77Skettenis if (symname == NULL || strcmp (symname, s->filename) == 0)
579e93f7393Sniklas dump_symtab (objfile, s, outfile);
580e93f7393Sniklas immediate_quit--;
581e93f7393Sniklas do_cleanups (cleanups);
582e93f7393Sniklas }
583e93f7393Sniklas
584e93f7393Sniklas /* Print symbol ARGS->SYMBOL on ARGS->OUTFILE. ARGS->DEPTH says how
585e93f7393Sniklas far to indent. ARGS is really a struct print_symbol_args *, but is
586e93f7393Sniklas declared as char * to get it past catch_errors. Returns 0 for error,
587e93f7393Sniklas 1 for success. */
588e93f7393Sniklas
589e93f7393Sniklas static int
print_symbol(void * args)590b725ae77Skettenis print_symbol (void *args)
591e93f7393Sniklas {
592e93f7393Sniklas struct symbol *symbol = ((struct print_symbol_args *) args)->symbol;
593e93f7393Sniklas int depth = ((struct print_symbol_args *) args)->depth;
594b725ae77Skettenis struct ui_file *outfile = ((struct print_symbol_args *) args)->outfile;
595e93f7393Sniklas
596e93f7393Sniklas print_spaces (depth, outfile);
597b725ae77Skettenis if (SYMBOL_DOMAIN (symbol) == LABEL_DOMAIN)
598e93f7393Sniklas {
599b725ae77Skettenis fprintf_filtered (outfile, "label %s at ", SYMBOL_PRINT_NAME (symbol));
600e93f7393Sniklas print_address_numeric (SYMBOL_VALUE_ADDRESS (symbol), 1, outfile);
601b725ae77Skettenis if (SYMBOL_BFD_SECTION (symbol))
602b725ae77Skettenis fprintf_filtered (outfile, " section %s\n",
603b725ae77Skettenis bfd_section_name (SYMBOL_BFD_SECTION (symbol)->owner,
604b725ae77Skettenis SYMBOL_BFD_SECTION (symbol)));
605b725ae77Skettenis else
606e93f7393Sniklas fprintf_filtered (outfile, "\n");
607e93f7393Sniklas return 1;
608e93f7393Sniklas }
609b725ae77Skettenis if (SYMBOL_DOMAIN (symbol) == STRUCT_DOMAIN)
610e93f7393Sniklas {
611e93f7393Sniklas if (TYPE_TAG_NAME (SYMBOL_TYPE (symbol)))
612e93f7393Sniklas {
613e93f7393Sniklas LA_PRINT_TYPE (SYMBOL_TYPE (symbol), "", outfile, 1, depth);
614e93f7393Sniklas }
615e93f7393Sniklas else
616e93f7393Sniklas {
617e93f7393Sniklas fprintf_filtered (outfile, "%s %s = ",
618e93f7393Sniklas (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_ENUM
619e93f7393Sniklas ? "enum"
620e93f7393Sniklas : (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_STRUCT
621e93f7393Sniklas ? "struct" : "union")),
622b725ae77Skettenis DEPRECATED_SYMBOL_NAME (symbol));
623e93f7393Sniklas LA_PRINT_TYPE (SYMBOL_TYPE (symbol), "", outfile, 1, depth);
624e93f7393Sniklas }
625e93f7393Sniklas fprintf_filtered (outfile, ";\n");
626e93f7393Sniklas }
627e93f7393Sniklas else
628e93f7393Sniklas {
629e93f7393Sniklas if (SYMBOL_CLASS (symbol) == LOC_TYPEDEF)
630e93f7393Sniklas fprintf_filtered (outfile, "typedef ");
631e93f7393Sniklas if (SYMBOL_TYPE (symbol))
632e93f7393Sniklas {
633e93f7393Sniklas /* Print details of types, except for enums where it's clutter. */
634b725ae77Skettenis LA_PRINT_TYPE (SYMBOL_TYPE (symbol), SYMBOL_PRINT_NAME (symbol),
635e93f7393Sniklas outfile,
636e93f7393Sniklas TYPE_CODE (SYMBOL_TYPE (symbol)) != TYPE_CODE_ENUM,
637e93f7393Sniklas depth);
638e93f7393Sniklas fprintf_filtered (outfile, "; ");
639e93f7393Sniklas }
640e93f7393Sniklas else
641b725ae77Skettenis fprintf_filtered (outfile, "%s ", SYMBOL_PRINT_NAME (symbol));
642e93f7393Sniklas
643e93f7393Sniklas switch (SYMBOL_CLASS (symbol))
644e93f7393Sniklas {
645e93f7393Sniklas case LOC_CONST:
646e93f7393Sniklas fprintf_filtered (outfile, "const %ld (0x%lx)",
647e93f7393Sniklas SYMBOL_VALUE (symbol),
648e93f7393Sniklas SYMBOL_VALUE (symbol));
649e93f7393Sniklas break;
650e93f7393Sniklas
651e93f7393Sniklas case LOC_CONST_BYTES:
652e93f7393Sniklas {
653e93f7393Sniklas unsigned i;
654e93f7393Sniklas struct type *type = check_typedef (SYMBOL_TYPE (symbol));
655e93f7393Sniklas fprintf_filtered (outfile, "const %u hex bytes:",
656e93f7393Sniklas TYPE_LENGTH (type));
657e93f7393Sniklas for (i = 0; i < TYPE_LENGTH (type); i++)
658e93f7393Sniklas fprintf_filtered (outfile, " %02x",
659e93f7393Sniklas (unsigned) SYMBOL_VALUE_BYTES (symbol)[i]);
660e93f7393Sniklas }
661e93f7393Sniklas break;
662e93f7393Sniklas
663e93f7393Sniklas case LOC_STATIC:
664e93f7393Sniklas fprintf_filtered (outfile, "static at ");
665e93f7393Sniklas print_address_numeric (SYMBOL_VALUE_ADDRESS (symbol), 1, outfile);
666b725ae77Skettenis if (SYMBOL_BFD_SECTION (symbol))
667b725ae77Skettenis fprintf_filtered (outfile, " section %s",
668b725ae77Skettenis bfd_section_name
669b725ae77Skettenis (SYMBOL_BFD_SECTION (symbol)->owner,
670b725ae77Skettenis SYMBOL_BFD_SECTION (symbol)));
671b725ae77Skettenis break;
672b725ae77Skettenis
673b725ae77Skettenis case LOC_INDIRECT:
674b725ae77Skettenis fprintf_filtered (outfile, "extern global at *(");
675b725ae77Skettenis print_address_numeric (SYMBOL_VALUE_ADDRESS (symbol), 1, outfile);
676b725ae77Skettenis fprintf_filtered (outfile, "),");
677e93f7393Sniklas break;
678e93f7393Sniklas
679e93f7393Sniklas case LOC_REGISTER:
680e93f7393Sniklas fprintf_filtered (outfile, "register %ld", SYMBOL_VALUE (symbol));
681e93f7393Sniklas break;
682e93f7393Sniklas
683e93f7393Sniklas case LOC_ARG:
684e93f7393Sniklas fprintf_filtered (outfile, "arg at offset 0x%lx",
685e93f7393Sniklas SYMBOL_VALUE (symbol));
686e93f7393Sniklas break;
687e93f7393Sniklas
688e93f7393Sniklas case LOC_LOCAL_ARG:
689e93f7393Sniklas fprintf_filtered (outfile, "arg at offset 0x%lx from fp",
690e93f7393Sniklas SYMBOL_VALUE (symbol));
691e93f7393Sniklas break;
692e93f7393Sniklas
693e93f7393Sniklas case LOC_REF_ARG:
694e93f7393Sniklas fprintf_filtered (outfile, "reference arg at 0x%lx", SYMBOL_VALUE (symbol));
695e93f7393Sniklas break;
696e93f7393Sniklas
697e93f7393Sniklas case LOC_REGPARM:
698e93f7393Sniklas fprintf_filtered (outfile, "parameter register %ld", SYMBOL_VALUE (symbol));
699e93f7393Sniklas break;
700e93f7393Sniklas
701e93f7393Sniklas case LOC_REGPARM_ADDR:
702e93f7393Sniklas fprintf_filtered (outfile, "address parameter register %ld", SYMBOL_VALUE (symbol));
703e93f7393Sniklas break;
704e93f7393Sniklas
705e93f7393Sniklas case LOC_LOCAL:
706e93f7393Sniklas fprintf_filtered (outfile, "local at offset 0x%lx",
707e93f7393Sniklas SYMBOL_VALUE (symbol));
708e93f7393Sniklas break;
709e93f7393Sniklas
710e93f7393Sniklas case LOC_BASEREG:
711e93f7393Sniklas fprintf_filtered (outfile, "local at 0x%lx from register %d",
712e93f7393Sniklas SYMBOL_VALUE (symbol), SYMBOL_BASEREG (symbol));
713e93f7393Sniklas break;
714e93f7393Sniklas
715e93f7393Sniklas case LOC_BASEREG_ARG:
716e93f7393Sniklas fprintf_filtered (outfile, "arg at 0x%lx from register %d",
717e93f7393Sniklas SYMBOL_VALUE (symbol), SYMBOL_BASEREG (symbol));
718e93f7393Sniklas break;
719e93f7393Sniklas
720e93f7393Sniklas case LOC_TYPEDEF:
721e93f7393Sniklas break;
722e93f7393Sniklas
723e93f7393Sniklas case LOC_LABEL:
724e93f7393Sniklas fprintf_filtered (outfile, "label at ");
725e93f7393Sniklas print_address_numeric (SYMBOL_VALUE_ADDRESS (symbol), 1, outfile);
726b725ae77Skettenis if (SYMBOL_BFD_SECTION (symbol))
727b725ae77Skettenis fprintf_filtered (outfile, " section %s",
728b725ae77Skettenis bfd_section_name
729b725ae77Skettenis (SYMBOL_BFD_SECTION (symbol)->owner,
730b725ae77Skettenis SYMBOL_BFD_SECTION (symbol)));
731e93f7393Sniklas break;
732e93f7393Sniklas
733e93f7393Sniklas case LOC_BLOCK:
734e93f7393Sniklas fprintf_filtered (outfile, "block object ");
735b725ae77Skettenis gdb_print_host_address (SYMBOL_BLOCK_VALUE (symbol), outfile);
736e93f7393Sniklas fprintf_filtered (outfile, ", ");
737e93f7393Sniklas print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (symbol)),
738e93f7393Sniklas 1,
739e93f7393Sniklas outfile);
740e93f7393Sniklas fprintf_filtered (outfile, "..");
741e93f7393Sniklas print_address_numeric (BLOCK_END (SYMBOL_BLOCK_VALUE (symbol)),
742e93f7393Sniklas 1,
743e93f7393Sniklas outfile);
744b725ae77Skettenis if (SYMBOL_BFD_SECTION (symbol))
745b725ae77Skettenis fprintf_filtered (outfile, " section %s",
746b725ae77Skettenis bfd_section_name
747b725ae77Skettenis (SYMBOL_BFD_SECTION (symbol)->owner,
748b725ae77Skettenis SYMBOL_BFD_SECTION (symbol)));
749b725ae77Skettenis break;
750b725ae77Skettenis
751b725ae77Skettenis case LOC_COMPUTED:
752b725ae77Skettenis case LOC_COMPUTED_ARG:
753b725ae77Skettenis fprintf_filtered (outfile, "computed at runtime");
754e93f7393Sniklas break;
755e93f7393Sniklas
756e93f7393Sniklas case LOC_UNRESOLVED:
757e93f7393Sniklas fprintf_filtered (outfile, "unresolved");
758e93f7393Sniklas break;
759e93f7393Sniklas
760e93f7393Sniklas case LOC_OPTIMIZED_OUT:
761e93f7393Sniklas fprintf_filtered (outfile, "optimized out");
762e93f7393Sniklas break;
763e93f7393Sniklas
764e93f7393Sniklas default:
765e93f7393Sniklas fprintf_filtered (outfile, "botched symbol class %x",
766e93f7393Sniklas SYMBOL_CLASS (symbol));
767e93f7393Sniklas break;
768e93f7393Sniklas }
769e93f7393Sniklas }
770e93f7393Sniklas fprintf_filtered (outfile, "\n");
771e93f7393Sniklas return 1;
772e93f7393Sniklas }
773e93f7393Sniklas
774e93f7393Sniklas void
maintenance_print_psymbols(char * args,int from_tty)775b725ae77Skettenis maintenance_print_psymbols (char *args, int from_tty)
776e93f7393Sniklas {
777e93f7393Sniklas char **argv;
778b725ae77Skettenis struct ui_file *outfile;
779e93f7393Sniklas struct cleanup *cleanups;
780e93f7393Sniklas char *symname = NULL;
781e93f7393Sniklas char *filename = DEV_TTY;
782e93f7393Sniklas struct objfile *objfile;
783e93f7393Sniklas struct partial_symtab *ps;
784e93f7393Sniklas
785e93f7393Sniklas dont_repeat ();
786e93f7393Sniklas
787e93f7393Sniklas if (args == NULL)
788e93f7393Sniklas {
789e93f7393Sniklas error ("print-psymbols takes an output file name and optional symbol file name");
790e93f7393Sniklas }
791e93f7393Sniklas else if ((argv = buildargv (args)) == NULL)
792e93f7393Sniklas {
793e93f7393Sniklas nomem (0);
794e93f7393Sniklas }
795b725ae77Skettenis cleanups = make_cleanup_freeargv (argv);
796e93f7393Sniklas
797e93f7393Sniklas if (argv[0] != NULL)
798e93f7393Sniklas {
799e93f7393Sniklas filename = argv[0];
800e93f7393Sniklas /* If a second arg is supplied, it is a source file name to match on */
801e93f7393Sniklas if (argv[1] != NULL)
802e93f7393Sniklas {
803e93f7393Sniklas symname = argv[1];
804e93f7393Sniklas }
805e93f7393Sniklas }
806e93f7393Sniklas
807e93f7393Sniklas filename = tilde_expand (filename);
808b725ae77Skettenis make_cleanup (xfree, filename);
809e93f7393Sniklas
810e93f7393Sniklas outfile = gdb_fopen (filename, FOPEN_WT);
811e93f7393Sniklas if (outfile == 0)
812e93f7393Sniklas perror_with_name (filename);
813b725ae77Skettenis make_cleanup_ui_file_delete (outfile);
814e93f7393Sniklas
815e93f7393Sniklas immediate_quit++;
816e93f7393Sniklas ALL_PSYMTABS (objfile, ps)
817b725ae77Skettenis if (symname == NULL || strcmp (symname, ps->filename) == 0)
818e93f7393Sniklas dump_psymtab (objfile, ps, outfile);
819e93f7393Sniklas immediate_quit--;
820e93f7393Sniklas do_cleanups (cleanups);
821e93f7393Sniklas }
822e93f7393Sniklas
823e93f7393Sniklas static void
print_partial_symbols(struct partial_symbol ** p,int count,char * what,struct ui_file * outfile)824b725ae77Skettenis print_partial_symbols (struct partial_symbol **p, int count, char *what,
825b725ae77Skettenis struct ui_file *outfile)
826e93f7393Sniklas {
827e93f7393Sniklas fprintf_filtered (outfile, " %s partial symbols:\n", what);
828e93f7393Sniklas while (count-- > 0)
829e93f7393Sniklas {
830b725ae77Skettenis fprintf_filtered (outfile, " `%s'", DEPRECATED_SYMBOL_NAME (*p));
831e93f7393Sniklas if (SYMBOL_DEMANGLED_NAME (*p) != NULL)
832e93f7393Sniklas {
833e93f7393Sniklas fprintf_filtered (outfile, " `%s'", SYMBOL_DEMANGLED_NAME (*p));
834e93f7393Sniklas }
835e93f7393Sniklas fputs_filtered (", ", outfile);
836b725ae77Skettenis switch (SYMBOL_DOMAIN (*p))
837e93f7393Sniklas {
838b725ae77Skettenis case UNDEF_DOMAIN:
839b725ae77Skettenis fputs_filtered ("undefined domain, ", outfile);
840e93f7393Sniklas break;
841b725ae77Skettenis case VAR_DOMAIN:
842e93f7393Sniklas /* This is the usual thing -- don't print it */
843e93f7393Sniklas break;
844b725ae77Skettenis case STRUCT_DOMAIN:
845b725ae77Skettenis fputs_filtered ("struct domain, ", outfile);
846e93f7393Sniklas break;
847b725ae77Skettenis case LABEL_DOMAIN:
848b725ae77Skettenis fputs_filtered ("label domain, ", outfile);
849e93f7393Sniklas break;
850e93f7393Sniklas default:
851b725ae77Skettenis fputs_filtered ("<invalid domain>, ", outfile);
852e93f7393Sniklas break;
853e93f7393Sniklas }
854e93f7393Sniklas switch (SYMBOL_CLASS (*p))
855e93f7393Sniklas {
856e93f7393Sniklas case LOC_UNDEF:
857e93f7393Sniklas fputs_filtered ("undefined", outfile);
858e93f7393Sniklas break;
859e93f7393Sniklas case LOC_CONST:
860e93f7393Sniklas fputs_filtered ("constant int", outfile);
861e93f7393Sniklas break;
862e93f7393Sniklas case LOC_STATIC:
863e93f7393Sniklas fputs_filtered ("static", outfile);
864e93f7393Sniklas break;
865b725ae77Skettenis case LOC_INDIRECT:
866b725ae77Skettenis fputs_filtered ("extern global", outfile);
867b725ae77Skettenis break;
868e93f7393Sniklas case LOC_REGISTER:
869e93f7393Sniklas fputs_filtered ("register", outfile);
870e93f7393Sniklas break;
871e93f7393Sniklas case LOC_ARG:
872e93f7393Sniklas fputs_filtered ("pass by value", outfile);
873e93f7393Sniklas break;
874e93f7393Sniklas case LOC_REF_ARG:
875e93f7393Sniklas fputs_filtered ("pass by reference", outfile);
876e93f7393Sniklas break;
877e93f7393Sniklas case LOC_REGPARM:
878e93f7393Sniklas fputs_filtered ("register parameter", outfile);
879e93f7393Sniklas break;
880e93f7393Sniklas case LOC_REGPARM_ADDR:
881e93f7393Sniklas fputs_filtered ("register address parameter", outfile);
882e93f7393Sniklas break;
883e93f7393Sniklas case LOC_LOCAL:
884e93f7393Sniklas fputs_filtered ("stack parameter", outfile);
885e93f7393Sniklas break;
886e93f7393Sniklas case LOC_TYPEDEF:
887e93f7393Sniklas fputs_filtered ("type", outfile);
888e93f7393Sniklas break;
889e93f7393Sniklas case LOC_LABEL:
890e93f7393Sniklas fputs_filtered ("label", outfile);
891e93f7393Sniklas break;
892e93f7393Sniklas case LOC_BLOCK:
893e93f7393Sniklas fputs_filtered ("function", outfile);
894e93f7393Sniklas break;
895e93f7393Sniklas case LOC_CONST_BYTES:
896e93f7393Sniklas fputs_filtered ("constant bytes", outfile);
897e93f7393Sniklas break;
898e93f7393Sniklas case LOC_LOCAL_ARG:
899e93f7393Sniklas fputs_filtered ("shuffled arg", outfile);
900e93f7393Sniklas break;
901e93f7393Sniklas case LOC_UNRESOLVED:
902e93f7393Sniklas fputs_filtered ("unresolved", outfile);
903e93f7393Sniklas break;
904e93f7393Sniklas case LOC_OPTIMIZED_OUT:
905e93f7393Sniklas fputs_filtered ("optimized out", outfile);
906e93f7393Sniklas break;
907b725ae77Skettenis case LOC_COMPUTED:
908b725ae77Skettenis case LOC_COMPUTED_ARG:
909b725ae77Skettenis fputs_filtered ("computed at runtime", outfile);
910b725ae77Skettenis break;
911e93f7393Sniklas default:
912e93f7393Sniklas fputs_filtered ("<invalid location>", outfile);
913e93f7393Sniklas break;
914e93f7393Sniklas }
915e93f7393Sniklas fputs_filtered (", ", outfile);
916b725ae77Skettenis print_address_numeric (SYMBOL_VALUE_ADDRESS (*p), 1, outfile);
917b725ae77Skettenis fprintf_filtered (outfile, "\n");
918e93f7393Sniklas p++;
919e93f7393Sniklas }
920e93f7393Sniklas }
921e93f7393Sniklas
922e93f7393Sniklas void
maintenance_print_msymbols(char * args,int from_tty)923b725ae77Skettenis maintenance_print_msymbols (char *args, int from_tty)
924e93f7393Sniklas {
925e93f7393Sniklas char **argv;
926b725ae77Skettenis struct ui_file *outfile;
927e93f7393Sniklas struct cleanup *cleanups;
928e93f7393Sniklas char *filename = DEV_TTY;
929e93f7393Sniklas char *symname = NULL;
930e93f7393Sniklas struct objfile *objfile;
931e93f7393Sniklas
932e93f7393Sniklas dont_repeat ();
933e93f7393Sniklas
934e93f7393Sniklas if (args == NULL)
935e93f7393Sniklas {
936e93f7393Sniklas error ("print-msymbols takes an output file name and optional symbol file name");
937e93f7393Sniklas }
938e93f7393Sniklas else if ((argv = buildargv (args)) == NULL)
939e93f7393Sniklas {
940e93f7393Sniklas nomem (0);
941e93f7393Sniklas }
942b725ae77Skettenis cleanups = make_cleanup_freeargv (argv);
943e93f7393Sniklas
944e93f7393Sniklas if (argv[0] != NULL)
945e93f7393Sniklas {
946e93f7393Sniklas filename = argv[0];
947e93f7393Sniklas /* If a second arg is supplied, it is a source file name to match on */
948e93f7393Sniklas if (argv[1] != NULL)
949e93f7393Sniklas {
950e93f7393Sniklas symname = argv[1];
951e93f7393Sniklas }
952e93f7393Sniklas }
953e93f7393Sniklas
954e93f7393Sniklas filename = tilde_expand (filename);
955b725ae77Skettenis make_cleanup (xfree, filename);
956e93f7393Sniklas
957e93f7393Sniklas outfile = gdb_fopen (filename, FOPEN_WT);
958e93f7393Sniklas if (outfile == 0)
959e93f7393Sniklas perror_with_name (filename);
960b725ae77Skettenis make_cleanup_ui_file_delete (outfile);
961e93f7393Sniklas
962e93f7393Sniklas immediate_quit++;
963e93f7393Sniklas ALL_OBJFILES (objfile)
964b725ae77Skettenis if (symname == NULL || strcmp (symname, objfile->name) == 0)
965e93f7393Sniklas dump_msymbols (objfile, outfile);
966e93f7393Sniklas immediate_quit--;
967e93f7393Sniklas fprintf_filtered (outfile, "\n\n");
968e93f7393Sniklas do_cleanups (cleanups);
969e93f7393Sniklas }
970e93f7393Sniklas
971e93f7393Sniklas void
maintenance_print_objfiles(char * ignore,int from_tty)972b725ae77Skettenis maintenance_print_objfiles (char *ignore, int from_tty)
973e93f7393Sniklas {
974e93f7393Sniklas struct objfile *objfile;
975e93f7393Sniklas
976e93f7393Sniklas dont_repeat ();
977e93f7393Sniklas
978e93f7393Sniklas immediate_quit++;
979e93f7393Sniklas ALL_OBJFILES (objfile)
980e93f7393Sniklas dump_objfile (objfile);
981e93f7393Sniklas immediate_quit--;
982e93f7393Sniklas }
983e93f7393Sniklas
984b725ae77Skettenis
985b725ae77Skettenis /* List all the symbol tables whose names match REGEXP (optional). */
986b725ae77Skettenis void
maintenance_info_symtabs(char * regexp,int from_tty)987b725ae77Skettenis maintenance_info_symtabs (char *regexp, int from_tty)
988b725ae77Skettenis {
989b725ae77Skettenis struct objfile *objfile;
990b725ae77Skettenis
991b725ae77Skettenis if (regexp)
992b725ae77Skettenis re_comp (regexp);
993b725ae77Skettenis
994b725ae77Skettenis ALL_OBJFILES (objfile)
995b725ae77Skettenis {
996b725ae77Skettenis struct symtab *symtab;
997b725ae77Skettenis
998b725ae77Skettenis /* We don't want to print anything for this objfile until we
999b725ae77Skettenis actually find a symtab whose name matches. */
1000b725ae77Skettenis int printed_objfile_start = 0;
1001b725ae77Skettenis
1002b725ae77Skettenis ALL_OBJFILE_SYMTABS (objfile, symtab)
1003b725ae77Skettenis if (! regexp
1004b725ae77Skettenis || re_exec (symtab->filename))
1005b725ae77Skettenis {
1006b725ae77Skettenis if (! printed_objfile_start)
1007b725ae77Skettenis {
1008b725ae77Skettenis printf_filtered ("{ objfile %s ", objfile->name);
1009b725ae77Skettenis wrap_here (" ");
1010b725ae77Skettenis printf_filtered ("((struct objfile *) %p)\n", objfile);
1011b725ae77Skettenis printed_objfile_start = 1;
1012b725ae77Skettenis }
1013b725ae77Skettenis
1014b725ae77Skettenis printf_filtered (" { symtab %s ", symtab->filename);
1015b725ae77Skettenis wrap_here (" ");
1016b725ae77Skettenis printf_filtered ("((struct symtab *) %p)\n", symtab);
1017b725ae77Skettenis printf_filtered (" dirname %s\n",
1018b725ae77Skettenis symtab->dirname ? symtab->dirname : "(null)");
1019b725ae77Skettenis printf_filtered (" fullname %s\n",
1020b725ae77Skettenis symtab->fullname ? symtab->fullname : "(null)");
1021b725ae77Skettenis printf_filtered (" blockvector ((struct blockvector *) %p)%s\n",
1022b725ae77Skettenis symtab->blockvector,
1023b725ae77Skettenis symtab->primary ? " (primary)" : "");
1024b725ae77Skettenis printf_filtered (" debugformat %s\n", symtab->debugformat);
1025b725ae77Skettenis printf_filtered (" }\n");
1026b725ae77Skettenis }
1027b725ae77Skettenis
1028b725ae77Skettenis if (printed_objfile_start)
1029b725ae77Skettenis printf_filtered ("}\n");
1030b725ae77Skettenis }
1031b725ae77Skettenis }
1032b725ae77Skettenis
1033b725ae77Skettenis
1034b725ae77Skettenis /* List all the partial symbol tables whose names match REGEXP (optional). */
1035b725ae77Skettenis void
maintenance_info_psymtabs(char * regexp,int from_tty)1036b725ae77Skettenis maintenance_info_psymtabs (char *regexp, int from_tty)
1037b725ae77Skettenis {
1038b725ae77Skettenis struct objfile *objfile;
1039b725ae77Skettenis
1040b725ae77Skettenis if (regexp)
1041b725ae77Skettenis re_comp (regexp);
1042b725ae77Skettenis
1043b725ae77Skettenis ALL_OBJFILES (objfile)
1044b725ae77Skettenis {
1045b725ae77Skettenis struct partial_symtab *psymtab;
1046b725ae77Skettenis
1047b725ae77Skettenis /* We don't want to print anything for this objfile until we
1048b725ae77Skettenis actually find a symtab whose name matches. */
1049b725ae77Skettenis int printed_objfile_start = 0;
1050b725ae77Skettenis
1051b725ae77Skettenis ALL_OBJFILE_PSYMTABS (objfile, psymtab)
1052b725ae77Skettenis if (! regexp
1053b725ae77Skettenis || re_exec (psymtab->filename))
1054b725ae77Skettenis {
1055b725ae77Skettenis if (! printed_objfile_start)
1056b725ae77Skettenis {
1057b725ae77Skettenis printf_filtered ("{ objfile %s ", objfile->name);
1058b725ae77Skettenis wrap_here (" ");
1059b725ae77Skettenis printf_filtered ("((struct objfile *) %p)\n", objfile);
1060b725ae77Skettenis printed_objfile_start = 1;
1061b725ae77Skettenis }
1062b725ae77Skettenis
1063b725ae77Skettenis printf_filtered (" { psymtab %s ", psymtab->filename);
1064b725ae77Skettenis wrap_here (" ");
1065b725ae77Skettenis printf_filtered ("((struct partial_symtab *) %p)\n", psymtab);
1066b725ae77Skettenis printf_filtered (" readin %s\n",
1067b725ae77Skettenis psymtab->readin ? "yes" : "no");
1068b725ae77Skettenis printf_filtered (" fullname %s\n",
1069b725ae77Skettenis psymtab->fullname ? psymtab->fullname : "(null)");
1070b725ae77Skettenis printf_filtered (" text addresses ");
1071b725ae77Skettenis print_address_numeric (psymtab->textlow, 1, gdb_stdout);
1072b725ae77Skettenis printf_filtered (" -- ");
1073b725ae77Skettenis print_address_numeric (psymtab->texthigh, 1, gdb_stdout);
1074b725ae77Skettenis printf_filtered ("\n");
1075b725ae77Skettenis printf_filtered (" globals ");
1076b725ae77Skettenis if (psymtab->n_global_syms)
1077b725ae77Skettenis {
1078b725ae77Skettenis printf_filtered ("(* (struct partial_symbol **) %p @ %d)\n",
1079b725ae77Skettenis (psymtab->objfile->global_psymbols.list
1080b725ae77Skettenis + psymtab->globals_offset),
1081b725ae77Skettenis psymtab->n_global_syms);
1082b725ae77Skettenis }
1083b725ae77Skettenis else
1084b725ae77Skettenis printf_filtered ("(none)\n");
1085b725ae77Skettenis printf_filtered (" statics ");
1086b725ae77Skettenis if (psymtab->n_static_syms)
1087b725ae77Skettenis {
1088b725ae77Skettenis printf_filtered ("(* (struct partial_symbol **) %p @ %d)\n",
1089b725ae77Skettenis (psymtab->objfile->static_psymbols.list
1090b725ae77Skettenis + psymtab->statics_offset),
1091b725ae77Skettenis psymtab->n_static_syms);
1092b725ae77Skettenis }
1093b725ae77Skettenis else
1094b725ae77Skettenis printf_filtered ("(none)\n");
1095b725ae77Skettenis printf_filtered (" dependencies ");
1096b725ae77Skettenis if (psymtab->number_of_dependencies)
1097b725ae77Skettenis {
1098b725ae77Skettenis int i;
1099b725ae77Skettenis
1100b725ae77Skettenis printf_filtered ("{\n");
1101b725ae77Skettenis for (i = 0; i < psymtab->number_of_dependencies; i++)
1102b725ae77Skettenis {
1103b725ae77Skettenis struct partial_symtab *dep = psymtab->dependencies[i];
1104b725ae77Skettenis
1105b725ae77Skettenis /* Note the string concatenation there --- no comma. */
1106b725ae77Skettenis printf_filtered (" psymtab %s "
1107b725ae77Skettenis "((struct partial_symtab *) %p)\n",
1108b725ae77Skettenis dep->filename, dep);
1109b725ae77Skettenis }
1110b725ae77Skettenis printf_filtered (" }\n");
1111b725ae77Skettenis }
1112b725ae77Skettenis else
1113b725ae77Skettenis printf_filtered ("(none)\n");
1114b725ae77Skettenis printf_filtered (" }\n");
1115b725ae77Skettenis }
1116b725ae77Skettenis
1117b725ae77Skettenis if (printed_objfile_start)
1118b725ae77Skettenis printf_filtered ("}\n");
1119b725ae77Skettenis }
1120b725ae77Skettenis }
1121b725ae77Skettenis
1122b725ae77Skettenis
1123e93f7393Sniklas /* Check consistency of psymtabs and symtabs. */
1124e93f7393Sniklas
1125e93f7393Sniklas void
maintenance_check_symtabs(char * ignore,int from_tty)1126b725ae77Skettenis maintenance_check_symtabs (char *ignore, int from_tty)
1127e93f7393Sniklas {
1128b725ae77Skettenis struct symbol *sym;
1129b725ae77Skettenis struct partial_symbol **psym;
1130b725ae77Skettenis struct symtab *s = NULL;
1131b725ae77Skettenis struct partial_symtab *ps;
1132e93f7393Sniklas struct blockvector *bv;
1133b725ae77Skettenis struct objfile *objfile;
1134b725ae77Skettenis struct block *b;
1135e93f7393Sniklas int length;
1136e93f7393Sniklas
1137e93f7393Sniklas ALL_PSYMTABS (objfile, ps)
1138e93f7393Sniklas {
1139e93f7393Sniklas s = PSYMTAB_TO_SYMTAB (ps);
1140e93f7393Sniklas if (s == NULL)
1141e93f7393Sniklas continue;
1142e93f7393Sniklas bv = BLOCKVECTOR (s);
1143e93f7393Sniklas b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
1144e93f7393Sniklas psym = ps->objfile->static_psymbols.list + ps->statics_offset;
1145e93f7393Sniklas length = ps->n_static_syms;
1146e93f7393Sniklas while (length--)
1147e93f7393Sniklas {
1148b725ae77Skettenis sym = lookup_block_symbol (b, DEPRECATED_SYMBOL_NAME (*psym),
1149b725ae77Skettenis NULL, SYMBOL_DOMAIN (*psym));
1150e93f7393Sniklas if (!sym)
1151e93f7393Sniklas {
1152e93f7393Sniklas printf_filtered ("Static symbol `");
1153b725ae77Skettenis puts_filtered (DEPRECATED_SYMBOL_NAME (*psym));
1154e93f7393Sniklas printf_filtered ("' only found in ");
1155e93f7393Sniklas puts_filtered (ps->filename);
1156e93f7393Sniklas printf_filtered (" psymtab\n");
1157e93f7393Sniklas }
1158e93f7393Sniklas psym++;
1159e93f7393Sniklas }
1160e93f7393Sniklas b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
1161e93f7393Sniklas psym = ps->objfile->global_psymbols.list + ps->globals_offset;
1162e93f7393Sniklas length = ps->n_global_syms;
1163e93f7393Sniklas while (length--)
1164e93f7393Sniklas {
1165b725ae77Skettenis sym = lookup_block_symbol (b, DEPRECATED_SYMBOL_NAME (*psym),
1166b725ae77Skettenis NULL, SYMBOL_DOMAIN (*psym));
1167e93f7393Sniklas if (!sym)
1168e93f7393Sniklas {
1169e93f7393Sniklas printf_filtered ("Global symbol `");
1170b725ae77Skettenis puts_filtered (DEPRECATED_SYMBOL_NAME (*psym));
1171e93f7393Sniklas printf_filtered ("' only found in ");
1172e93f7393Sniklas puts_filtered (ps->filename);
1173e93f7393Sniklas printf_filtered (" psymtab\n");
1174e93f7393Sniklas }
1175e93f7393Sniklas psym++;
1176e93f7393Sniklas }
1177e93f7393Sniklas if (ps->texthigh < ps->textlow)
1178e93f7393Sniklas {
1179e93f7393Sniklas printf_filtered ("Psymtab ");
1180e93f7393Sniklas puts_filtered (ps->filename);
1181e93f7393Sniklas printf_filtered (" covers bad range ");
1182b725ae77Skettenis print_address_numeric (ps->textlow, 1, gdb_stdout);
1183e93f7393Sniklas printf_filtered (" - ");
1184b725ae77Skettenis print_address_numeric (ps->texthigh, 1, gdb_stdout);
1185e93f7393Sniklas printf_filtered ("\n");
1186e93f7393Sniklas continue;
1187e93f7393Sniklas }
1188e93f7393Sniklas if (ps->texthigh == 0)
1189e93f7393Sniklas continue;
1190e93f7393Sniklas if (ps->textlow < BLOCK_START (b) || ps->texthigh > BLOCK_END (b))
1191e93f7393Sniklas {
1192e93f7393Sniklas printf_filtered ("Psymtab ");
1193e93f7393Sniklas puts_filtered (ps->filename);
1194e93f7393Sniklas printf_filtered (" covers ");
1195b725ae77Skettenis print_address_numeric (ps->textlow, 1, gdb_stdout);
1196e93f7393Sniklas printf_filtered (" - ");
1197b725ae77Skettenis print_address_numeric (ps->texthigh, 1, gdb_stdout);
1198e93f7393Sniklas printf_filtered (" but symtab covers only ");
1199b725ae77Skettenis print_address_numeric (BLOCK_START (b), 1, gdb_stdout);
1200e93f7393Sniklas printf_filtered (" - ");
1201b725ae77Skettenis print_address_numeric (BLOCK_END (b), 1, gdb_stdout);
1202e93f7393Sniklas printf_filtered ("\n");
1203e93f7393Sniklas }
1204e93f7393Sniklas }
1205e93f7393Sniklas }
1206e93f7393Sniklas
1207b725ae77Skettenis
1208e93f7393Sniklas /* Return the nexting depth of a block within other blocks in its symtab. */
1209e93f7393Sniklas
1210e93f7393Sniklas static int
block_depth(struct block * block)1211b725ae77Skettenis block_depth (struct block *block)
1212e93f7393Sniklas {
1213b725ae77Skettenis int i = 0;
1214e93f7393Sniklas while ((block = BLOCK_SUPERBLOCK (block)) != NULL)
1215e93f7393Sniklas {
1216e93f7393Sniklas i++;
1217e93f7393Sniklas }
1218e93f7393Sniklas return i;
1219e93f7393Sniklas }
1220e93f7393Sniklas
1221b725ae77Skettenis
1222e93f7393Sniklas /* Increase the space allocated for LISTP, which is probably
1223e93f7393Sniklas global_psymbols or static_psymbols. This space will eventually
1224e93f7393Sniklas be freed in free_objfile(). */
1225e93f7393Sniklas
1226e93f7393Sniklas void
extend_psymbol_list(struct psymbol_allocation_list * listp,struct objfile * objfile)1227b725ae77Skettenis extend_psymbol_list (struct psymbol_allocation_list *listp,
1228b725ae77Skettenis struct objfile *objfile)
1229e93f7393Sniklas {
1230e93f7393Sniklas int new_size;
1231e93f7393Sniklas if (listp->size == 0)
1232e93f7393Sniklas {
1233e93f7393Sniklas new_size = 255;
1234e93f7393Sniklas listp->list = (struct partial_symbol **)
1235*63addd46Skettenis xmalloc (new_size * sizeof (struct partial_symbol *));
1236e93f7393Sniklas }
1237e93f7393Sniklas else
1238e93f7393Sniklas {
1239e93f7393Sniklas new_size = listp->size * 2;
1240e93f7393Sniklas listp->list = (struct partial_symbol **)
1241*63addd46Skettenis xrealloc ((char *) listp->list,
1242e93f7393Sniklas new_size * sizeof (struct partial_symbol *));
1243e93f7393Sniklas }
1244e93f7393Sniklas /* Next assumes we only went one over. Should be good if
1245e93f7393Sniklas program works correctly */
1246e93f7393Sniklas listp->next = listp->list + listp->size;
1247e93f7393Sniklas listp->size = new_size;
1248e93f7393Sniklas }
1249e93f7393Sniklas
1250e93f7393Sniklas
1251e93f7393Sniklas /* Do early runtime initializations. */
1252e93f7393Sniklas void
_initialize_symmisc(void)1253b725ae77Skettenis _initialize_symmisc (void)
1254e93f7393Sniklas {
1255e93f7393Sniklas std_in = stdin;
1256e93f7393Sniklas std_out = stdout;
1257e93f7393Sniklas std_err = stderr;
1258e93f7393Sniklas }
1259