diff options
author | Ian Lance Taylor <iant@google.com> | 2007-09-23 05:31:48 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2007-09-23 05:31:48 +0000 |
commit | ab5c9e90a6d088f6b09bdc8f6bee09c911789df6 (patch) | |
tree | 315b4833fd2030948138845c5f58b05f252dc918 /gold/i386.cc | |
parent | cb615bc189241f02996054391ade06ba06147147 (diff) | |
download | gdb-ab5c9e90a6d088f6b09bdc8f6bee09c911789df6.zip gdb-ab5c9e90a6d088f6b09bdc8f6bee09c911789df6.tar.gz gdb-ab5c9e90a6d088f6b09bdc8f6bee09c911789df6.tar.bz2 |
Use special value when we refer a function symbol in some way other
than calling it.
Diffstat (limited to 'gold/i386.cc')
-rw-r--r-- | gold/i386.cc | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/gold/i386.cc b/gold/i386.cc index 00ac288..54c388b 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -74,6 +74,11 @@ class Target_i386 : public Sized_target<32, 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<32, false>*, @@ -844,7 +849,18 @@ Target_i386::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_386_PC32 + && r_type != elfcpp::R_386_PC16 + && r_type != elfcpp::R_386_PC8) + gsym->set_needs_dynsym_value(); + } else target->copy_reloc(&options, symtab, layout, object, data_shndx, gsym, reloc); @@ -1507,6 +1523,18 @@ Target_i386::relocate_section(const Relocate_info<32, 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_i386::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. |