diff options
author | Tom Tromey <tromey@adacore.com> | 2019-06-25 12:50:45 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2019-10-02 09:53:17 -0600 |
commit | 4b610737f02338b2aea7641ab771aa5e137d067c (patch) | |
tree | a29d17f55e269ad24027060bb9fb0bdf40cd3b67 /gdb/dwarf2read.c | |
parent | 1dd588507782591478882a891f64945af9e2b86c (diff) | |
download | gdb-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/dwarf2read.c')
-rw-r--r-- | gdb/dwarf2read.c | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index f10f384..feac40f 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -2138,8 +2138,10 @@ attr_value_as_address (struct attribute *attr) /* See declaration. */ dwarf2_per_objfile::dwarf2_per_objfile (struct objfile *objfile_, - const dwarf2_debug_sections *names) - : objfile (objfile_) + const dwarf2_debug_sections *names, + bool can_copy_) + : objfile (objfile_), + can_copy (can_copy_) { if (names == NULL) names = &dwarf2_elf_names; @@ -2214,11 +2216,14 @@ private: /* Try to locate the sections we need for DWARF 2 debugging information and return true if we have enough to do something. NAMES points to the dwarf2 section names, or is NULL if the standard - ELF names are used. */ + ELF names are used. CAN_COPY is true for formats where symbol + interposition is possible and so symbol values must follow copy + relocation rules. */ int dwarf2_has_info (struct objfile *objfile, - const struct dwarf2_debug_sections *names) + const struct dwarf2_debug_sections *names, + bool can_copy) { if (objfile->flags & OBJF_READNEVER) return 0; @@ -2228,7 +2233,8 @@ dwarf2_has_info (struct objfile *objfile, if (dwarf2_per_objfile == NULL) dwarf2_per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile, - names); + names, + can_copy); return (!dwarf2_per_objfile->info.is_virtual && dwarf2_per_objfile->info.s.section != NULL @@ -21715,19 +21721,21 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu, } else if (attr2 && (DW_UNSND (attr2) != 0)) { - /* Workaround gfortran PR debug/40040 - it uses - DW_AT_location for variables in -fPIC libraries which may - get overriden by other libraries/executable and get - a different address. Resolve it by the minimal symbol - which may come from inferior's executable using copy - relocation. Make this workaround only for gfortran as for - other compilers GDB cannot guess the minimal symbol - Fortran mangling kind. */ - if (cu->language == language_fortran && die->parent - && die->parent->tag == DW_TAG_module - && cu->producer - && startswith (cu->producer, "GNU Fortran")) - SYMBOL_ACLASS_INDEX (sym) = LOC_UNRESOLVED; + if (SYMBOL_CLASS (sym) == LOC_STATIC + && (objfile->flags & OBJF_MAINLINE) == 0 + && dwarf2_per_objfile->can_copy) + { + /* A global static variable might be subject to + copy relocation. We first check for a local + minsym, though, because maybe the symbol was + marked hidden, in which case this would not + apply. */ + bound_minimal_symbol found + = (lookup_minimal_symbol_linkage + (SYMBOL_LINKAGE_NAME (sym), objfile)); + if (found.minsym != nullptr) + sym->maybe_copied = 1; + } /* A variable with DW_AT_external is never static, but it may be block-scoped. */ |