diff options
-rw-r--r-- | gdb/ChangeLog | 27 | ||||
-rw-r--r-- | gdb/minsyms.c | 15 | ||||
-rw-r--r-- | gdb/objfiles.c | 124 | ||||
-rw-r--r-- | gdb/objfiles.h | 25 | ||||
-rw-r--r-- | gdb/symfile.c | 21 | ||||
-rw-r--r-- | gdb/symfile.h | 5 | ||||
-rw-r--r-- | gdb/symtab.c | 66 |
7 files changed, 200 insertions, 83 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 74aba43..3f12d05 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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> Add fast tracepoints. diff --git a/gdb/minsyms.c b/gdb/minsyms.c index c177c02..ee730a4 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -216,7 +216,7 @@ lookup_minimal_symbol (const char *name, const char *sfile, 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. */ @@ -324,7 +324,7 @@ lookup_minimal_symbol_text (const char *name, struct objfile *objf) 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; @@ -377,7 +377,7 @@ lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name, 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; @@ -416,7 +416,7 @@ lookup_minimal_symbol_solib_trampoline (const char *name, 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; @@ -473,11 +473,10 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, 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 diff --git a/gdb/objfiles.c b/gdb/objfiles.c index c241e8f..9f779a4 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -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. 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")); } +/* 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 @@ -475,16 +546,38 @@ unlink_objfile (struct objfile *objfile) 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 @@ -778,25 +871,16 @@ objfile_has_full_symbols (struct objfile *objfile) } /* 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; } diff --git a/gdb/objfiles.h b/gdb/objfiles.h index cf5fc38..c689622 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -363,15 +363,25 @@ struct objfile 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; @@ -452,14 +462,21 @@ extern int build_objfile_section_table (struct 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 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); diff --git a/gdb/symfile.c b/gdb/symfile.c index fe91fb6..91b7870 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -1042,22 +1042,16 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, 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 @@ -2272,14 +2266,9 @@ reread_symbols (void) 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? */ diff --git a/gdb/symfile.h b/gdb/symfile.h index 8eb1b5e..f9c4daa 100644 --- a/gdb/symfile.h +++ b/gdb/symfile.h @@ -238,10 +238,9 @@ extern struct objfile *symbol_file_add_from_bfd (bfd *, int, 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. */ diff --git a/gdb/symtab.c b/gdb/symtab.c index d7b8145..7f5dabd 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -1499,48 +1499,50 @@ lookup_symbol_aux_block (const char *name, const char *linkage_name, 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; } |