Use special value when we refer a function symbol in some way other

than calling it.
This commit is contained in:
Ian Lance Taylor
2007-09-23 05:31:48 +00:00
parent cb615bc189
commit ab5c9e90a6
4 changed files with 76 additions and 12 deletions

View File

@ -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.