2010-01-06 Tristan Gingold <gingold@adacore.com>

* symtab.c (lookup_global_symbol_from_objfile): Rename objfile
	parameter to main_objfile.  Iterate on all separate debug objfiles.
	* symfile.h (symbol_file_add_separate)
	(find_separate_debug_file_by_debuglink): Remove parameter names.
	* symfile.c (symbol_file_add_separate): Use add_separate_objfile.
	(reread_symbols): Use free_objfile_separate_debug.
	* objfiles.h (struct objfile): Add separate_debug_objfile_link.
	Adjust comment.
	(objfile_separate_debug_iterate, add_separate_debug_objfile)
	(free_objfile_separate_debug): New prototypes.
	* objfiles.c (objfile_separate_debug_iterate): New function.
	(add_separate_debug_objfile, free_objfile_separate_debug): New
	functions.
	(free_objfile): Use free_objfile_separate_debug.  Adjust for
	multiple separate debug objfile.
	(objfile_has_symbols): Adjust comment.  Iterate on all separate
	debug objfiles.
	* minsyms.c (lookup_minimal_symbol): Adjust for multiple separate
	debug objfile.
	(lookup_minimal_symbol_text): Ditto.
	(lookup_minimal_symbol_by_pc_name): Ditto.
	(lookup_minimal_symbol_solib_trampoline): Ditto.
	(lookup_minimal_symbol_by_pc_section_1): Iterate on all separate
	debug objfiles.
This commit is contained in:
Tristan Gingold 2010-01-06 10:11:04 +00:00
parent d2ca6b5b42
commit 15d123c99f
7 changed files with 199 additions and 82 deletions

View File

@ -1,3 +1,30 @@
2010-01-06 Tristan Gingold <gingold@adacore.com>
* symtab.c (lookup_global_symbol_from_objfile): Rename objfile
parameter to main_objfile. Iterate on all separate debug objfiles.
* symfile.h (symbol_file_add_separate)
(find_separate_debug_file_by_debuglink): Remove parameter names.
* symfile.c (symbol_file_add_separate): Use add_separate_objfile.
(reread_symbols): Use free_objfile_separate_debug.
* objfiles.h (struct objfile): Add separate_debug_objfile_link.
Adjust comment.
(objfile_separate_debug_iterate, add_separate_debug_objfile)
(free_objfile_separate_debug): New prototypes.
* objfiles.c (objfile_separate_debug_iterate): New function.
(add_separate_debug_objfile, free_objfile_separate_debug): New
functions.
(free_objfile): Use free_objfile_separate_debug. Adjust for
multiple separate debug objfile.
(objfile_has_symbols): Adjust comment. Iterate on all separate
debug objfiles.
* minsyms.c (lookup_minimal_symbol): Adjust for multiple separate
debug objfile.
(lookup_minimal_symbol_text): Ditto.
(lookup_minimal_symbol_by_pc_name): Ditto.
(lookup_minimal_symbol_solib_trampoline): Ditto.
(lookup_minimal_symbol_by_pc_section_1): Iterate on all separate
debug objfiles.
2010-01-05 Stan Shebs <stan@codesourcery.com> 2010-01-05 Stan Shebs <stan@codesourcery.com>
Add fast tracepoints. Add fast tracepoints.

View File

