/* Partial symbol tables.
- Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2009-2013 Free Software Foundation, Inc.
This file is part of GDB.
#include "dictionary.h"
#include "language.h"
#include "cp-support.h"
+#include "gdbcmd.h"
#ifndef DEV_TTY
#define DEV_TTY "/dev/tty"
struct bcache *bcache;
};
-/* A fast way to get from a psymtab to its symtab (after the first time). */
-#define PSYMTAB_TO_SYMTAB(pst) \
- ((pst) -> symtab != NULL ? (pst) -> symtab : psymtab_to_symtab (pst))
-
-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. */
ALL_OBJFILES (objfile) \
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
-/* Lookup the partial symbol table of a source file named NAME.
- *If* there is no '/' in the name, a match after a '/'
- in the psymtab filename will also work. */
+/* Helper function for partial_map_symtabs_matching_filename that
+ expands the symtabs and calls the iterator. */
-static struct partial_symtab *
-lookup_partial_symtab (struct objfile *objfile, const char *name,
- const char *full_path, const char *real_path)
+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 *),
+ void *data)
+{
+ struct symtab *last_made = objfile->symtabs;
+
+ /* Shared psymtabs should never be seen here. Instead they should
+ be handled properly by the caller. */
+ gdb_assert (pst->user == NULL);
+
+ /* Don't visit already-expanded psymtabs. */
+ if (pst->readin)
+ return 0;
+
+ /* This may expand more than one symtab, and we want to iterate over
+ all of them. */
+ psymtab_to_symtab (objfile, pst);
+
+ return iterate_over_some_symtabs (name, full_path, real_path, callback, data,
+ objfile->symtabs, last_made);
+}
+
+/* Implementation of the map_symtabs_matching_filename method. */
+
+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 *),
+ void *data)
{
struct partial_symtab *pst;
+ const char *name_basename = lbasename (name);
+ int is_abs = IS_ABSOLUTE_PATH (name);
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
{
- if (FILENAME_CMP (name, pst->filename) == 0)
+ /* We can skip shared psymtabs here, because any file name will be
+ attached to the unshared psymtab. */
+ if (pst->user != NULL)
+ continue;
+
+ /* Anonymous psymtabs don't have a file name. */
+ if (pst->anonymous)
+ continue;
+
+ if (FILENAME_CMP (name, pst->filename) == 0
+ || (!is_abs && compare_filenames_for_search (pst->filename, name)))
{
- return (pst);
+ if (partial_map_expand_apply (objfile, name, full_path, real_path,
+ pst, callback, data))
+ return 1;
}
+ /* Before we invoke realpath, which can get expensive when many
+ files are involved, do a quick comparison of the basenames. */
+ if (! basenames_may_differ
+ && 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)
{
psymtab_to_fullname (pst);
if (pst->fullname != NULL
- && FILENAME_CMP (full_path, pst->fullname) == 0)
+ && (FILENAME_CMP (full_path, pst->fullname) == 0
+ || (!is_abs && compare_filenames_for_search (pst->fullname,
+ name))))
{
- return pst;
+ if (partial_map_expand_apply (objfile, name, full_path, real_path,
+ pst, callback, data))
+ return 1;
}
}
rp = gdb_realpath (pst->fullname);
make_cleanup (xfree, rp);
}
- if (rp != NULL && FILENAME_CMP (real_path, rp) == 0)
+ if (rp != NULL
+ && (FILENAME_CMP (real_path, rp) == 0
+ || (!is_abs && compare_filenames_for_search (real_path, name))))
{
- return pst;
+ if (partial_map_expand_apply (objfile, name, full_path, real_path,
+ pst, callback, data))
+ return 1;
}
}
}
- /* Now, search for a matching tail (only if name doesn't have any dirs). */
-
- if (lbasename (name) == name)
- ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
- {
- if (FILENAME_CMP (lbasename (pst->filename), name) == 0)
- return (pst);
- }
-
- return (NULL);
-}
-
-static int
-lookup_symtab_via_partial_symtab (struct objfile *objfile, const char *name,
- const char *full_path, const char *real_path,
- struct symtab **result)
-{
- struct partial_symtab *ps;
-
- ps = lookup_partial_symtab (objfile, name, full_path, real_path);
- if (!ps)
- return 0;
-
- if (ps->readin)
- error (_("Internal: readin %s pst for `%s' found when no symtab found."),
- ps->filename, name);
-
- *result = PSYMTAB_TO_SYMTAB (ps);
- return 1;
+ return 0;
}
/* Find which partial symtab contains PC and SECTION starting at psymtab PST.
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;
+ gdb_assert (!pst->psymtabs_addrmap_supported);
+
/* An objfile that has its functions reordered might have
many partial symbol tables containing the PC, but
we want the partial symbol table that contains the
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))
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))
debug info type in single OBJFILE. */
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
- if (pc >= pst->textlow && pc < pst->texthigh)
+ if (!pst->psymtabs_addrmap_supported
+ && pc >= pst->textlow && pc < pst->texthigh)
{
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;
}
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));
- return PSYMTAB_TO_SYMTAB (ps);
+ paddress (get_objfile_arch (objfile), pc));
+ psymtab_to_symtab (objfile, ps);
+ return ps->symtab;
}
return NULL;
}
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;
/* 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++)
{
{
if (section) /* Match on a specific section. */
{
- fixup_psymbol_section (p, psymtab->objfile);
+ fixup_psymbol_section (p, objfile);
if (!matching_obj_sections (SYMBOL_OBJ_SECTION (p), section))
continue;
}
}
}
- 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++)
{
{
if (section) /* Match on a specific section. */
{
- fixup_psymbol_section (p, psymtab->objfile);
+ fixup_psymbol_section (p, objfile);
if (!matching_obj_sections (SYMBOL_OBJ_SECTION (p), section))
continue;
}
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;
-
- if (SYMBOL_OBJ_SECTION (psym))
- return psym;
+ if (psym == NULL || SYMBOL_OBJ_SECTION (psym) != NULL)
+ return;
gdb_assert (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 *
{
struct partial_symtab *ps;
const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0);
+ struct symtab *stab_best = NULL;
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
}
if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
- return stab;
+ {
+ if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+ return stab;
+
+ stab_best = stab;
+ }
/* Keep looking through other psymtabs. */
}
}
- return NULL;
+ return stab_best;
}
/* Look in PST for a symbol in DOMAIN whose name matches NAME. Search
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)
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. */
{
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,
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;
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. */
{
}
/* Get the symbol table that corresponds to a partial_symtab.
- This is fast after the first time you do it. In fact, there
- is an even faster macro PSYMTAB_TO_SYMTAB that does the fast
- case inline. */
+ 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. */
+ while (pst->user != NULL)
+ pst = pst->user;
+
/* If it's been looked up before, return it. */
if (pst->symtab)
return pst->symtab;
{
struct cleanup *back_to = increment_reading_symtab ();
- (*pst->read_symtab) (pst);
+ (*pst->read_symtab) (objfile, pst);
do_cleanups (back_to);
}
"readin pst found and no symtabs."));
}
else
- return PSYMTAB_TO_SYMTAB (cs_pst);
+ return psymtab_to_symtab (ofp, cs_pst);
}
return NULL;
}
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)
{
struct gdbarch *gdbarch = get_objfile_arch (objfile);
int i;
- fprintf_filtered (outfile, "\nPartial symtab for source file %s ",
- psymtab->filename);
+ if (psymtab->anonymous)
+ {
+ fprintf_filtered (outfile, "\nAnonymous partial symtab (%s) ",
+ psymtab->filename);
+ }
+ else
+ {
+ fprintf_filtered (outfile, "\nPartial symtab for source file %s ",
+ psymtab->filename);
+ }
fprintf_filtered (outfile, "(object ");
gdb_print_host_address (psymtab, outfile);
fprintf_filtered (outfile, ")\n\n");
}
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, ", ");
fprintf_filtered (outfile, "-");
fputs_filtered (paddress (gdbarch, psymtab->texthigh), outfile);
fprintf_filtered (outfile, "\n");
+ fprintf_filtered (outfile, " Address map supported - %s.\n",
+ psymtab->psymtabs_addrmap_supported ? "yes" : "no");
fprintf_filtered (outfile, " Depends on %d other partial symtabs.\n",
psymtab->number_of_dependencies);
for (i = 0; i < psymtab->number_of_dependencies; i++)
fprintf_filtered (outfile, " %s\n",
psymtab->dependencies[i]->filename);
}
+ if (psymtab->user != NULL)
+ {
+ fprintf_filtered (outfile, " Shared partial symtab with user ");
+ gdb_print_host_address (psymtab->user, outfile);
+ fprintf_filtered (outfile, "\n");
+ }
if (psymtab->n_global_syms > 0)
{
print_partial_symbols (gdbarch,
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");
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);
}
}
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, psymtab)
{
- psymtab_to_symtab (psymtab);
+ psymtab_to_symtab (objfile, psymtab);
}
}
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
{
+ /* Anonymous psymtabs don't have a name of a source file. */
+ if (p->anonymous)
+ continue;
+
if (filename_cmp (filename, p->filename) == 0)
- PSYMTAB_TO_SYMTAB (p);
+ psymtab_to_symtab (objfile, p);
}
}
static void
map_symbol_filenames_psymtab (struct objfile *objfile,
- symbol_filename_ftype *fun, void *data)
+ symbol_filename_ftype *fun, void *data,
+ int need_fullname)
{
struct partial_symtab *ps;
if (ps->readin)
continue;
- fullname = psymtab_to_fullname (ps);
+ /* We can skip shared psymtabs here, because any file name will be
+ attached to the unshared psymtab. */
+ if (ps->user != NULL)
+ continue;
+
+ /* Anonymous psymtabs don't have a file name. */
+ if (ps->anonymous)
+ continue;
+
+ QUIT;
+ if (need_fullname)
+ fullname = psymtab_to_fullname (ps);
+ else
+ fullname = NULL;
(*fun) (ps->filename, fullname, data);
}
}
-int find_and_open_source (const char *filename,
- const char *dirname,
- char **fullname);
-
/* Finds the fullname that a partial_symtab represents.
If this functions finds the fullname, it will save it in ps->fullname
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;
+
+ /* 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;
- /* Don't check ps->fullname here, the file could have been
- deleted/moved/..., look for it again. */
r = find_and_open_source (ps->filename, ps->dirname, &ps->fullname);
if (r >= 0)
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
{
- if (lookup_partial_symbol (pst, name, 1, VAR_DOMAIN))
+ if (lookup_partial_symbol (objfile, pst, name, 1, VAR_DOMAIN))
return pst->filename;
}
return NULL;
int (*callback) (struct block *, struct symbol *, void *),
void *data, symbol_compare_ftype *match)
{
- struct dict_iterator iter;
+ struct block_iterator iter;
struct symbol *sym;
- for (sym = dict_iter_match_first (BLOCK_DICT (block), name, match, &iter);
- sym != NULL; sym = dict_iter_match_next (name, match, &iter))
+ for (sym = block_iter_match_first (block, name, match, &iter);
+ sym != NULL; sym = block_iter_match_next (name, match, &iter))
{
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
SYMBOL_DOMAIN (sym), 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)
}
}
-static void
-expand_symtabs_matching_via_partial (struct objfile *objfile,
- int (*file_matcher) (const char *,
- void *),
- int (*name_matcher) (const char *,
- void *),
- enum search_domain kind,
- void *data)
+/* A helper for expand_symtabs_matching_via_partial that handles
+ searching included psymtabs. This returns 1 if a symbol is found,
+ and zero otherwise. It also updates the 'searched_flag' on the
+ various psymtabs that it searches. */
+
+static int
+recursively_search_psymtabs (struct partial_symtab *ps,
+ struct objfile *objfile,
+ enum search_domain kind,
+ int (*name_matcher) (const char *, void *),
+ void *data)
{
- struct partial_symtab *ps;
+ struct partial_symbol **psym;
+ struct partial_symbol **bound, **gbound, **sbound;
+ int keep_going = 1;
+ int result = PST_SEARCHED_AND_NOT_FOUND;
+ int i;
- ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
+ if (ps->searched_flag != PST_NOT_SEARCHED)
+ return ps->searched_flag == PST_SEARCHED_AND_FOUND;
+
+ /* Recurse into shared psymtabs first, because they may have already
+ been searched, and this could save some time. */
+ for (i = 0; i < ps->number_of_dependencies; ++i)
{
- struct partial_symbol **psym;
- struct partial_symbol **bound, **gbound, **sbound;
- int keep_going = 1;
+ int r;
- if (ps->readin)
+ /* Skip non-shared dependencies, these are handled elsewhere. */
+ if (ps->dependencies[i]->user == NULL)
continue;
- if (file_matcher && ! (*file_matcher) (ps->filename, data))
- continue;
+ r = recursively_search_psymtabs (ps->dependencies[i],
+ objfile, kind, name_matcher, data);
+ if (r != 0)
+ {
+ ps->searched_flag = PST_SEARCHED_AND_FOUND;
+ return 1;
+ }
+ }
- gbound = objfile->global_psymbols.list
- + ps->globals_offset + ps->n_global_syms;
- sbound = objfile->static_psymbols.list
- + ps->statics_offset + ps->n_static_syms;
- bound = gbound;
+ gbound = (objfile->global_psymbols.list
+ + ps->globals_offset + ps->n_global_syms);
+ sbound = (objfile->static_psymbols.list
+ + ps->statics_offset + ps->n_static_syms);
+ bound = gbound;
- /* Go through all of the symbols stored in a partial
- symtab in one loop. */
- psym = objfile->global_psymbols.list + ps->globals_offset;
- while (keep_going)
+ /* Go through all of the symbols stored in a partial
+ symtab in one loop. */
+ psym = objfile->global_psymbols.list + ps->globals_offset;
+ while (keep_going)
+ {
+ if (psym >= bound)
{
- if (psym >= bound)
+ if (bound == gbound && ps->n_static_syms != 0)
{
- if (bound == gbound && ps->n_static_syms != 0)
- {
- psym = objfile->static_psymbols.list + ps->statics_offset;
- bound = sbound;
- }
- else
- keep_going = 0;
- continue;
+ psym = objfile->static_psymbols.list + ps->statics_offset;
+ bound = sbound;
}
else
+ keep_going = 0;
+ continue;
+ }
+ else
+ {
+ QUIT;
+
+ if ((kind == ALL_DOMAIN
+ || (kind == VARIABLES_DOMAIN
+ && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
+ && SYMBOL_CLASS (*psym) != LOC_BLOCK)
+ || (kind == FUNCTIONS_DOMAIN
+ && SYMBOL_CLASS (*psym) == LOC_BLOCK)
+ || (kind == TYPES_DOMAIN
+ && SYMBOL_CLASS (*psym) == LOC_TYPEDEF))
+ && (*name_matcher) (SYMBOL_SEARCH_NAME (*psym), data))
{
- QUIT;
-
- if ((kind == ALL_DOMAIN
- || (kind == VARIABLES_DOMAIN
- && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
- && SYMBOL_CLASS (*psym) != LOC_BLOCK)
- || (kind == FUNCTIONS_DOMAIN
- && SYMBOL_CLASS (*psym) == LOC_BLOCK)
- || (kind == TYPES_DOMAIN
- && SYMBOL_CLASS (*psym) == LOC_TYPEDEF))
- && (*name_matcher) (SYMBOL_NATURAL_NAME (*psym), data))
- {
- PSYMTAB_TO_SYMTAB (ps);
- keep_going = 0;
- }
+ /* Found a match, so notify our caller. */
+ result = PST_SEARCHED_AND_FOUND;
+ keep_going = 0;
}
- psym++;
}
+ psym++;
+ }
+
+ ps->searched_flag = result;
+ return result == PST_SEARCHED_AND_FOUND;
+}
+
+static void
+expand_symtabs_matching_via_partial
+ (struct objfile *objfile,
+ int (*file_matcher) (const char *, void *),
+ int (*name_matcher) (const char *, void *),
+ enum search_domain kind,
+ void *data)
+{
+ struct partial_symtab *ps;
+
+ /* Clear the search flags. */
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
+ {
+ ps->searched_flag = PST_NOT_SEARCHED;
+ }
+
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
+ {
+ if (ps->readin)
+ continue;
+
+ /* We skip shared psymtabs because file-matching doesn't apply
+ to them; but we search them later in the loop. */
+ if (ps->user != NULL)
+ continue;
+
+ if (file_matcher)
+ {
+ if (ps->anonymous)
+ continue;
+ if (! (*file_matcher) (ps->filename, data))
+ continue;
+ }
+
+ if (recursively_search_psymtabs (ps, objfile, kind, name_matcher, data))
+ psymtab_to_symtab (objfile, ps);
}
}
objfile_has_psyms,
find_last_source_symtab_from_partial,
forget_cached_source_info_partial,
- lookup_symtab_via_partial_symtab,
+ 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,
}
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);
}
Since one arg is a struct, we pass in a ptr and deref it (sigh).
Return the partial symbol that has been added. */
-/* NOTE: carlton/2003-09-11: The reason why we return the partial
- symbol is so that callers can get access to the symbol's demangled
- name, which they don't have any cheap way to determine otherwise.
- (Currenly, dwarf2read.c is the only file who uses that information,
- though it's possible that other readers might in the future.)
- Elena wasn't thrilled about that, and I don't blame her, but we
- couldn't come up with a better way to get that information. If
- it's needed in other situations, we could consider breaking up
- SYMBOL_SET_NAMES to provide access to the demangled name lookup
- cache. */
-
-const struct partial_symbol *
+void
add_psymbol_to_list (const char *name, int namelength, int copy_name,
domain_enum domain,
enum address_class class,
/* Do not duplicate global partial symbols. */
if (list == &objfile->global_psymbols
&& !added)
- return psym;
+ return;
/* Save pointer to partial symbol in psymtab, growing symtab if needed. */
append_psymbol_to_list (list, psym, objfile);
- return psym;
}
/* Initialize storage for partial 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;
Psymtabs are searched in most recent inserted -> least recent
inserted order. */
- psymtab->objfile = objfile;
psymtab->next = objfile->psymtabs;
objfile->psymtabs = psymtab;
+ if (symtab_create_debug)
+ {
+ /* Be a bit clever with debugging messages, and don't print objfile
+ every time, only when it changes. */
+ static char *last_objfile_name = NULL;
+
+ if (last_objfile_name == NULL
+ || strcmp (last_objfile_name, objfile->name) != 0)
+ {
+ xfree (last_objfile_name);
+ last_objfile_name = xstrdup (objfile->name);
+ fprintf_unfiltered (gdb_stdlog,
+ "Creating one or more psymtabs for objfile %s ...\n",
+ last_objfile_name);
+ }
+ fprintf_unfiltered (gdb_stdlog,
+ "Created psymtab %s for module %s.\n",
+ host_address_to_string (psymtab), filename);
+ }
+
return (psymtab);
}
void
-discard_psymtab (struct partial_symtab *pst)
+discard_psymtab (struct objfile *objfile, struct partial_symtab *pst)
{
struct partial_symtab **prev_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);
}
\f
-void
+static void
maintenance_print_psymbols (char *args, int from_tty)
{
char **argv;
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;
fputs_filtered (paddress (gdbarch, psymtab->texthigh),
gdb_stdout);
printf_filtered ("\n");
+ printf_filtered (" psymtabs_addrmap_supported %s\n",
+ (psymtab->psymtabs_addrmap_supported
+ ? "yes" : "no"));
printf_filtered (" globals ");
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);
}
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);
}
/* Check consistency of psymtabs and symtabs. */
-void
+static void
maintenance_check_symtabs (char *ignore, int from_tty)
{
struct symbol *sym;
{
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- s = PSYMTAB_TO_SYMTAB (ps);
+ s = psymtab_to_symtab (objfile, ps);
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--)
{
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--)
{
\f
void
-expand_partial_symbol_names (int (*fun) (const char *, void *), void *data)
+expand_partial_symbol_names (int (*fun) (const char *, void *),
+ void *data)
{
struct objfile *objfile;
}
void
-map_partial_symbol_filenames (symbol_filename_ftype *fun, void *data)
+map_partial_symbol_filenames (symbol_filename_ftype *fun, void *data,
+ int need_fullname)
{
struct objfile *objfile;
ALL_OBJFILES (objfile)
{
if (objfile->sf)
- objfile->sf->qf->map_symbol_filenames (objfile, fun, data);
+ objfile->sf->qf->map_symbol_filenames (objfile, fun, 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-symtabs", class_maintenance, maintenance_check_symtabs,
+ _("Check consistency of psymtabs and symtabs."),
+ &maintenancelist);
+}