aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-10-03 05:40:11 +0000
committerIan Lance Taylor <iant@google.com>2007-10-03 05:40:11 +0000
commit4fb6c25d5007c1bc13c8fddda21c96bb4d05ef91 (patch)
tree565fef912ad177b890548935295b3716538c3fb6
parent6f08d80e81cc9b0b99abdd60a25d65ad09c75ffc (diff)
downloadgdb-4fb6c25d5007c1bc13c8fddda21c96bb4d05ef91.zip
gdb-4fb6c25d5007c1bc13c8fddda21c96bb4d05ef91.tar.gz
gdb-4fb6c25d5007c1bc13c8fddda21c96bb4d05ef91.tar.bz2
From Craig Silverstein: set symbol value for function pointer
equality across shared library boundaries.
-rw-r--r--gold/x86_64.cc31
1 files changed, 30 insertions, 1 deletions
diff --git a/gold/x86_64.cc b/gold/x86_64.cc
index d7a6ea9..df76051 100644
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -86,6 +86,11 @@ class Target_x86_64 : public Sized_target<64, false>
void
do_finalize_sections(Layout*);
+ // Return the value to use for a dynamic which requires special
+ // treatment.
+ uint64_t
+ do_dynsym_value(const Symbol*) const;
+
// Relocate a section.
void
relocate_section(const Relocate_info<64, false>*,
@@ -849,7 +854,19 @@ Target_x86_64::Scan::global(const General_options& options,
// function, we make a PLT entry. Otherwise we need to
// either generate a COPY reloc or copy this reloc.
if (gsym->type() == elfcpp::STT_FUNC)
- target->make_plt_entry(symtab, layout, gsym);
+ {
+ target->make_plt_entry(symtab, layout, gsym);
+
+ // If this is not a PC relative reference, then we may
+ // be taking the address of the function. In that case
+ // we need to set the entry in the dynamic symbol table
+ // to the address of the PLT entry.
+ if (r_type != elfcpp::R_X86_64_PC64
+ && r_type != elfcpp::R_X86_64_PC32
+ && r_type != elfcpp::R_X86_64_PC16
+ && r_type != elfcpp::R_X86_64_PC8)
+ gsym->set_needs_dynsym_value();
+ }
else
target->copy_reloc(&options, symtab, layout, object, data_shndx,
gsym, reloc);
@@ -1608,6 +1625,18 @@ Target_x86_64::relocate_section(const Relocate_info<64, false>* relinfo,
view_size);
}
+// Return the value to use for a dynamic which requires special
+// treatment. This is how we support equality comparisons of function
+// pointers across shared library boundaries, as described in the
+// processor specific ABI supplement.
+
+uint64_t
+Target_x86_64::do_dynsym_value(const Symbol* gsym) const
+{
+ gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
+ return this->plt_section()->address() + gsym->plt_offset();
+}
+
// Return a string used to fill a code section with nops to take up
// the specified length.