aboutsummaryrefslogtreecommitdiff
path: root/gdb/symtab.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2019-06-25 12:50:45 -0600
committerTom Tromey <tromey@adacore.com>2019-10-02 09:53:17 -0600
commit4b610737f02338b2aea7641ab771aa5e137d067c (patch)
treea29d17f55e269ad24027060bb9fb0bdf40cd3b67 /gdb/symtab.c
parent1dd588507782591478882a891f64945af9e2b86c (diff)
downloadgdb-4b610737f02338b2aea7641ab771aa5e137d067c.zip
gdb-4b610737f02338b2aea7641ab771aa5e137d067c.tar.gz
gdb-4b610737f02338b2aea7641ab771aa5e137d067c.tar.bz2
Handle copy relocations
In ELF, if a data symbol is defined in a shared library and used by the main program, it will be subject to a "copy relocation". In this scenario, the main program has a copy of the symbol in question, and a relocation that tells ld.so to copy the data from the shared library. Then the symbol in the main program is used to satisfy all references. This patch changes gdb to handle this scenario. Data symbols coming from ELF shared libraries get a special flag that indicates that the symbol's address may be subject to copy relocation. I looked briefly into handling copy relocations by looking at the actual relocations in the main program, but this seemed difficult to do with BFD. Note that no caching is done here. Perhaps this could be changed if need be; I wanted to avoid possible problems with either objfile lifetimes and changes, or conflicts with the long-term (vapor-ware) objfile splitting project. gdb/ChangeLog 2019-10-02 Tom Tromey <tromey@adacore.com> * symmisc.c (dump_msymbols): Don't use MSYMBOL_VALUE_ADDRESS. * ada-lang.c (lesseq_defined_than): Handle LOC_STATIC. * dwarf2read.c (dwarf2_per_objfile): Add can_copy parameter. (dwarf2_has_info): Likewise. (new_symbol): Set maybe_copied on symbol when appropriate. * dwarf2read.h (dwarf2_per_objfile): Add can_copy parameter. <can_copy>: New member. * elfread.c (record_minimal_symbol): Set maybe_copied on symbol when appropriate. (elf_symfile_read): Update call to dwarf2_has_info. * minsyms.c (lookup_minimal_symbol_linkage): New function. * minsyms.h (lookup_minimal_symbol_linkage): Declare. * symtab.c (get_symbol_address, get_msymbol_address): New functions. * symtab.h (get_symbol_address, get_msymbol_address): Declare. (SYMBOL_VALUE_ADDRESS, MSYMBOL_VALUE_ADDRESS): Handle maybe_copied. (struct symbol, struct minimal_symbol) <maybe_copied>: New member.
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r--gdb/symtab.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 7b4444c..8a551f1 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -6261,6 +6261,50 @@ symbol_set_symtab (struct symbol *symbol, struct symtab *symtab)
symbol->owner.symtab = symtab;
}
+/* See symtab.h. */
+
+CORE_ADDR
+get_symbol_address (const struct symbol *sym)
+{
+ gdb_assert (sym->maybe_copied);
+ gdb_assert (SYMBOL_CLASS (sym) == LOC_STATIC);
+
+ const char *linkage_name = SYMBOL_LINKAGE_NAME (sym);
+
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ bound_minimal_symbol minsym
+ = lookup_minimal_symbol_linkage (linkage_name, objfile);
+ if (minsym.minsym != nullptr)
+ return BMSYMBOL_VALUE_ADDRESS (minsym);
+ }
+ return sym->ginfo.value.address;
+}
+
+/* See symtab.h. */
+
+CORE_ADDR
+get_msymbol_address (struct objfile *objf, const struct minimal_symbol *minsym)
+{
+ gdb_assert (minsym->maybe_copied);
+ gdb_assert ((objf->flags & OBJF_MAINLINE) == 0);
+
+ const char *linkage_name = MSYMBOL_LINKAGE_NAME (minsym);
+
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ if ((objfile->flags & OBJF_MAINLINE) != 0)
+ {
+ bound_minimal_symbol found
+ = lookup_minimal_symbol_linkage (linkage_name, objfile);
+ if (found.minsym != nullptr)
+ return BMSYMBOL_VALUE_ADDRESS (found);
+ }
+ }
+ return (minsym->value.address
+ + ANOFFSET (objf->section_offsets, minsym->section));
+}
+
void