Index: gdb/psymtab.c |
diff --git a/gdb/psymtab.c b/gdb/psymtab.c |
index 5623e2dc5f8ba30d6b1aa52cb6c9fa3579855d70..1d336623941d08c361a70e737119c830e19bd7b4 100644 |
--- a/gdb/psymtab.c |
+++ b/gdb/psymtab.c |
@@ -1,6 +1,6 @@ |
/* Partial symbol tables. |
- Copyright (C) 2009-2012 Free Software Foundation, Inc. |
+ Copyright (C) 2009-2013 Free Software Foundation, Inc. |
This file is part of GDB. |
@@ -35,6 +35,7 @@ |
#include "dictionary.h" |
#include "language.h" |
#include "cp-support.h" |
+#include "gdbcmd.h" |
#ifndef DEV_TTY |
#define DEV_TTY "/dev/tty" |
@@ -45,27 +46,30 @@ struct psymbol_bcache |
struct bcache *bcache; |
}; |
-static struct partial_symbol *match_partial_symbol (struct partial_symtab *, |
+static struct partial_symbol *match_partial_symbol (struct objfile *, |
+ struct partial_symtab *, |
int, |
const char *, domain_enum, |
symbol_compare_ftype *, |
symbol_compare_ftype *); |
-static struct partial_symbol *lookup_partial_symbol (struct partial_symtab *, |
+static struct partial_symbol *lookup_partial_symbol (struct objfile *, |
+ struct partial_symtab *, |
const char *, int, |
domain_enum); |
-static char *psymtab_to_fullname (struct partial_symtab *ps); |
+static const char *psymtab_to_fullname (struct partial_symtab *ps); |
-static struct partial_symbol *find_pc_sect_psymbol (struct partial_symtab *, |
+static struct partial_symbol *find_pc_sect_psymbol (struct objfile *, |
+ struct partial_symtab *, |
CORE_ADDR, |
struct obj_section *); |
-static struct partial_symbol *fixup_psymbol_section (struct partial_symbol |
- *psym, |
- struct objfile *objfile); |
+static void fixup_psymbol_section (struct partial_symbol *psym, |
+ struct objfile *objfile); |
-static struct symtab *psymtab_to_symtab (struct partial_symtab *pst); |
+static struct symtab *psymtab_to_symtab (struct objfile *objfile, |
+ struct partial_symtab *pst); |
/* Ensure that the partial symbols for OBJFILE have been loaded. This |
function always returns its argument, as a convenience. */ |
@@ -82,7 +86,7 @@ require_partial_symbols (struct objfile *objfile, int verbose) |
if (verbose) |
{ |
printf_unfiltered (_("Reading symbols from %s..."), |
- objfile->name); |
+ objfile_name (objfile)); |
gdb_flush (gdb_stdout); |
} |
(*objfile->sf->sym_read_psymbols) (objfile); |
@@ -127,7 +131,6 @@ require_partial_symbols (struct objfile *objfile, int verbose) |
static int |
partial_map_expand_apply (struct objfile *objfile, |
const char *name, |
- const char *full_path, |
const char *real_path, |
struct partial_symtab *pst, |
int (*callback) (struct symtab *, void *), |
@@ -145,9 +148,9 @@ partial_map_expand_apply (struct objfile *objfile, |
/* This may expand more than one symtab, and we want to iterate over |
all of them. */ |
- psymtab_to_symtab (pst); |
+ psymtab_to_symtab (objfile, pst); |
- return iterate_over_some_symtabs (name, full_path, real_path, callback, data, |
+ return iterate_over_some_symtabs (name, real_path, callback, data, |
objfile->symtabs, last_made); |
} |
@@ -156,7 +159,6 @@ partial_map_expand_apply (struct objfile *objfile, |
static int |
partial_map_symtabs_matching_filename (struct objfile *objfile, |
const char *name, |
- const char *full_path, |
const char *real_path, |
int (*callback) (struct symtab *, |
void *), |
@@ -164,8 +166,6 @@ partial_map_symtabs_matching_filename (struct objfile *objfile, |
{ |
struct partial_symtab *pst; |
const char *name_basename = lbasename (name); |
- int name_len = strlen (name); |
- int is_abs = IS_ABSOLUTE_PATH (name); |
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst) |
{ |
@@ -178,13 +178,12 @@ partial_map_symtabs_matching_filename (struct objfile *objfile, |
if (pst->anonymous) |
continue; |
- if (FILENAME_CMP (name, pst->filename) == 0 |
- || (!is_abs && compare_filenames_for_search (pst->filename, |
- name, name_len))) |
+ if (compare_filenames_for_search (pst->filename, name)) |
{ |
- if (partial_map_expand_apply (objfile, name, full_path, real_path, |
+ if (partial_map_expand_apply (objfile, name, real_path, |
pst, callback, data)) |
return 1; |
+ continue; |
} |
/* Before we invoke realpath, which can get expensive when many |
@@ -193,39 +192,26 @@ partial_map_symtabs_matching_filename (struct objfile *objfile, |
&& FILENAME_CMP (name_basename, lbasename (pst->filename)) != 0) |
continue; |
- /* If the user gave us an absolute path, try to find the file in |
- this symtab and use its absolute path. */ |
- if (full_path != NULL) |
+ if (compare_filenames_for_search (psymtab_to_fullname (pst), name)) |
{ |
- psymtab_to_fullname (pst); |
- if (pst->fullname != NULL |
- && (FILENAME_CMP (full_path, pst->fullname) == 0 |
- || (!is_abs && compare_filenames_for_search (pst->fullname, |
- name, name_len)))) |
- { |
- if (partial_map_expand_apply (objfile, name, full_path, real_path, |
- pst, callback, data)) |
- return 1; |
- } |
+ if (partial_map_expand_apply (objfile, name, real_path, |
+ pst, callback, data)) |
+ return 1; |
+ continue; |
} |
+ /* If the user gave us an absolute path, try to find the file in |
+ this symtab and use its absolute path. */ |
if (real_path != NULL) |
{ |
- char *rp = NULL; |
- psymtab_to_fullname (pst); |
- if (pst->fullname != NULL) |
- { |
- rp = gdb_realpath (pst->fullname); |
- make_cleanup (xfree, rp); |
- } |
- if (rp != NULL |
- && (FILENAME_CMP (real_path, rp) == 0 |
- || (!is_abs && compare_filenames_for_search (real_path, |
- name, name_len)))) |
+ gdb_assert (IS_ABSOLUTE_PATH (real_path)); |
+ gdb_assert (IS_ABSOLUTE_PATH (name)); |
+ if (filename_cmp (psymtab_to_fullname (pst), real_path) == 0) |
{ |
- if (partial_map_expand_apply (objfile, name, full_path, real_path, |
+ if (partial_map_expand_apply (objfile, name, real_path, |
pst, callback, data)) |
return 1; |
+ continue; |
} |
} |
} |
@@ -237,11 +223,11 @@ partial_map_symtabs_matching_filename (struct objfile *objfile, |
We may find a different psymtab than PST. See FIND_PC_SECT_PSYMTAB. */ |
static struct partial_symtab * |
-find_pc_sect_psymtab_closer (CORE_ADDR pc, struct obj_section *section, |
+find_pc_sect_psymtab_closer (struct objfile *objfile, |
+ CORE_ADDR pc, struct obj_section *section, |
struct partial_symtab *pst, |
struct minimal_symbol *msymbol) |
{ |
- struct objfile *objfile = pst->objfile; |
struct partial_symtab *tpst; |
struct partial_symtab *best_pst = pst; |
CORE_ADDR best_addr = pst->textlow; |
@@ -277,7 +263,7 @@ find_pc_sect_psymtab_closer (CORE_ADDR pc, struct obj_section *section, |
corresponding msymbol, which is not necessarily |
true; the debug info might be much richer than the |
object's symbol table. */ |
- p = find_pc_sect_psymbol (tpst, pc, section); |
+ p = find_pc_sect_psymbol (objfile, tpst, pc, section); |
if (p != NULL |
&& SYMBOL_VALUE_ADDRESS (p) |
== SYMBOL_VALUE_ADDRESS (msymbol)) |
@@ -342,7 +328,7 @@ find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc, |
corresponding msymbol, which is not necessarily |
true; the debug info might be much richer than the |
object's symbol table. */ |
- p = find_pc_sect_psymbol (pst, pc, section); |
+ p = find_pc_sect_psymbol (objfile, pst, pc, section); |
if (!p |
|| SYMBOL_VALUE_ADDRESS (p) |
!= SYMBOL_VALUE_ADDRESS (msymbol)) |
@@ -376,7 +362,8 @@ find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc, |
{ |
struct partial_symtab *best_pst; |
- best_pst = find_pc_sect_psymtab_closer (pc, section, pst, msymbol); |
+ best_pst = find_pc_sect_psymtab_closer (objfile, pc, section, pst, |
+ msymbol); |
if (best_pst != NULL) |
return best_pst; |
} |
@@ -400,8 +387,8 @@ find_pc_sect_symtab_from_partial (struct objfile *objfile, |
continue, so let's not. */ |
warning (_("\ |
(Internal error: pc %s in read in psymtab, but not in symtab.)\n"), |
- paddress (get_objfile_arch (ps->objfile), pc)); |
- psymtab_to_symtab (ps); |
+ paddress (get_objfile_arch (objfile), pc)); |
+ psymtab_to_symtab (objfile, ps); |
return ps->symtab; |
} |
return NULL; |
@@ -411,7 +398,8 @@ find_pc_sect_symtab_from_partial (struct objfile *objfile, |
Return 0 if none. */ |
static struct partial_symbol * |
-find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, |
+find_pc_sect_psymbol (struct objfile *objfile, |
+ struct partial_symtab *psymtab, CORE_ADDR pc, |
struct obj_section *section) |
{ |
struct partial_symbol *best = NULL, *p, **pp; |
@@ -425,14 +413,14 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, |
/* Search the global symbols as well as the static symbols, so that |
find_pc_partial_function doesn't use a minimal symbol and thus |
cache a bad endaddr. */ |
- for (pp = psymtab->objfile->global_psymbols.list + psymtab->globals_offset; |
- (pp - (psymtab->objfile->global_psymbols.list + psymtab->globals_offset) |
+ for (pp = objfile->global_psymbols.list + psymtab->globals_offset; |
+ (pp - (objfile->global_psymbols.list + psymtab->globals_offset) |
< psymtab->n_global_syms); |
pp++) |
{ |
p = *pp; |
if (SYMBOL_DOMAIN (p) == VAR_DOMAIN |
- && SYMBOL_CLASS (p) == LOC_BLOCK |
+ && PSYMBOL_CLASS (p) == LOC_BLOCK |
&& pc >= SYMBOL_VALUE_ADDRESS (p) |
&& (SYMBOL_VALUE_ADDRESS (p) > best_pc |
|| (psymtab->textlow == 0 |
@@ -440,8 +428,9 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, |
{ |
if (section) /* Match on a specific section. */ |
{ |
- fixup_psymbol_section (p, psymtab->objfile); |
- if (!matching_obj_sections (SYMBOL_OBJ_SECTION (p), section)) |
+ fixup_psymbol_section (p, objfile); |
+ if (!matching_obj_sections (SYMBOL_OBJ_SECTION (objfile, p), |
+ section)) |
continue; |
} |
best_pc = SYMBOL_VALUE_ADDRESS (p); |
@@ -449,14 +438,14 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, |
} |
} |
- for (pp = psymtab->objfile->static_psymbols.list + psymtab->statics_offset; |
- (pp - (psymtab->objfile->static_psymbols.list + psymtab->statics_offset) |
+ for (pp = objfile->static_psymbols.list + psymtab->statics_offset; |
+ (pp - (objfile->static_psymbols.list + psymtab->statics_offset) |
< psymtab->n_static_syms); |
pp++) |
{ |
p = *pp; |
if (SYMBOL_DOMAIN (p) == VAR_DOMAIN |
- && SYMBOL_CLASS (p) == LOC_BLOCK |
+ && PSYMBOL_CLASS (p) == LOC_BLOCK |
&& pc >= SYMBOL_VALUE_ADDRESS (p) |
&& (SYMBOL_VALUE_ADDRESS (p) > best_pc |
|| (psymtab->textlow == 0 |
@@ -464,8 +453,9 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, |
{ |
if (section) /* Match on a specific section. */ |
{ |
- fixup_psymbol_section (p, psymtab->objfile); |
- if (!matching_obj_sections (SYMBOL_OBJ_SECTION (p), section)) |
+ fixup_psymbol_section (p, objfile); |
+ if (!matching_obj_sections (SYMBOL_OBJ_SECTION (objfile, p), |
+ section)) |
continue; |
} |
best_pc = SYMBOL_VALUE_ADDRESS (p); |
@@ -476,20 +466,20 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, |
return best; |
} |
-static struct partial_symbol * |
+static void |
fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile) |
{ |
CORE_ADDR addr; |
if (!psym) |
- return NULL; |
+ return; |
- if (SYMBOL_OBJ_SECTION (psym)) |
- return psym; |
+ if (SYMBOL_SECTION (psym) >= 0) |
+ return; |
gdb_assert (objfile); |
- switch (SYMBOL_CLASS (psym)) |
+ switch (PSYMBOL_CLASS (psym)) |
{ |
case LOC_STATIC: |
case LOC_LABEL: |
@@ -499,12 +489,10 @@ fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile) |
default: |
/* Nothing else will be listed in the minsyms -- no use looking |
it up. */ |
- return psym; |
+ return; |
} |
fixup_section (&psym->ginfo, addr, objfile); |
- |
- return psym; |
} |
static struct symtab * |
@@ -518,10 +506,11 @@ lookup_symbol_aux_psymtabs (struct objfile *objfile, |
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps) |
{ |
- if (!ps->readin && lookup_partial_symbol (ps, name, psymtab_index, domain)) |
+ if (!ps->readin && lookup_partial_symbol (objfile, ps, name, |
+ psymtab_index, domain)) |
{ |
struct symbol *sym = NULL; |
- struct symtab *stab = psymtab_to_symtab (ps); |
+ struct symtab *stab = psymtab_to_symtab (objfile, ps); |
/* Some caution must be observed with overloaded functions |
and methods, since the psymtab will not contain any overload |
@@ -558,7 +547,8 @@ lookup_symbol_aux_psymtabs (struct objfile *objfile, |
with MATCH. Returns the symbol, if found, and otherwise NULL. */ |
static struct partial_symbol * |
-match_partial_symbol (struct partial_symtab *pst, int global, |
+match_partial_symbol (struct objfile *objfile, |
+ struct partial_symtab *pst, int global, |
const char *name, domain_enum domain, |
symbol_compare_ftype *match, |
symbol_compare_ftype *ordered_compare) |
@@ -571,8 +561,8 @@ match_partial_symbol (struct partial_symtab *pst, int global, |
if (length == 0) |
return NULL; |
start = (global ? |
- pst->objfile->global_psymbols.list + pst->globals_offset : |
- pst->objfile->static_psymbols.list + pst->statics_offset); |
+ objfile->global_psymbols.list + pst->globals_offset : |
+ objfile->static_psymbols.list + pst->statics_offset); |
if (global && ordered_compare) /* Can use a binary search. */ |
{ |
@@ -628,15 +618,6 @@ match_partial_symbol (struct partial_symtab *pst, int global, |
return NULL; |
} |
-static void |
-pre_expand_symtabs_matching_psymtabs (struct objfile *objfile, |
- enum block_enum block_kind, |
- const char *name, |
- domain_enum domain) |
-{ |
- /* Nothing. */ |
-} |
- |
/* Returns the name used to search psymtabs. Unlike symtabs, psymtabs do |
not contain any method/function instance information (since this would |
force reading type information while reading psymtabs). Therefore, |
@@ -674,7 +655,8 @@ psymtab_search_name (const char *name) |
Check the global symbols if GLOBAL, the static symbols if not. */ |
static struct partial_symbol * |
-lookup_partial_symbol (struct partial_symtab *pst, const char *name, |
+lookup_partial_symbol (struct objfile *objfile, |
+ struct partial_symtab *pst, const char *name, |
int global, domain_enum domain) |
{ |
struct partial_symbol **start, **psym; |
@@ -692,8 +674,8 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, |
search_name = psymtab_search_name (name); |
cleanup = make_cleanup (xfree, search_name); |
start = (global ? |
- pst->objfile->global_psymbols.list + pst->globals_offset : |
- pst->objfile->static_psymbols.list + pst->statics_offset); |
+ objfile->global_psymbols.list + pst->globals_offset : |
+ objfile->static_psymbols.list + pst->statics_offset); |
if (global) /* This means we can use a binary search. */ |
{ |
@@ -778,7 +760,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, |
This is fast after the first time you do it. */ |
static struct symtab * |
-psymtab_to_symtab (struct partial_symtab *pst) |
+psymtab_to_symtab (struct objfile *objfile, struct partial_symtab *pst) |
{ |
/* If it is a shared psymtab, find an unshared psymtab that includes |
it. Any such psymtab will do. */ |
@@ -794,7 +776,7 @@ psymtab_to_symtab (struct partial_symtab *pst) |
{ |
struct cleanup *back_to = increment_reading_symtab (); |
- (*pst->read_symtab) (pst); |
+ (*pst->read_symtab) (pst, objfile); |
do_cleanups (back_to); |
} |
@@ -803,8 +785,8 @@ psymtab_to_symtab (struct partial_symtab *pst) |
static void |
relocate_psymtabs (struct objfile *objfile, |
- struct section_offsets *new_offsets, |
- struct section_offsets *delta) |
+ const struct section_offsets *new_offsets, |
+ const struct section_offsets *delta) |
{ |
struct partial_symbol **psym; |
struct partial_symtab *p; |
@@ -860,7 +842,7 @@ find_last_source_symtab_from_partial (struct objfile *ofp) |
"readin pst found and no symtabs.")); |
} |
else |
- return psymtab_to_symtab (cs_pst); |
+ return psymtab_to_symtab (ofp, cs_pst); |
} |
return NULL; |
} |
@@ -888,6 +870,7 @@ print_partial_symbols (struct gdbarch *gdbarch, |
fprintf_filtered (outfile, " %s partial symbols:\n", what); |
while (count-- > 0) |
{ |
+ QUIT; |
fprintf_filtered (outfile, " `%s'", SYMBOL_LINKAGE_NAME (*p)); |
if (SYMBOL_DEMANGLED_NAME (*p) != NULL) |
{ |
@@ -912,7 +895,7 @@ print_partial_symbols (struct gdbarch *gdbarch, |
fputs_filtered ("<invalid domain>, ", outfile); |
break; |
} |
- switch (SYMBOL_CLASS (*p)) |
+ switch (PSYMBOL_CLASS (*p)) |
{ |
case LOC_UNDEF: |
fputs_filtered ("undefined", outfile); |
@@ -991,7 +974,7 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab, |
gdb_print_host_address (psymtab, outfile); |
fprintf_filtered (outfile, ")\n\n"); |
fprintf_unfiltered (outfile, " Read from object file %s (", |
- objfile->name); |
+ objfile_name (objfile)); |
gdb_print_host_address (objfile, outfile); |
fprintf_unfiltered (outfile, ")\n"); |
@@ -1006,7 +989,7 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab, |
} |
fprintf_filtered (outfile, " Relocate symbols by "); |
- for (i = 0; i < psymtab->objfile->num_sections; ++i) |
+ for (i = 0; i < objfile->num_sections; ++i) |
{ |
if (i != 0) |
fprintf_filtered (outfile, ", "); |
@@ -1087,10 +1070,6 @@ dump_psymtabs_for_objfile (struct objfile *objfile) |
psymtab->filename); |
gdb_print_host_address (psymtab, gdb_stdout); |
printf_filtered (", "); |
- if (psymtab->objfile != objfile) |
- { |
- printf_filtered ("NOT ON CHAIN! "); |
- } |
wrap_here (" "); |
} |
printf_filtered ("\n\n"); |
@@ -1110,11 +1089,11 @@ read_symtabs_for_function (struct objfile *objfile, const char *func_name) |
if (ps->readin) |
continue; |
- if ((lookup_partial_symbol (ps, func_name, 1, VAR_DOMAIN) |
+ if ((lookup_partial_symbol (objfile, ps, func_name, 1, VAR_DOMAIN) |
!= NULL) |
- || (lookup_partial_symbol (ps, func_name, 0, VAR_DOMAIN) |
+ || (lookup_partial_symbol (objfile, ps, func_name, 0, VAR_DOMAIN) |
!= NULL)) |
- psymtab_to_symtab (ps); |
+ psymtab_to_symtab (objfile, ps); |
} |
} |
@@ -1125,12 +1104,12 @@ expand_partial_symbol_tables (struct objfile *objfile) |
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, psymtab) |
{ |
- psymtab_to_symtab (psymtab); |
+ psymtab_to_symtab (objfile, psymtab); |
} |
} |
static void |
-read_psymtabs_with_filename (struct objfile *objfile, const char *filename) |
+read_psymtabs_with_fullname (struct objfile *objfile, const char *fullname) |
{ |
struct partial_symtab *p; |
@@ -1140,8 +1119,12 @@ read_psymtabs_with_filename (struct objfile *objfile, const char *filename) |
if (p->anonymous) |
continue; |
- if (filename_cmp (filename, p->filename) == 0) |
- psymtab_to_symtab (p); |
+ /* psymtab_to_fullname tries to open the file which is slow. |
+ Don't call it if we know the basenames don't match. */ |
+ if ((basenames_may_differ |
+ || filename_cmp (lbasename (fullname), lbasename (p->filename)) == 0) |
+ && filename_cmp (fullname, psymtab_to_fullname (p)) == 0) |
+ psymtab_to_symtab (objfile, p); |
} |
} |
@@ -1185,44 +1168,42 @@ map_symbol_filenames_psymtab (struct objfile *objfile, |
If this function fails to find the file that this partial_symtab represents, |
NULL will be returned and ps->fullname will be set to NULL. */ |
-static char * |
+static const char * |
psymtab_to_fullname (struct partial_symtab *ps) |
{ |
- int r; |
- |
- if (!ps) |
- return NULL; |
- if (ps->anonymous) |
- return NULL; |
+ gdb_assert (!ps->anonymous); |
/* Use cached copy if we have it. |
We rely on forget_cached_source_info being called appropriately |
to handle cases like the file being moved. */ |
- if (ps->fullname) |
- return ps->fullname; |
+ if (ps->fullname == NULL) |
+ { |
+ int fd = find_and_open_source (ps->filename, ps->dirname, &ps->fullname); |
- r = find_and_open_source (ps->filename, ps->dirname, &ps->fullname); |
+ if (fd >= 0) |
+ close (fd); |
+ else |
+ { |
+ char *fullname; |
+ struct cleanup *back_to; |
- if (r >= 0) |
- { |
- close (r); |
- return ps->fullname; |
- } |
+ /* rewrite_source_path would be applied by find_and_open_source, we |
+ should report the pathname where GDB tried to find the file. */ |
- return NULL; |
-} |
+ if (ps->dirname == NULL || IS_ABSOLUTE_PATH (ps->filename)) |
+ fullname = xstrdup (ps->filename); |
+ else |
+ fullname = concat (ps->dirname, SLASH_STRING, ps->filename, NULL); |
-static const char * |
-find_symbol_file_from_partial (struct objfile *objfile, const char *name) |
-{ |
- struct partial_symtab *pst; |
+ back_to = make_cleanup (xfree, fullname); |
+ ps->fullname = rewrite_source_path (fullname); |
+ if (ps->fullname == NULL) |
+ ps->fullname = xstrdup (fullname); |
+ do_cleanups (back_to); |
+ } |
+ } |
- ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst) |
- { |
- if (lookup_partial_symbol (pst, name, 1, VAR_DOMAIN)) |
- return pst->filename; |
- } |
- return NULL; |
+ return ps->fullname; |
} |
/* For all symbols, s, in BLOCK that are in NAMESPACE and match NAME |
@@ -1257,8 +1238,9 @@ map_block (const char *name, domain_enum namespace, struct objfile *objfile, |
the definition of quick_symbol_functions in symfile.h. */ |
static void |
-map_matching_symbols_psymtab (const char *name, domain_enum namespace, |
- struct objfile *objfile, int global, |
+map_matching_symbols_psymtab (struct objfile *objfile, |
+ const char *name, domain_enum namespace, |
+ int global, |
int (*callback) (struct block *, |
struct symbol *, void *), |
void *data, |
@@ -1272,10 +1254,10 @@ map_matching_symbols_psymtab (const char *name, domain_enum namespace, |
{ |
QUIT; |
if (ps->readin |
- || match_partial_symbol (ps, global, name, namespace, match, |
+ || match_partial_symbol (objfile, ps, global, name, namespace, match, |
ordered_compare)) |
{ |
- struct symtab *s = psymtab_to_symtab (ps); |
+ struct symtab *s = psymtab_to_symtab (objfile, ps); |
struct block *block; |
if (s == NULL || !s->primary) |
@@ -1358,12 +1340,12 @@ recursively_search_psymtabs (struct partial_symtab *ps, |
if ((kind == ALL_DOMAIN |
|| (kind == VARIABLES_DOMAIN |
- && SYMBOL_CLASS (*psym) != LOC_TYPEDEF |
- && SYMBOL_CLASS (*psym) != LOC_BLOCK) |
+ && PSYMBOL_CLASS (*psym) != LOC_TYPEDEF |
+ && PSYMBOL_CLASS (*psym) != LOC_BLOCK) |
|| (kind == FUNCTIONS_DOMAIN |
- && SYMBOL_CLASS (*psym) == LOC_BLOCK) |
+ && PSYMBOL_CLASS (*psym) == LOC_BLOCK) |
|| (kind == TYPES_DOMAIN |
- && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)) |
+ && PSYMBOL_CLASS (*psym) == LOC_TYPEDEF)) |
&& (*name_matcher) (SYMBOL_SEARCH_NAME (*psym), data)) |
{ |
/* Found a match, so notify our caller. */ |
@@ -1381,7 +1363,7 @@ recursively_search_psymtabs (struct partial_symtab *ps, |
static void |
expand_symtabs_matching_via_partial |
(struct objfile *objfile, |
- int (*file_matcher) (const char *, void *), |
+ int (*file_matcher) (const char *, void *, int basenames), |
int (*name_matcher) (const char *, void *), |
enum search_domain kind, |
void *data) |
@@ -1406,14 +1388,26 @@ expand_symtabs_matching_via_partial |
if (file_matcher) |
{ |
+ int match; |
+ |
if (ps->anonymous) |
continue; |
- if (! (*file_matcher) (ps->filename, data)) |
+ |
+ match = (*file_matcher) (ps->filename, data, 0); |
+ if (!match) |
+ { |
+ /* Before we invoke realpath, which can get expensive when many |
+ files are involved, do a quick comparison of the basenames. */ |
+ if (basenames_may_differ |
+ || (*file_matcher) (lbasename (ps->filename), data, 1)) |
+ match = (*file_matcher) (psymtab_to_fullname (ps), data, 0); |
+ } |
+ if (!match) |
continue; |
} |
if (recursively_search_psymtabs (ps, objfile, kind, name_matcher, data)) |
- psymtab_to_symtab (ps); |
+ psymtab_to_symtab (objfile, ps); |
} |
} |
@@ -1430,14 +1424,12 @@ const struct quick_symbol_functions psym_functions = |
forget_cached_source_info_partial, |
partial_map_symtabs_matching_filename, |
lookup_symbol_aux_psymtabs, |
- pre_expand_symtabs_matching_psymtabs, |
print_psymtab_stats_for_objfile, |
dump_psymtabs_for_objfile, |
relocate_psymtabs, |
read_symtabs_for_function, |
expand_partial_symbol_tables, |
- read_psymtabs_with_filename, |
- find_symbol_file_from_partial, |
+ read_psymtabs_with_fullname, |
map_matching_symbols_psymtab, |
expand_symtabs_matching_via_partial, |
find_pc_sect_symtab_from_partial, |
@@ -1460,11 +1452,11 @@ compare_psymbols (const void *s1p, const void *s2p) |
} |
void |
-sort_pst_symbols (struct partial_symtab *pst) |
+sort_pst_symbols (struct objfile *objfile, struct partial_symtab *pst) |
{ |
/* Sort the global list; don't sort the static list. */ |
- qsort (pst->objfile->global_psymbols.list + pst->globals_offset, |
+ qsort (objfile->global_psymbols.list + pst->globals_offset, |
pst->n_global_syms, sizeof (struct partial_symbol *), |
compare_psymbols); |
} |
@@ -1595,10 +1587,10 @@ add_psymbol_to_bcache (const char *name, int namelength, int copy_name, |
{ |
struct partial_symbol psymbol; |
- /* We must ensure that the entire 'value' field has been zeroed |
- before assigning to it, because an assignment may not write the |
- entire field. */ |
- memset (&psymbol.ginfo.value, 0, sizeof (psymbol.ginfo.value)); |
+ /* We must ensure that the entire struct has been zeroed before |
+ assigning to it, because an assignment may not touch some of the |
+ holes. */ |
+ memset (&psymbol, 0, sizeof (psymbol)); |
/* val and coreaddr are mutually exclusive, one of them *will* be zero. */ |
if (val != 0) |
@@ -1609,9 +1601,8 @@ add_psymbol_to_bcache (const char *name, int namelength, int copy_name, |
{ |
SYMBOL_VALUE_ADDRESS (&psymbol) = coreaddr; |
} |
- SYMBOL_SECTION (&psymbol) = 0; |
- SYMBOL_OBJ_SECTION (&psymbol) = NULL; |
- SYMBOL_SET_LANGUAGE (&psymbol, language); |
+ SYMBOL_SECTION (&psymbol) = -1; |
+ SYMBOL_SET_LANGUAGE (&psymbol, language, &objfile->objfile_obstack); |
PSYMBOL_DOMAIN (&psymbol) = domain; |
PSYMBOL_CLASS (&psymbol) = class; |
@@ -1714,7 +1705,7 @@ init_psymbol_list (struct objfile *objfile, int total_symbols) |
/* Current best guess is that approximately a twentieth |
of the total symbols (in a debugging file) are global or static |
- oriented symbols. */ |
+ oriented symbols, then multiply that by slop factor of two. */ |
objfile->global_psymbols.size = total_symbols / 10; |
objfile->static_psymbols.size = total_symbols / 10; |
@@ -1751,15 +1742,14 @@ allocate_psymtab (const char *filename, struct objfile *objfile) |
sizeof (struct partial_symtab)); |
memset (psymtab, 0, sizeof (struct partial_symtab)); |
- psymtab->filename = obsavestring (filename, strlen (filename), |
- &objfile->objfile_obstack); |
+ psymtab->filename = bcache (filename, strlen (filename) + 1, |
+ objfile->per_bfd->filename_cache); |
psymtab->symtab = NULL; |
/* Prepend it to the psymtab list for the objfile it belongs to. |
Psymtabs are searched in most recent inserted -> least recent |
inserted order. */ |
- psymtab->objfile = objfile; |
psymtab->next = objfile->psymtabs; |
objfile->psymtabs = psymtab; |
@@ -1770,10 +1760,10 @@ allocate_psymtab (const char *filename, struct objfile *objfile) |
static char *last_objfile_name = NULL; |
if (last_objfile_name == NULL |
- || strcmp (last_objfile_name, objfile->name) != 0) |
+ || strcmp (last_objfile_name, objfile_name (objfile)) != 0) |
{ |
xfree (last_objfile_name); |
- last_objfile_name = xstrdup (objfile->name); |
+ last_objfile_name = xstrdup (objfile_name (objfile)); |
fprintf_unfiltered (gdb_stdlog, |
"Creating one or more psymtabs for objfile %s ...\n", |
last_objfile_name); |
@@ -1787,7 +1777,7 @@ allocate_psymtab (const char *filename, struct objfile *objfile) |
} |
void |
-discard_psymtab (struct partial_symtab *pst) |
+discard_psymtab (struct objfile *objfile, struct partial_symtab *pst) |
{ |
struct partial_symtab **prev_pst; |
@@ -1800,20 +1790,58 @@ discard_psymtab (struct partial_symtab *pst) |
/* First, snip it out of the psymtab chain. */ |
- prev_pst = &(pst->objfile->psymtabs); |
+ prev_pst = &(objfile->psymtabs); |
while ((*prev_pst) != pst) |
prev_pst = &((*prev_pst)->next); |
(*prev_pst) = pst->next; |
/* Next, put it on a free list for recycling. */ |
- pst->next = pst->objfile->free_psymtabs; |
- pst->objfile->free_psymtabs = pst; |
+ pst->next = objfile->free_psymtabs; |
+ objfile->free_psymtabs = pst; |
+} |
+ |
+/* An object of this type is passed to discard_psymtabs_upto. */ |
+ |
+struct psymtab_state |
+{ |
+ /* The objfile where psymtabs are discarded. */ |
+ |
+ struct objfile *objfile; |
+ |
+ /* The first psymtab to save. */ |
+ |
+ struct partial_symtab *save; |
+}; |
+ |
+/* A cleanup function used by make_cleanup_discard_psymtabs. */ |
+ |
+static void |
+discard_psymtabs_upto (void *arg) |
+{ |
+ struct psymtab_state *state = arg; |
+ |
+ while (state->objfile->psymtabs != state->save) |
+ discard_psymtab (state->objfile, state->objfile->psymtabs); |
+} |
+ |
+/* Return a new cleanup that discards all psymtabs created in OBJFILE |
+ after this function is called. */ |
+ |
+struct cleanup * |
+make_cleanup_discard_psymtabs (struct objfile *objfile) |
+{ |
+ struct psymtab_state *state = XNEW (struct psymtab_state); |
+ |
+ state->objfile = objfile; |
+ state->save = objfile->psymtabs; |
+ |
+ return make_cleanup_dtor (discard_psymtabs_upto, state, xfree); |
} |
-void |
+static void |
maintenance_print_psymbols (char *args, int from_tty) |
{ |
char **argv; |
@@ -1852,16 +1880,17 @@ print-psymbols takes an output file name and optional symbol file name")); |
perror_with_name (filename); |
make_cleanup_ui_file_delete (outfile); |
- immediate_quit++; |
ALL_PSYMTABS (objfile, ps) |
- if (symname == NULL || filename_cmp (symname, ps->filename) == 0) |
- dump_psymtab (objfile, ps, outfile); |
- immediate_quit--; |
+ { |
+ QUIT; |
+ if (symname == NULL || filename_cmp (symname, ps->filename) == 0) |
+ dump_psymtab (objfile, ps, outfile); |
+ } |
do_cleanups (cleanups); |
} |
/* List all the partial symbol tables whose names match REGEXP (optional). */ |
-void |
+static void |
maintenance_info_psymtabs (char *regexp, int from_tty) |
{ |
struct program_space *pspace; |
@@ -1889,7 +1918,7 @@ maintenance_info_psymtabs (char *regexp, int from_tty) |
{ |
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)); |
@@ -1920,7 +1949,7 @@ maintenance_info_psymtabs (char *regexp, int from_tty) |
if (psymtab->n_global_syms) |
{ |
printf_filtered ("(* (struct partial_symbol **) %s @ %d)\n", |
- host_address_to_string (psymtab->objfile->global_psymbols.list |
+ host_address_to_string (objfile->global_psymbols.list |
+ psymtab->globals_offset), |
psymtab->n_global_syms); |
} |
@@ -1930,7 +1959,7 @@ maintenance_info_psymtabs (char *regexp, int from_tty) |
if (psymtab->n_static_syms) |
{ |
printf_filtered ("(* (struct partial_symbol **) %s @ %d)\n", |
- host_address_to_string (psymtab->objfile->static_psymbols.list |
+ host_address_to_string (objfile->static_psymbols.list |
+ psymtab->statics_offset), |
psymtab->n_static_syms); |
} |
@@ -1965,10 +1994,10 @@ maintenance_info_psymtabs (char *regexp, int from_tty) |
} |
} |
-/* Check consistency of psymtabs and symtabs. */ |
+/* Check consistency of currently expanded psymtabs vs symtabs. */ |
-void |
-maintenance_check_symtabs (char *ignore, int from_tty) |
+static void |
+maintenance_check_psymtabs (char *ignore, int from_tty) |
{ |
struct symbol *sym; |
struct partial_symbol **psym; |
@@ -1983,12 +2012,30 @@ maintenance_check_symtabs (char *ignore, int from_tty) |
{ |
struct gdbarch *gdbarch = get_objfile_arch (objfile); |
- s = psymtab_to_symtab (ps); |
+ /* We don't call psymtab_to_symtab here because that may cause symtab |
+ expansion. When debugging a problem it helps if checkers leave |
+ things unchanged. */ |
+ s = ps->symtab; |
+ |
+ /* First do some checks that don't require the associated symtab. */ |
+ if (ps->texthigh < ps->textlow) |
+ { |
+ printf_filtered ("Psymtab "); |
+ puts_filtered (ps->filename); |
+ printf_filtered (" covers bad range "); |
+ fputs_filtered (paddress (gdbarch, ps->textlow), gdb_stdout); |
+ printf_filtered (" - "); |
+ fputs_filtered (paddress (gdbarch, ps->texthigh), gdb_stdout); |
+ printf_filtered ("\n"); |
+ continue; |
+ } |
+ |
+ /* Now do checks requiring the associated symtab. */ |
if (s == NULL) |
continue; |
bv = BLOCKVECTOR (s); |
b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); |
- psym = ps->objfile->static_psymbols.list + ps->statics_offset; |
+ psym = objfile->static_psymbols.list + ps->statics_offset; |
length = ps->n_static_syms; |
while (length--) |
{ |
@@ -2005,7 +2052,7 @@ maintenance_check_symtabs (char *ignore, int from_tty) |
psym++; |
} |
b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); |
- psym = ps->objfile->global_psymbols.list + ps->globals_offset; |
+ psym = objfile->global_psymbols.list + ps->globals_offset; |
length = ps->n_global_syms; |
while (length--) |
{ |
@@ -2021,20 +2068,8 @@ maintenance_check_symtabs (char *ignore, int from_tty) |
} |
psym++; |
} |
- if (ps->texthigh < ps->textlow) |
- { |
- printf_filtered ("Psymtab "); |
- puts_filtered (ps->filename); |
- printf_filtered (" covers bad range "); |
- fputs_filtered (paddress (gdbarch, ps->textlow), gdb_stdout); |
- printf_filtered (" - "); |
- fputs_filtered (paddress (gdbarch, ps->texthigh), gdb_stdout); |
- printf_filtered ("\n"); |
- continue; |
- } |
- if (ps->texthigh == 0) |
- continue; |
- if (ps->textlow < BLOCK_START (b) || ps->texthigh > BLOCK_END (b)) |
+ if (ps->texthigh != 0 |
+ && (ps->textlow < BLOCK_START (b) || ps->texthigh > BLOCK_END (b))) |
{ |
printf_filtered ("Psymtab "); |
puts_filtered (ps->filename); |
@@ -2080,3 +2115,26 @@ map_partial_symbol_filenames (symbol_filename_ftype *fun, void *data, |
need_fullname); |
} |
} |
+ |
+extern initialize_file_ftype _initialize_psymtab; |
+ |
+void |
+_initialize_psymtab (void) |
+{ |
+ add_cmd ("psymbols", class_maintenance, maintenance_print_psymbols, _("\ |
+Print dump of current partial symbol definitions.\n\ |
+Entries in the partial symbol table are dumped to file OUTFILE.\n\ |
+If a SOURCE file is specified, dump only that file's partial symbols."), |
+ &maintenanceprintlist); |
+ |
+ add_cmd ("psymtabs", class_maintenance, maintenance_info_psymtabs, _("\ |
+List the partial symbol tables for all object files.\n\ |
+This does not include information about individual partial symbols,\n\ |
+just the symbol table structures themselves."), |
+ &maintenanceinfolist); |
+ |
+ add_cmd ("check-psymtabs", class_maintenance, maintenance_check_psymtabs, |
+ _("\ |
+Check consistency of currently expanded psymtabs versus symtabs."), |
+ &maintenancelist); |
+} |