diff options
author | Ian Lance Taylor <ian@airs.com> | 2011-07-12 22:29:09 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2011-07-12 22:29:09 +0000 |
commit | 07aa62f2670a590b8f35a7308129bff58bf4a9d6 (patch) | |
tree | 15e9038da0603a28ee7e192ed1ddac4b5db6954d /gold/x86_64.cc | |
parent | a7035dbbd10c5208e63cc3bc1b45f2dd8d16d7bb (diff) | |
download | fsf-binutils-gdb-07aa62f2670a590b8f35a7308129bff58bf4a9d6.zip fsf-binutils-gdb-07aa62f2670a590b8f35a7308129bff58bf4a9d6.tar.gz fsf-binutils-gdb-07aa62f2670a590b8f35a7308129bff58bf4a9d6.tar.bz2 |
PR gold/12980
* i386.cc (Target_i386::Scan::global): For a GOT reloc, use a
GLOB_DAT relocation rather than a RELATIVE relocation for a
protected symbol when creating a shared library.
* x86_64.cc (Target_x86_64::Scan::global): Likewise.
* testsuite/protected_1.cc (f2, get_f2_addr): New functions.
* testsuite/protected_main_1.cc (main): Test that protected
function has same address.
Diffstat (limited to 'gold/x86_64.cc')
-rw-r--r-- | gold/x86_64.cc | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/gold/x86_64.cc b/gold/x86_64.cc index de204cb..ef66737 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -2436,9 +2436,24 @@ Target_x86_64::Scan::global(Symbol_table* symtab, // If this symbol is not fully resolved, we need to add a // dynamic relocation for it. Reloc_section* rela_dyn = target->rela_dyn_section(layout); + + // Use a GLOB_DAT rather than a RELATIVE reloc if: + // + // 1) The symbol may be defined in some other module. + // + // 2) We are building a shared library and this is a + // protected symbol; using GLOB_DAT means that the dynamic + // linker can use the address of the PLT in the main + // executable when appropriate so that function address + // comparisons work. + // + // 3) This is a STT_GNU_IFUNC symbol in position dependent + // code, again so that function address comparisons work. if (gsym->is_from_dynobj() || gsym->is_undefined() || gsym->is_preemptible() + || (gsym->visibility() == elfcpp::STV_PROTECTED + && parameters->options().shared()) || (gsym->type() == elfcpp::STT_GNU_IFUNC && parameters->options().output_is_position_independent())) got->add_global_with_rela(gsym, GOT_TYPE_STANDARD, rela_dyn, |