@ -216,7 +216,7 @@ lookup_minimal_symbol (const char *name, const char *sfile,
objfile = objfile->next) objfile = objfile->next)
{ {
if (objf == NULL || objf == objfile if (objf == NULL || objf == objfile
|| objf->separate_debug_objfile == objfile) || objf == objfile->separate_debug_objfile_backlink)
{ {
/* Do two passes: the first over the ordinary hash table, /* Do two passes: the first over the ordinary hash table,
and the second over the demangled hash table. */ and the second over the demangled hash table. */
@ -324,7 +324,7 @@ lookup_minimal_symbol_text (const char *name, struct objfile *objf)
objfile = objfile->next) objfile = objfile->next)
{ {
if (objf == NULL || objf == objfile if (objf == NULL || objf == objfile
|| objf->separate_debug_objfile == objfile) || objf == objfile->separate_debug_objfile_backlink)
{ {
for (msymbol = objfile->msymbol_hash[hash]; for (msymbol = objfile->msymbol_hash[hash];
msymbol != NULL && found_symbol == NULL; msymbol != NULL && found_symbol == NULL;
@ -377,7 +377,7 @@ lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name,
objfile = objfile->next) objfile = objfile->next)
{ {
if (objf == NULL || objf == objfile if (objf == NULL || objf == objfile
|| objf->separate_debug_objfile == objfile) || objf == objfile->separate_debug_objfile_backlink)
{ {
for (msymbol = objfile->msymbol_hash[hash]; for (msymbol = objfile->msymbol_hash[hash];
msymbol != NULL; msymbol != NULL;
@ -416,7 +416,7 @@ lookup_minimal_symbol_solib_trampoline (const char *name,
objfile = objfile->next) objfile = objfile->next)
{ {
if (objf == NULL || objf == objfile if (objf == NULL || objf == objfile
|| objf->separate_debug_objfile == objfile) || objf == objfile->separate_debug_objfile_backlink)
{ {
for (msymbol = objfile->msymbol_hash[hash]; for (msymbol = objfile->msymbol_hash[hash];
msymbol != NULL && found_symbol == NULL; msymbol != NULL && found_symbol == NULL;
@ -473,11 +473,10 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
no telling which one will have the minimal symbols. */ no telling which one will have the minimal symbols. */
gdb_assert (section != NULL); gdb_assert (section != NULL);
objfile = section->objfile;
if (objfile->separate_debug_objfile)
objfile = objfile->separate_debug_objfile;
for (; objfile != NULL; objfile = objfile->separate_debug_objfile_backlink) for (objfile = section->objfile;
objfile != NULL;
objfile = objfile_separate_debug_iterate (section->objfile, objfile))
{ {
/* If this objfile has a minimal symbol table, go search it using /* If this objfile has a minimal symbol table, go search it using
a binary search. Note that a minimal symbol table always consists a binary search. Note that a minimal symbol table always consists

View File

@ -378,6 +378,42 @@ terminate_minimal_symbol_table (struct objfile *objfile)
} }
} }
/* Iterator on PARENT and every separate debug objfile of PARENT.
The usage pattern is:
for (objfile = parent;
objfile;
objfile = objfile_separate_debug_iterate (parent, objfile))
...
*/
struct objfile *
objfile_separate_debug_iterate (const struct objfile *parent,
const struct objfile *objfile)
{
struct objfile *res;
res = objfile->separate_debug_objfile;
if (res)
return res;
res = objfile->separate_debug_objfile_link;
if (res)
return res;
/* Common case where there is no separate debug objfile. */
if (objfile == parent)
return NULL;
for (res = objfile->separate_debug_objfile_backlink;
res != parent;
res = res->separate_debug_objfile_backlink)
{
gdb_assert (res != NULL);
if (res->separate_debug_objfile_link)
return res->separate_debug_objfile_link;
}
return NULL;
}
/* Put one object file before a specified on in the global list. /* Put one object file before a specified on in the global list.
This can be used to make sure an object file is destroyed before This can be used to make sure an object file is destroyed before
@ -455,6 +491,41 @@ unlink_objfile (struct objfile *objfile)
_("unlink_objfile: objfile already unlinked")); _("unlink_objfile: objfile already unlinked"));
} }
/* Add OBJFILE as a separate debug objfile of PARENT. */
void
add_separate_debug_objfile (struct objfile *objfile, struct objfile *parent)
{
gdb_assert (objfile && parent);
/* Must not be already in a list. */
gdb_assert (objfile->separate_debug_objfile_backlink == NULL);
gdb_assert (objfile->separate_debug_objfile_link == NULL);
objfile->separate_debug_objfile_backlink = parent;
objfile->separate_debug_objfile_link = parent->separate_debug_objfile;
parent->separate_debug_objfile = objfile;
/* Put the separate debug object before the normal one, this is so that
usage of the ALL_OBJFILES_SAFE macro will stay safe. */
put_objfile_before (objfile, parent);
}
/* Free all separate debug objfile of OBJFILE, but don't free OBJFILE
itself. */
void
free_objfile_separate_debug (struct objfile *objfile)
{
struct objfile *child;
for (child = objfile->separate_debug_objfile; child;)
{
struct objfile *next_child = child->separate_debug_objfile_link;
free_objfile (child);
child = next_child;
}
}
/* Destroy an objfile and all the symtabs and psymtabs under it. Note /* Destroy an objfile and all the symtabs and psymtabs under it. Note
that as much as possible is allocated on the objfile_obstack that as much as possible is allocated on the objfile_obstack
@ -475,16 +546,38 @@ unlink_objfile (struct objfile *objfile)
void void
free_objfile (struct objfile *objfile) free_objfile (struct objfile *objfile)
{ {
if (objfile->separate_debug_objfile) /* Free all separate debug objfiles. */
{ free_objfile_separate_debug (objfile);
free_objfile (objfile->separate_debug_objfile);
}
if (objfile->separate_debug_objfile_backlink) if (objfile->separate_debug_objfile_backlink)
{ {
/* We freed the separate debug file, make sure the base objfile /* We freed the separate debug file, make sure the base objfile
doesn't reference it. */ doesn't reference it. */
objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL; struct objfile *child;
child = objfile->separate_debug_objfile_backlink->separate_debug_objfile;
if (child == objfile)
{
/* OBJFILE is the first child. */
objfile->separate_debug_objfile_backlink->separate_debug_objfile =
objfile->separate_debug_objfile_link;
}
else
{
/* Find OBJFILE in the list. */
while (1)
{
if (child->separate_debug_objfile_link == objfile)
{
child->separate_debug_objfile_link =
objfile->separate_debug_objfile_link;
break;
}
child = child->separate_debug_objfile_link;
gdb_assert (child);
}
}
} }
/* Remove any references to this objfile in the global value /* Remove any references to this objfile in the global value
@ -778,25 +871,16 @@ objfile_has_full_symbols (struct objfile *objfile)
} }
/* Return non-zero if OBJFILE has full or partial symbols, either directly /* Return non-zero if OBJFILE has full or partial symbols, either directly
or throught its separate debug file. */ or through a separate debug file. */
int int
objfile_has_symbols (struct objfile *objfile) objfile_has_symbols (struct objfile *objfile)
{ {
struct objfile *separate_objfile; struct objfile *o;
if (objfile_has_partial_symbols (objfile) for (o = objfile; o; o = objfile_separate_debug_iterate (objfile, o))
|| objfile_has_full_symbols (objfile)) if (objfile_has_partial_symbols (o) || objfile_has_full_symbols (o))
return 1; return 1;
separate_objfile = objfile->separate_debug_objfile;
if (separate_objfile == NULL)
return 0;
if (objfile_has_partial_symbols (separate_objfile)
|| objfile_has_full_symbols (separate_objfile))
return 1;
return 0; return 0;
} }

View File

@ -363,15 +363,25 @@ struct objfile
struct obj_section struct obj_section
*sections, *sections_end; *sections, *sections_end;
/* Link to objfile that contains the debug symbols for this one. /* GDB allows to have debug symbols in separate object files. This is
One is loaded if this file has an debug link to an existing used by .gnu_debuglink, ELF build id note and Mach-O OSO.
debug file with the right checksum */ Although this is a tree structure, GDB only support one level
(ie a separate debug for a separate debug is not supported). Note that
separate debug object are in the main chain and therefore will be
visited by ALL_OBJFILES & co iterators. Separate debug objfile always
has a non-nul separate_debug_objfile_backlink. */
/* Link to the first separate debug object, if any. */
struct objfile *separate_debug_objfile; struct objfile *separate_debug_objfile;
/* If this is a separate debug object, this is used as a link to the /* If this is a separate debug object, this is used as a link to the
actual executable objfile. */ actual executable objfile. */
struct objfile *separate_debug_objfile_backlink; struct objfile *separate_debug_objfile_backlink;
/* If this is a separate debug object, this is a link to the next one
for the same executable objfile. */
struct objfile *separate_debug_objfile_link;
/* Place to stash various statistics about this objfile */ /* Place to stash various statistics about this objfile */
OBJSTATS; OBJSTATS;
@ -452,14 +462,21 @@ extern int build_objfile_section_table (struct objfile *);
extern void terminate_minimal_symbol_table (struct objfile *objfile); extern void terminate_minimal_symbol_table (struct objfile *objfile);
extern struct objfile *objfile_separate_debug_iterate (const struct objfile *,
const struct objfile *);
extern void put_objfile_before (struct objfile *, struct objfile *); extern void put_objfile_before (struct objfile *, struct objfile *);
extern void objfile_to_front (struct objfile *); extern void objfile_to_front (struct objfile *);
extern void add_separate_debug_objfile (struct objfile *, struct objfile *);
extern void unlink_objfile (struct objfile *); extern void unlink_objfile (struct objfile *);
extern void free_objfile (struct objfile *); extern void free_objfile (struct objfile *);
extern void free_objfile_separate_debug (struct objfile *);
extern struct cleanup *make_cleanup_free_objfile (struct objfile *); extern struct cleanup *make_cleanup_free_objfile (struct objfile *);
extern void free_all_objfiles (void); extern void free_all_objfiles (void);

View File

@ -1042,22 +1042,16 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd,
void void
symbol_file_add_separate (bfd *bfd, int symfile_flags, struct objfile *objfile) symbol_file_add_separate (bfd *bfd, int symfile_flags, struct objfile *objfile)
{ {
/* Currently only one separate debug objfile is supported. */ struct objfile *new_objfile;
gdb_assert (objfile && objfile->separate_debug_objfile == NULL);
objfile->separate_debug_objfile = new_objfile = symbol_file_add_with_addrs_or_offsets
symbol_file_add_with_addrs_or_offsets
(bfd, symfile_flags, (bfd, symfile_flags,
0, /* No addr table. */ 0, /* No addr table. */
objfile->section_offsets, objfile->num_sections, objfile->section_offsets, objfile->num_sections,
objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW
| OBJF_USERLOADED)); | OBJF_USERLOADED));
objfile->separate_debug_objfile->separate_debug_objfile_backlink
= objfile;
/* Put the separate debug object before the normal one, this is so that add_separate_debug_objfile (new_objfile, objfile);
usage of the ALL_OBJFILES_SAFE macro will stay safe. */
put_objfile_before (objfile->separate_debug_objfile, objfile);
} }
/* Process the symbol file ABFD, as either the main file or as a /* Process the symbol file ABFD, as either the main file or as a
@ -2272,14 +2266,9 @@ reread_symbols (void)
clear_objfile_data (objfile); clear_objfile_data (objfile);
/* Free the separate debug objfile if there is one. It will be /* Free the separate debug objfiles. It will be
automatically recreated by sym_read. */ automatically recreated by sym_read. */
if (objfile->separate_debug_objfile) free_objfile_separate_debug (objfile);
{
/* Note: no need to clear separate_debug_objfile field as it is
done by free_objfile. */
free_objfile (objfile->separate_debug_objfile);
}
/* FIXME: Do we have to free a whole linked list, or is this /* FIXME: Do we have to free a whole linked list, or is this
enough? */ enough? */

View File

@ -238,10 +238,9 @@ extern struct objfile *symbol_file_add_from_bfd (bfd *, int,
struct section_addr_info *, struct section_addr_info *,
int); int);
extern void symbol_file_add_separate (bfd *bfd, int symfile_flags, extern void symbol_file_add_separate (bfd *, int, struct objfile *);
struct objfile *objfile);
extern char *find_separate_debug_file_by_debuglink (struct objfile *objfile); extern char *find_separate_debug_file_by_debuglink (struct objfile *);
/* Create a new section_addr_info, with room for NUM_SECTIONS. */ /* Create a new section_addr_info, with room for NUM_SECTIONS. */

View File

@ -1499,17 +1499,22 @@ lookup_symbol_aux_block (const char *name, const char *linkage_name,
psymtabs. */ psymtabs. */
struct symbol * struct symbol *
lookup_global_symbol_from_objfile (const struct objfile *objfile, lookup_global_symbol_from_objfile (const struct objfile *main_objfile,
const char *name, const char *name,
const char *linkage_name, const char *linkage_name,
const domain_enum domain) const domain_enum domain)
{ {
const struct objfile *objfile;
struct symbol *sym; struct symbol *sym;
struct blockvector *bv; struct blockvector *bv;
const struct block *block; const struct block *block;
struct symtab *s; struct symtab *s;
struct partial_symtab *ps; struct partial_symtab *ps;
for (objfile = main_objfile;
objfile;
objfile = objfile_separate_debug_iterate (main_objfile, objfile))
{
/* Go through symtabs. */ /* Go through symtabs. */
ALL_OBJFILE_SYMTABS (objfile, s) ALL_OBJFILE_SYMTABS (objfile, s)
{ {
@ -1537,10 +1542,7 @@ lookup_global_symbol_from_objfile (const struct objfile *objfile,
return fixup_symbol_section (sym, (struct objfile *)objfile); return fixup_symbol_section (sym, (struct objfile *)objfile);
} }
} }
}
if (objfile->separate_debug_objfile)
return lookup_global_symbol_from_objfile (objfile->separate_debug_objfile,
name, linkage_name, domain);
return NULL; return NULL;
} }