+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>
Add fast tracepoints.
objfile = objfile->next)
{
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,
and the second over the demangled hash table. */
objfile = objfile->next)
{
if (objf == NULL || objf == objfile
- || objf->separate_debug_objfile == objfile)
+ || objf == objfile->separate_debug_objfile_backlink)
{
for (msymbol = objfile->msymbol_hash[hash];
msymbol != NULL && found_symbol == NULL;
objfile = objfile->next)
{
if (objf == NULL || objf == objfile
- || objf->separate_debug_objfile == objfile)
+ || objf == objfile->separate_debug_objfile_backlink)
{
for (msymbol = objfile->msymbol_hash[hash];
msymbol != NULL;
objfile = objfile->next)
{
if (objf == NULL || objf == objfile
- || objf->separate_debug_objfile == objfile)
+ || objf == objfile->separate_debug_objfile_backlink)
{
for (msymbol = objfile->msymbol_hash[hash];
msymbol != NULL && found_symbol == NULL;
no telling which one will have the minimal symbols. */
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
a binary search. Note that a minimal symbol table always consists
}
}
+/* 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.
This can be used to make sure an object file is destroyed before
_("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
that as much as possible is allocated on the objfile_obstack
void
free_objfile (struct objfile *objfile)
{
- if (objfile->separate_debug_objfile)
- {
- free_objfile (objfile->separate_debug_objfile);
- }
-
+ /* Free all separate debug objfiles. */
+ free_objfile_separate_debug (objfile);
+
if (objfile->separate_debug_objfile_backlink)
{
/* We freed the separate debug file, make sure the base objfile
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
}
/* 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
objfile_has_symbols (struct objfile *objfile)
{
- struct objfile *separate_objfile;
-
- if (objfile_has_partial_symbols (objfile)
- || objfile_has_full_symbols (objfile))
- 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;
+ struct objfile *o;
+ for (o = objfile; o; o = objfile_separate_debug_iterate (objfile, o))
+ if (objfile_has_partial_symbols (o) || objfile_has_full_symbols (o))
+ return 1;
return 0;
}
struct obj_section
*sections, *sections_end;
- /* Link to objfile that contains the debug symbols for this one.
- One is loaded if this file has an debug link to an existing
- debug file with the right checksum */
+ /* GDB allows to have debug symbols in separate object files. This is
+ used by .gnu_debuglink, ELF build id note and Mach-O OSO.
+ 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;
/* If this is a separate debug object, this is used as a link to the
actual executable objfile. */
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 */
OBJSTATS;
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 objfile_to_front (struct objfile *);
+extern void add_separate_debug_objfile (struct objfile *, struct objfile *);
+
extern void unlink_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 void free_all_objfiles (void);
void
symbol_file_add_separate (bfd *bfd, int symfile_flags, struct objfile *objfile)
{
- /* Currently only one separate debug objfile is supported. */
- gdb_assert (objfile && objfile->separate_debug_objfile == NULL);
+ struct objfile *new_objfile;
- objfile->separate_debug_objfile =
- symbol_file_add_with_addrs_or_offsets
+ new_objfile = symbol_file_add_with_addrs_or_offsets
(bfd, symfile_flags,
0, /* No addr table. */
objfile->section_offsets, objfile->num_sections,
objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW
| OBJF_USERLOADED));
- objfile->separate_debug_objfile->separate_debug_objfile_backlink
- = 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->separate_debug_objfile, objfile);
+ add_separate_debug_objfile (new_objfile, objfile);
}
/* Process the symbol file ABFD, as either the main file or as a
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. */
- if (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);
- }
+ free_objfile_separate_debug (objfile);
/* FIXME: Do we have to free a whole linked list, or is this
enough? */
struct section_addr_info *,
int);
-extern void symbol_file_add_separate (bfd *bfd, int symfile_flags,
- struct objfile *objfile);
+extern void symbol_file_add_separate (bfd *, int, struct 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. */
psymtabs. */
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 *linkage_name,
const domain_enum domain)
{
+ const struct objfile *objfile;
struct symbol *sym;
struct blockvector *bv;
const struct block *block;
struct symtab *s;
struct partial_symtab *ps;
- /* Go through symtabs. */
- ALL_OBJFILE_SYMTABS (objfile, s)
- {
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, linkage_name, domain);
- if (sym)
- {
- block_found = block;
- return fixup_symbol_section (sym, (struct objfile *)objfile);
- }
- }
-
- /* Now go through psymtabs. */
- ALL_OBJFILE_PSYMTABS (objfile, ps)
- {
- if (!ps->readin
- && lookup_partial_symbol (ps, name, linkage_name,
- 1, domain))
- {
- s = PSYMTAB_TO_SYMTAB (ps);
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, linkage_name, domain);
- 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);
+ for (objfile = main_objfile;
+ objfile;
+ objfile = objfile_separate_debug_iterate (main_objfile, objfile))
+ {
+ /* Go through symtabs. */
+ ALL_OBJFILE_SYMTABS (objfile, s)
+ {
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
+ if (sym)
+ {
+ block_found = block;
+ return fixup_symbol_section (sym, (struct objfile *)objfile);
+ }
+ }
+
+ /* Now go through psymtabs. */
+ ALL_OBJFILE_PSYMTABS (objfile, ps)
+ {
+ if (!ps->readin
+ && lookup_partial_symbol (ps, name, linkage_name,
+ 1, domain))
+ {
+ s = PSYMTAB_TO_SYMTAB (ps);
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
+ return fixup_symbol_section (sym, (struct objfile *)objfile);
+ }
+ }
+ }
return NULL;
}