aboutsummaryrefslogtreecommitdiff
path: root/gdb/symtab.h
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.h
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.h')
-rw-r--r--gdb/symtab.h42
1 files changed, 39 insertions, 3 deletions
diff --git a/gdb/symtab.h b/gdb/symtab.h
index e9024a0..dc65409 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -454,6 +454,14 @@ extern const char *symbol_get_demangled_name
extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, struct obj_section *);
+/* Return the address of SYM. The MAYBE_COPIED flag must be set on
+ SYM. If SYM appears in the main program's minimal symbols, then
+ that minsym's address is returned; otherwise, SYM's address is
+ returned. This should generally only be used via the
+ SYMBOL_VALUE_ADDRESS macro. */
+
+extern CORE_ADDR get_symbol_address (const struct symbol *sym);
+
/* Note that all the following SYMBOL_* macros are used with the
SYMBOL argument being either a partial symbol or
a full symbol. Both types have a ginfo field. In particular
@@ -463,7 +471,9 @@ extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, struct obj_section *);
field only, instead of the SYMBOL parameter. */
#define SYMBOL_VALUE(symbol) (symbol)->ginfo.value.ivalue
-#define SYMBOL_VALUE_ADDRESS(symbol) ((symbol)->ginfo.value.address + 0)
+#define SYMBOL_VALUE_ADDRESS(symbol) \
+ (((symbol)->maybe_copied) ? get_symbol_address (symbol) \
+ : ((symbol)->ginfo.value.address))
#define SET_SYMBOL_VALUE_ADDRESS(symbol, new_value) \
((symbol)->ginfo.value.address = (new_value))
#define SYMBOL_VALUE_BYTES(symbol) (symbol)->ginfo.value.bytes
@@ -671,6 +681,14 @@ struct minimal_symbol : public general_symbol_info
the object file format may not carry that piece of information. */
unsigned int has_size : 1;
+ /* For data symbols only, if this is set, then the symbol might be
+ subject to copy relocation. In this case, a minimal symbol
+ matching the symbol's linkage name is first looked for in the
+ main objfile. If found, then that address is used; otherwise the
+ address in this symbol is used. */
+
+ unsigned maybe_copied : 1;
+
/* Minimal symbols with the same hash key are kept on a linked
list. This is the link. */
@@ -690,6 +708,15 @@ struct minimal_symbol : public general_symbol_info
bool text_p () const;
};
+/* Return the address of MINSYM, which comes from OBJF. The
+ MAYBE_COPIED flag must be set on MINSYM. If MINSYM appears in the
+ main program's minimal symbols, then that minsym's address is
+ returned; otherwise, MINSYM's address is returned. This should
+ generally only be used via the MSYMBOL_VALUE_ADDRESS macro. */
+
+extern CORE_ADDR get_msymbol_address (struct objfile *objf,
+ const struct minimal_symbol *minsym);
+
#define MSYMBOL_TARGET_FLAG_1(msymbol) (msymbol)->target_flag_1
#define MSYMBOL_TARGET_FLAG_2(msymbol) (msymbol)->target_flag_2
#define MSYMBOL_SIZE(msymbol) ((msymbol)->size + 0)
@@ -708,8 +735,9 @@ struct minimal_symbol : public general_symbol_info
/* The relocated address of the minimal symbol, using the section
offsets from OBJFILE. */
#define MSYMBOL_VALUE_ADDRESS(objfile, symbol) \
- ((symbol)->value.address \
- + ANOFFSET ((objfile)->section_offsets, ((symbol)->section)))
+ (((symbol)->maybe_copied) ? get_msymbol_address (objfile, symbol) \
+ : ((symbol)->value.address \
+ + ANOFFSET ((objfile)->section_offsets, ((symbol)->section))))
/* For a bound minsym, we can easily compute the address directly. */
#define BMSYMBOL_VALUE_ADDRESS(symbol) \
MSYMBOL_VALUE_ADDRESS ((symbol).objfile, (symbol).minsym)
@@ -1112,6 +1140,14 @@ struct symbol
/* Whether this is an inlined function (class LOC_BLOCK only). */
unsigned is_inlined : 1;
+ /* For LOC_STATIC only, if this is set, then the symbol might be
+ subject to copy relocation. In this case, a minimal symbol
+ matching the symbol's linkage name is first looked for in the
+ main objfile. If found, then that address is used; otherwise the
+ address in this symbol is used. */
+
+ unsigned maybe_copied : 1;
+
/* The concrete type of this symbol. */
ENUM_BITFIELD (symbol_subclass_kind) subclass : 2;