aboutsummaryrefslogtreecommitdiff
path: root/gold/i386.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2011-07-12 22:29:09 +0000
committerIan Lance Taylor <ian@airs.com>2011-07-12 22:29:09 +0000
commit07aa62f2670a590b8f35a7308129bff58bf4a9d6 (patch)
tree15e9038da0603a28ee7e192ed1ddac4b5db6954d /gold/i386.cc
parenta7035dbbd10c5208e63cc3bc1b45f2dd8d16d7bb (diff)
downloadgdb-07aa62f2670a590b8f35a7308129bff58bf4a9d6.zip
gdb-07aa62f2670a590b8f35a7308129bff58bf4a9d6.tar.gz
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/i386.cc')
-rw-r--r--gold/i386.cc15
1 files changed, 15 insertions, 0 deletions
diff --git a/gold/i386.cc b/gold/i386.cc
index 8d3b630..84b9f07 100644
--- a/gold/i386.cc
+++ b/gold/i386.cc
@@ -1985,9 +1985,24 @@ Target_i386::Scan::global(Symbol_table* symtab,
// If this symbol is not fully resolved, we need to add a
// GOT entry with a dynamic relocation.
Reloc_section* rel_dyn = target->rel_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_rel(gsym, GOT_TYPE_STANDARD,