Index: gdb/symmisc.c |
diff --git a/gdb/symmisc.c b/gdb/symmisc.c |
index d5a737b0498593ec1452fab3f9eb2cda73e7e4de..ec21c6c456cc86fc18979298ab08098511a4920d 100644 |
--- a/gdb/symmisc.c |
+++ b/gdb/symmisc.c |
@@ -1,7 +1,6 @@ |
/* Do various things to symbol tables (other than lookup), for GDB. |
- Copyright (C) 1986-2000, 2002-2004, 2007-2012 Free Software |
- Foundation, Inc. |
+ Copyright (C) 1986-2013 Free Software Foundation, Inc. |
This file is part of GDB. |
@@ -33,10 +32,13 @@ |
#include "bcache.h" |
#include "block.h" |
#include "gdb_regex.h" |
-#include "gdb_stat.h" |
+#include <sys/stat.h> |
#include "dictionary.h" |
+#include "typeprint.h" |
+#include "gdbcmd.h" |
+#include "source.h" |
-#include "gdb_string.h" |
+#include <string.h> |
#include "readline/readline.h" |
#include "psymtab.h" |
@@ -57,13 +59,6 @@ FILE *std_err; |
/* Prototypes for local functions */ |
-static void dump_symtab (struct objfile *, struct symtab *, |
- struct ui_file *); |
- |
-static void dump_msymbols (struct objfile *, struct ui_file *); |
- |
-static void dump_objfile (struct objfile *); |
- |
static int block_depth (struct block *); |
void _initialize_symmisc (void); |
@@ -85,17 +80,19 @@ print_symbol_bcache_statistics (void) |
struct program_space *pspace; |
struct objfile *objfile; |
- immediate_quit++; |
ALL_PSPACES (pspace) |
ALL_PSPACE_OBJFILES (pspace, objfile) |
{ |
- printf_filtered (_("Byte cache statistics for '%s':\n"), objfile->name); |
+ QUIT; |
+ printf_filtered (_("Byte cache statistics for '%s':\n"), |
+ objfile_name (objfile)); |
print_bcache_statistics (psymbol_bcache_get_bcache (objfile->psymbol_cache), |
"partial symbol cache"); |
- print_bcache_statistics (objfile->macro_cache, "preprocessor macro cache"); |
- print_bcache_statistics (objfile->filename_cache, "file name cache"); |
+ print_bcache_statistics (objfile->per_bfd->macro_cache, |
+ "preprocessor macro cache"); |
+ print_bcache_statistics (objfile->per_bfd->filename_cache, |
+ "file name cache"); |
} |
- immediate_quit--; |
} |
void |
@@ -106,11 +103,11 @@ print_objfile_statistics (void) |
struct symtab *s; |
int i, linetables, blockvectors; |
- immediate_quit++; |
ALL_PSPACES (pspace) |
ALL_PSPACE_OBJFILES (pspace, objfile) |
{ |
- printf_filtered (_("Statistics for '%s':\n"), objfile->name); |
+ QUIT; |
+ printf_filtered (_("Statistics for '%s':\n"), objfile_name (objfile)); |
if (OBJSTAT (objfile, n_stabs) > 0) |
printf_filtered (_(" Number of \"stab\" symbols read: %d\n"), |
OBJSTAT (objfile, n_stabs)); |
@@ -148,15 +145,16 @@ print_objfile_statistics (void) |
OBJSTAT (objfile, sz_strtab)); |
printf_filtered (_(" Total memory used for objfile obstack: %d\n"), |
obstack_memory_used (&objfile->objfile_obstack)); |
+ printf_filtered (_(" Total memory used for BFD obstack: %d\n"), |
+ obstack_memory_used (&objfile->per_bfd->storage_obstack)); |
printf_filtered (_(" Total memory used for psymbol cache: %d\n"), |
bcache_memory_used (psymbol_bcache_get_bcache |
(objfile->psymbol_cache))); |
printf_filtered (_(" Total memory used for macro cache: %d\n"), |
- bcache_memory_used (objfile->macro_cache)); |
+ bcache_memory_used (objfile->per_bfd->macro_cache)); |
printf_filtered (_(" Total memory used for file name cache: %d\n"), |
- bcache_memory_used (objfile->filename_cache)); |
+ bcache_memory_used (objfile->per_bfd->filename_cache)); |
} |
- immediate_quit--; |
} |
static void |
@@ -164,7 +162,7 @@ dump_objfile (struct objfile *objfile) |
{ |
struct symtab *symtab; |
- printf_filtered ("\nObject file %s: ", objfile->name); |
+ printf_filtered ("\nObject file %s: ", objfile_name (objfile)); |
printf_filtered ("Objfile at "); |
gdb_print_host_address (objfile, gdb_stdout); |
printf_filtered (", bfd at "); |
@@ -182,7 +180,7 @@ dump_objfile (struct objfile *objfile) |
symtab != NULL; |
symtab = symtab->next) |
{ |
- printf_filtered ("%s at ", symtab->filename); |
+ printf_filtered ("%s at ", symtab_to_filename_for_display (symtab)); |
gdb_print_host_address (symtab, gdb_stdout); |
printf_filtered (", "); |
if (symtab->objfile != objfile) |
@@ -205,7 +203,7 @@ dump_msymbols (struct objfile *objfile, struct ui_file *outfile) |
int index; |
char ms_type; |
- fprintf_filtered (outfile, "\nObject file %s:\n\n", objfile->name); |
+ fprintf_filtered (outfile, "\nObject file %s:\n\n", objfile_name (objfile)); |
if (objfile->minimal_symbol_count == 0) |
{ |
fprintf_filtered (outfile, "No minimal symbols found.\n"); |
@@ -214,7 +212,7 @@ dump_msymbols (struct objfile *objfile, struct ui_file *outfile) |
index = 0; |
ALL_OBJFILE_MSYMBOLS (objfile, msymbol) |
{ |
- struct obj_section *section = SYMBOL_OBJ_SECTION (msymbol); |
+ struct obj_section *section = SYMBOL_OBJ_SECTION (objfile, msymbol); |
switch (MSYMBOL_TYPE (msymbol)) |
{ |
@@ -257,9 +255,15 @@ dump_msymbols (struct objfile *objfile, struct ui_file *outfile) |
outfile); |
fprintf_filtered (outfile, " %s", SYMBOL_LINKAGE_NAME (msymbol)); |
if (section) |
- fprintf_filtered (outfile, " section %s", |
- bfd_section_name (objfile->obfd, |
- section->the_bfd_section)); |
+ { |
+ if (section->the_bfd_section != NULL) |
+ fprintf_filtered (outfile, " section %s", |
+ bfd_section_name (objfile->obfd, |
+ section->the_bfd_section)); |
+ else |
+ fprintf_filtered (outfile, " spurious section %ld", |
+ (long) (section - objfile->sections)); |
+ } |
if (SYMBOL_DEMANGLED_NAME (msymbol) != NULL) |
{ |
fprintf_filtered (outfile, " %s", SYMBOL_DEMANGLED_NAME (msymbol)); |
@@ -291,11 +295,13 @@ dump_symtab_1 (struct objfile *objfile, struct symtab *symtab, |
struct block *b; |
int depth; |
- fprintf_filtered (outfile, "\nSymtab for file %s\n", symtab->filename); |
+ fprintf_filtered (outfile, "\nSymtab for file %s\n", |
+ symtab_to_filename_for_display (symtab)); |
if (symtab->dirname) |
fprintf_filtered (outfile, "Compilation directory is %s\n", |
symtab->dirname); |
- fprintf_filtered (outfile, "Read from object file %s (", objfile->name); |
+ fprintf_filtered (outfile, "Read from object file %s (", |
+ objfile_name (objfile)); |
gdb_print_host_address (objfile, outfile); |
fprintf_filtered (outfile, ")\n"); |
fprintf_filtered (outfile, "Language: %s\n", |
@@ -398,7 +404,7 @@ dump_symtab (struct objfile *objfile, struct symtab *symtab, |
dump_symtab_1 (objfile, symtab, outfile); |
} |
-void |
+static void |
maintenance_print_symbols (char *args, int from_tty) |
{ |
char **argv; |
@@ -437,11 +443,13 @@ maintenance_print_symbols (char *args, int from_tty) |
perror_with_name (filename); |
make_cleanup_ui_file_delete (outfile); |
- immediate_quit++; |
ALL_SYMTABS (objfile, s) |
- if (symname == NULL || filename_cmp (symname, s->filename) == 0) |
- dump_symtab (objfile, s, outfile); |
- immediate_quit--; |
+ { |
+ QUIT; |
+ if (symname == NULL |
+ || filename_cmp (symname, symtab_to_filename_for_display (s)) == 0) |
+ dump_symtab (objfile, s, outfile); |
+ } |
do_cleanups (cleanups); |
} |
@@ -457,7 +465,8 @@ print_symbol (void *args) |
struct symbol *symbol = ((struct print_symbol_args *) args)->symbol; |
int depth = ((struct print_symbol_args *) args)->depth; |
struct ui_file *outfile = ((struct print_symbol_args *) args)->outfile; |
- struct obj_section *section = SYMBOL_OBJ_SECTION (symbol); |
+ struct obj_section *section = SYMBOL_OBJ_SECTION (SYMBOL_OBJFILE (symbol), |
+ symbol); |
print_spaces (depth, outfile); |
if (SYMBOL_DOMAIN (symbol) == LABEL_DOMAIN) |
@@ -477,7 +486,8 @@ print_symbol (void *args) |
{ |
if (TYPE_TAG_NAME (SYMBOL_TYPE (symbol))) |
{ |
- LA_PRINT_TYPE (SYMBOL_TYPE (symbol), "", outfile, 1, depth); |
+ LA_PRINT_TYPE (SYMBOL_TYPE (symbol), "", outfile, 1, depth, |
+ &type_print_raw_options); |
} |
else |
{ |
@@ -487,7 +497,8 @@ print_symbol (void *args) |
: (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_STRUCT |
? "struct" : "union")), |
SYMBOL_LINKAGE_NAME (symbol)); |
- LA_PRINT_TYPE (SYMBOL_TYPE (symbol), "", outfile, 1, depth); |
+ LA_PRINT_TYPE (SYMBOL_TYPE (symbol), "", outfile, 1, depth, |
+ &type_print_raw_options); |
} |
fprintf_filtered (outfile, ";\n"); |
} |
@@ -501,7 +512,8 @@ print_symbol (void *args) |
LA_PRINT_TYPE (SYMBOL_TYPE (symbol), SYMBOL_PRINT_NAME (symbol), |
outfile, |
TYPE_CODE (SYMBOL_TYPE (symbol)) != TYPE_CODE_ENUM, |
- depth); |
+ depth, |
+ &type_print_raw_options); |
fprintf_filtered (outfile, "; "); |
} |
else |
@@ -619,7 +631,7 @@ print_symbol (void *args) |
return 1; |
} |
-void |
+static void |
maintenance_print_msymbols (char *args, int from_tty) |
{ |
char **argv; |
@@ -648,7 +660,7 @@ maintenance_print_msymbols (char *args, int from_tty) |
/* If a second arg is supplied, it is a source file name to match on. */ |
if (argv[1] != NULL) |
{ |
- symname = xfullpath (argv[1]); |
+ symname = gdb_realpath (argv[1]); |
make_cleanup (xfree, symname); |
if (symname && stat (symname, &sym_st)) |
perror_with_name (symname); |
@@ -663,40 +675,50 @@ maintenance_print_msymbols (char *args, int from_tty) |
perror_with_name (filename); |
make_cleanup_ui_file_delete (outfile); |
- immediate_quit++; |
ALL_PSPACES (pspace) |
ALL_PSPACE_OBJFILES (pspace, objfile) |
- if (symname == NULL || (!stat (objfile->name, &obj_st) |
- && sym_st.st_ino == obj_st.st_ino)) |
- dump_msymbols (objfile, outfile); |
- immediate_quit--; |
+ { |
+ QUIT; |
+ if (symname == NULL || (!stat (objfile_name (objfile), &obj_st) |
+ && sym_st.st_dev == obj_st.st_dev |
+ && sym_st.st_ino == obj_st.st_ino)) |
+ dump_msymbols (objfile, outfile); |
+ } |
fprintf_filtered (outfile, "\n\n"); |
do_cleanups (cleanups); |
} |
-void |
-maintenance_print_objfiles (char *ignore, int from_tty) |
+static void |
+maintenance_print_objfiles (char *regexp, int from_tty) |
{ |
struct program_space *pspace; |
struct objfile *objfile; |
dont_repeat (); |
- immediate_quit++; |
+ if (regexp) |
+ re_comp (regexp); |
+ |
ALL_PSPACES (pspace) |
ALL_PSPACE_OBJFILES (pspace, objfile) |
- dump_objfile (objfile); |
- immediate_quit--; |
+ { |
+ QUIT; |
+ if (! regexp |
+ || re_exec (objfile_name (objfile))) |
+ dump_objfile (objfile); |
+ } |
} |
- |
/* List all the symbol tables whose names match REGEXP (optional). */ |
-void |
+ |
+static void |
maintenance_info_symtabs (char *regexp, int from_tty) |
{ |
struct program_space *pspace; |
struct objfile *objfile; |
+ dont_repeat (); |
+ |
if (regexp) |
re_comp (regexp); |
@@ -714,18 +736,19 @@ maintenance_info_symtabs (char *regexp, int from_tty) |
QUIT; |
if (! regexp |
- || re_exec (symtab->filename)) |
+ || re_exec (symtab_to_filename_for_display (symtab))) |
{ |
if (! printed_objfile_start) |
{ |
- printf_filtered ("{ objfile %s ", objfile->name); |
+ printf_filtered ("{ objfile %s ", objfile_name (objfile)); |
wrap_here (" "); |
printf_filtered ("((struct objfile *) %s)\n", |
host_address_to_string (objfile)); |
printed_objfile_start = 1; |
} |
- printf_filtered (" { symtab %s ", symtab->filename); |
+ printf_filtered (" { symtab %s ", |
+ symtab_to_filename_for_display (symtab)); |
wrap_here (" "); |
printf_filtered ("((struct symtab *) %s)\n", |
host_address_to_string (symtab)); |
@@ -750,6 +773,136 @@ maintenance_info_symtabs (char *regexp, int from_tty) |
printf_filtered ("}\n"); |
} |
} |
+ |
+/* Check consistency of symtabs. |
+ An example of what this checks for is NULL blockvectors. |
+ They can happen if there's a bug during debug info reading. |
+ GDB assumes they are always non-NULL. |
+ |
+ Note: This does not check for psymtab vs symtab consistency. |
+ Use "maint check-psymtabs" for that. */ |
+ |
+static void |
+maintenance_check_symtabs (char *ignore, int from_tty) |
+{ |
+ struct program_space *pspace; |
+ struct objfile *objfile; |
+ |
+ ALL_PSPACES (pspace) |
+ ALL_PSPACE_OBJFILES (pspace, objfile) |
+ { |
+ struct symtab *symtab; |
+ |
+ /* We don't want to print anything for this objfile until we |
+ actually find something worth printing. */ |
+ int printed_objfile_start = 0; |
+ |
+ ALL_OBJFILE_SYMTABS (objfile, symtab) |
+ { |
+ int found_something = 0; |
+ |
+ QUIT; |
+ |
+ if (symtab->blockvector == NULL) |
+ found_something = 1; |
+ /* Add more checks here. */ |
+ |
+ if (found_something) |
+ { |
+ if (! printed_objfile_start) |
+ { |
+ printf_filtered ("{ objfile %s ", objfile_name (objfile)); |
+ wrap_here (" "); |
+ printf_filtered ("((struct objfile *) %s)\n", |
+ host_address_to_string (objfile)); |
+ printed_objfile_start = 1; |
+ } |
+ printf_filtered (" { symtab %s\n", |
+ symtab_to_filename_for_display (symtab)); |
+ if (symtab->blockvector == NULL) |
+ printf_filtered (" NULL blockvector\n"); |
+ printf_filtered (" }\n"); |
+ } |
+ } |
+ |
+ if (printed_objfile_start) |
+ printf_filtered ("}\n"); |
+ } |
+} |
+ |
+/* Helper function for maintenance_expand_symtabs. |
+ This is the name_matcher function for expand_symtabs_matching. */ |
+ |
+static int |
+maintenance_expand_name_matcher (const char *symname, void *data) |
+{ |
+ /* Since we're not searching on symbols, just return TRUE. */ |
+ return 1; |
+} |
+ |
+/* Helper function for maintenance_expand_symtabs. |
+ This is the file_matcher function for expand_symtabs_matching. */ |
+ |
+static int |
+maintenance_expand_file_matcher (const char *filename, void *data, |
+ int basenames) |
+{ |
+ const char *regexp = data; |
+ |
+ QUIT; |
+ |
+ /* KISS: Only apply the regexp to the complete file name. */ |
+ if (basenames) |
+ return 0; |
+ |
+ if (regexp == NULL || re_exec (filename)) |
+ return 1; |
+ |
+ return 0; |
+} |
+ |
+/* Expand all symbol tables whose name matches an optional regexp. */ |
+ |
+static void |
+maintenance_expand_symtabs (char *args, int from_tty) |
+{ |
+ struct program_space *pspace; |
+ struct objfile *objfile; |
+ struct cleanup *cleanups; |
+ char **argv; |
+ char *regexp = NULL; |
+ |
+ /* We use buildargv here so that we handle spaces in the regexp |
+ in a way that allows adding more arguments later. */ |
+ argv = gdb_buildargv (args); |
+ cleanups = make_cleanup_freeargv (argv); |
+ |
+ if (argv != NULL) |
+ { |
+ if (argv[0] != NULL) |
+ { |
+ regexp = argv[0]; |
+ if (argv[1] != NULL) |
+ error (_("Extra arguments after regexp.")); |
+ } |
+ } |
+ |
+ if (regexp) |
+ re_comp (regexp); |
+ |
+ ALL_PSPACES (pspace) |
+ ALL_PSPACE_OBJFILES (pspace, objfile) |
+ { |
+ if (objfile->sf) |
+ { |
+ objfile->sf->qf->expand_symtabs_matching |
+ (objfile, maintenance_expand_file_matcher, |
+ maintenance_expand_name_matcher, ALL_DOMAIN, regexp); |
+ } |
+ } |
+ |
+ do_cleanups (cleanups); |
+} |
/* Return the nexting depth of a block within other blocks in its symtab. */ |
@@ -768,10 +921,45 @@ block_depth (struct block *block) |
/* Do early runtime initializations. */ |
+ |
void |
_initialize_symmisc (void) |
{ |
std_in = stdin; |
std_out = stdout; |
std_err = stderr; |
+ |
+ add_cmd ("symbols", class_maintenance, maintenance_print_symbols, _("\ |
+Print dump of current symbol definitions.\n\ |
+Entries in the full symbol table are dumped to file OUTFILE.\n\ |
+If a SOURCE file is specified, dump only that file's symbols."), |
+ &maintenanceprintlist); |
+ |
+ add_cmd ("msymbols", class_maintenance, maintenance_print_msymbols, _("\ |
+Print dump of current minimal symbol definitions.\n\ |
+Entries in the minimal symbol table are dumped to file OUTFILE.\n\ |
+If a SOURCE file is specified, dump only that file's minimal symbols."), |
+ &maintenanceprintlist); |
+ |
+ add_cmd ("objfiles", class_maintenance, maintenance_print_objfiles, |
+ _("Print dump of current object file definitions.\n\ |
+With an argument REGEXP, list the object files with matching names."), |
+ &maintenanceprintlist); |
+ |
+ add_cmd ("symtabs", class_maintenance, maintenance_info_symtabs, _("\ |
+List the full symbol tables for all object files.\n\ |
+This does not include information about individual symbols, blocks, or\n\ |
+linetables --- just the symbol table structures themselves.\n\ |
+With an argument REGEXP, list the symbol tables with matching names."), |
+ &maintenanceinfolist); |
+ |
+ add_cmd ("check-symtabs", class_maintenance, maintenance_check_symtabs, |
+ _("\ |
+Check consistency of currently expanded symtabs."), |
+ &maintenancelist); |
+ |
+ add_cmd ("expand-symtabs", class_maintenance, maintenance_expand_symtabs, |
+ _("Expand symbol tables.\n\ |
+With an argument REGEXP, only expand the symbol tables with matching names."), |
+ &maintenancelist); |
} |