* psymtab.c (partial_map_expand_apply): Add assertion.
(partial_map_symtabs_matching_filename): Skip included psymtabs. (psymtab_to_symtab): Find unshared psymtab. (dump_psymtab): Print including psymtabs. (recursively_search_psymtabs): New function. (expand_symtabs_matching_via_partial): Use it. * psympriv.h (struct partial_symtab) <user, searched_flag>: New fields. (enum psymtab_search_status): New.
This commit is contained in:
parent
8157b174fd
commit
9439a077be
3 changed files with 176 additions and 45 deletions
|
@ -1,3 +1,15 @@
|
|||
2012-05-10 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* psymtab.c (partial_map_expand_apply): Add assertion.
|
||||
(partial_map_symtabs_matching_filename): Skip included psymtabs.
|
||||
(psymtab_to_symtab): Find unshared psymtab.
|
||||
(dump_psymtab): Print including psymtabs.
|
||||
(recursively_search_psymtabs): New function.
|
||||
(expand_symtabs_matching_via_partial): Use it.
|
||||
* psympriv.h (struct partial_symtab) <user, searched_flag>: New
|
||||
fields.
|
||||
(enum psymtab_search_status): New.
|
||||
|
||||
2012-05-10 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* tracepoint.c (scope_info): Update.
|
||||
|
|
|
@ -54,6 +54,17 @@ struct partial_symbol
|
|||
#define PSYMBOL_DOMAIN(psymbol) (psymbol)->domain
|
||||
#define PSYMBOL_CLASS(psymbol) (psymbol)->aclass
|
||||
|
||||
/* A convenience enum to give names to some constants used when
|
||||
searching psymtabs. This is internal to psymtab and should not be
|
||||
used elsewhere. */
|
||||
|
||||
enum psymtab_search_status
|
||||
{
|
||||
PST_NOT_SEARCHED,
|
||||
PST_SEARCHED_AND_FOUND,
|
||||
PST_SEARCHED_AND_NOT_FOUND
|
||||
};
|
||||
|
||||
/* Each source file that has not been fully read in is represented by
|
||||
a partial_symtab. This contains the information on where in the
|
||||
executable the debugging symbols for a specific file are, and a
|
||||
|
@ -111,6 +122,35 @@ struct partial_symtab
|
|||
|
||||
int number_of_dependencies;
|
||||
|
||||
/* If NULL, this is an ordinary partial symbol table.
|
||||
|
||||
If non-NULL, this holds a single includer of this partial symbol
|
||||
table, and this partial symbol table is a shared one.
|
||||
|
||||
A shared psymtab is one that is referenced by multiple other
|
||||
psymtabs, and which conceptually has its contents directly
|
||||
included in those.
|
||||
|
||||
Shared psymtabs have special semantics. When a search finds a
|
||||
symbol in a shared table, we instead return one of the non-shared
|
||||
tables that include this one.
|
||||
|
||||
A shared psymtabs can be referred to by other shared ones.
|
||||
|
||||
The psymtabs that refer to a shared psymtab will list the shared
|
||||
psymtab in their 'dependencies' array.
|
||||
|
||||
In DWARF terms, a shared psymtab is a DW_TAG_partial_unit; but
|
||||
of course using a name based on that would be too confusing, so
|
||||
"shared" was chosen instead.
|
||||
|
||||
Only a single user is needed because, when expanding a shared
|
||||
psymtab, we only need to expand its "canonical" non-shared user.
|
||||
The choice of which one should be canonical is left to the
|
||||
debuginfo reader; it can be arbitrary. */
|
||||
|
||||
struct partial_symtab *user;
|
||||
|
||||
/* Global symbol list. This list will be sorted after readin to
|
||||
improve access. Binary search will be the usual method of
|
||||
finding a symbol within it. globals_offset is an integer offset
|
||||
|
@ -142,6 +182,10 @@ struct partial_symtab
|
|||
|
||||
unsigned char psymtabs_addrmap_supported;
|
||||
|
||||
/* A flag that is temporarily used when searching psymtabs. */
|
||||
|
||||
ENUM_BITFIELD (psymtab_search_status) searched_flag : 2;
|
||||
|
||||
/* Pointer to symtab eventually allocated for this source file, 0 if
|
||||
!readin or if we haven't looked for the symtab after it was readin. */
|
||||
|
||||
|
|
165
gdb/psymtab.c
165
gdb/psymtab.c
|
@ -135,6 +135,10 @@ partial_map_expand_apply (struct objfile *objfile,
|
|||
{
|
||||
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;
|
||||
|
@ -165,6 +169,11 @@ partial_map_symtabs_matching_filename (struct objfile *objfile,
|
|||
|
||||
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
|
||||
{
|
||||
/* We can skip shared psymtabs here, because any file name will be
|
||||
attached to the unshared psymtab. */
|
||||
if (pst->user != NULL)
|
||||
continue;
|
||||
|
||||
if (FILENAME_CMP (name, pst->filename) == 0
|
||||
|| (!is_abs && compare_filenames_for_search (pst->filename,
|
||||
name, name_len)))
|
||||
|
@ -760,6 +769,11 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
|
|||
static struct symtab *
|
||||
psymtab_to_symtab (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;
|
||||
|
@ -1000,6 +1014,12 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
|
|||
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,
|
||||
|
@ -1236,6 +1256,94 @@ map_matching_symbols_psymtab (const char *name, domain_enum namespace,
|
|||
}
|
||||
}
|
||||
|
||||
/* 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_symbol **psym;
|
||||
struct partial_symbol **bound, **gbound, **sbound;
|
||||
int keep_going = 1;
|
||||
int result = PST_SEARCHED_AND_NOT_FOUND;
|
||||
int i;
|
||||
|
||||
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)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* Skip non-shared dependencies, these are handled elsewhere. */
|
||||
if (ps->dependencies[i]->user == NULL)
|
||||
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;
|
||||
|
||||
/* 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 (bound == gbound && ps->n_static_syms != 0)
|
||||
{
|
||||
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))
|
||||
{
|
||||
/* Found a match, so notify our caller. */
|
||||
result = PST_SEARCHED_AND_FOUND;
|
||||
keep_going = 0;
|
||||
}
|
||||
}
|
||||
psym++;
|
||||
}
|
||||
|
||||
ps->searched_flag = result;
|
||||
return result == PST_SEARCHED_AND_FOUND;
|
||||
}
|
||||
|
||||
static void
|
||||
expand_symtabs_matching_via_partial
|
||||
(struct objfile *objfile,
|
||||
|
@ -1246,60 +1354,27 @@ expand_symtabs_matching_via_partial
|
|||
{
|
||||
struct partial_symtab *ps;
|
||||
|
||||
/* Clear the search flags. */
|
||||
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
|
||||
{
|
||||
struct partial_symbol **psym;
|
||||
struct partial_symbol **bound, **gbound, **sbound;
|
||||
int keep_going = 1;
|
||||
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 && ! (*file_matcher) (ps->filename, data))
|
||||
continue;
|
||||
|
||||
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)
|
||||
{
|
||||
if (psym >= bound)
|
||||
{
|
||||
if (bound == gbound && ps->n_static_syms != 0)
|
||||
{
|
||||
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))
|
||||
{
|
||||
psymtab_to_symtab (ps);
|
||||
keep_going = 0;
|
||||
}
|
||||
}
|
||||
psym++;
|
||||
}
|
||||
if (recursively_search_psymtabs (ps, objfile, kind, name_matcher, data))
|
||||
psymtab_to_symtab (ps);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue