This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb/binutils-2_29-branch] [GOLD] PowerPC function address in non-PIC


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=437ea1e4871b36e879ff8dcc821b04411e03e600

commit 437ea1e4871b36e879ff8dcc821b04411e03e600
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Sep 20 09:17:56 2017 +0930

    [GOLD] PowerPC function address in non-PIC
    
    ppc32, like many targets, defines the address of a function as the PLT
    call stub code for functions referenced but not defined in a non-PIC
    executable.  ppc32 gold, unlike other targets, inherits the ppc64
    multiple stub capability for dealing with very large binaries where
    one set of stubs can't be reached from all code locations.  This means
    there can be multiple choices of address for a function, which might
    cause function pointer comparison failures.  So for ppc32, make
    non-branch references always use the first stub group.
    
    (PowerPC64 ELFv1 is always PIC so doesn't need to define the address
    of an external function as the PLT stub.  PowerPC64 ELFv2 needs a
    special set of global entry stubs to serve as the address of external
    functions, so it too is not affected by this bug.)
    
    	* powerpc.cc (Target_powerpc::Branch_info::make_stub): Put
    	stubs for ppc32 non-branch relocs in first stub table.
    	(Target_powerpc::Relocate::relocate): Resolve similarly.
    
    (cherry picked from commit 64b5d6d785eb4c337b7c071ab9607186541a8b14)

Diff:
---
 gold/ChangeLog  |  6 ++++++
 gold/powerpc.cc | 25 ++++++++++++++++++++-----
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/gold/ChangeLog b/gold/ChangeLog
index 6071f89..795837b 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,9 @@
+2017-09-20  Alan Modra  <amodra@gmail.com>
+
+	* powerpc.cc (Target_powerpc::Branch_info::make_stub): Put
+	stubs for ppc32 non-branch relocs in first stub table.
+	(Target_powerpc::Relocate::relocate): Resolve similarly.
+
 2017-09-19  Alan Modra  <amodra@gmail.com>
 
 	* options.h (stub-group-multi): Default to true.  Add
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index 629da4f..ba20ef1 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -3065,11 +3065,17 @@ Target_powerpc<size, big_endian>::Branch_info::make_stub(
 	target->glink_section()->add_global_entry(gsym);
       else
 	{
-	  if (stub_table == NULL)
+	  if (stub_table == NULL
+	      && !(size == 32
+		   && gsym != NULL
+		   && !parameters->options().output_is_position_independent()
+		   && !is_branch_reloc(this->r_type_)))
 	    stub_table = this->object_->stub_table(this->shndx_);
 	  if (stub_table == NULL)
 	    {
-	      // This is a ref from a data section to an ifunc symbol.
+	      // This is a ref from a data section to an ifunc symbol,
+	      // or a non-branch reloc for which we always want to use
+	      // one set of stubs for resolving function addresses.
 	      stub_table = ifunc_stub_table;
 	    }
 	  gold_assert(stub_table != NULL);
@@ -8052,11 +8058,20 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
 	}
       else
 	{
-	  Stub_table<size, big_endian>* stub_table
-	    = object->stub_table(relinfo->data_shndx);
+	  Stub_table<size, big_endian>* stub_table = NULL;
+	  if (target->stub_tables().size() == 1)
+	    stub_table = target->stub_tables()[0];
+	  if (stub_table == NULL
+	      && !(size == 32
+		   && gsym != NULL
+		   && !parameters->options().output_is_position_independent()
+		   && !is_branch_reloc(r_type)))
+	    stub_table = object->stub_table(relinfo->data_shndx);
 	  if (stub_table == NULL)
 	    {
-	      // This is a ref from a data section to an ifunc symbol.
+	      // This is a ref from a data section to an ifunc symbol,
+	      // or a non-branch reloc for which we always want to use
+	      // one set of stubs for resolving function addresses.
 	      if (target->stub_tables().size() != 0)
 		stub_table = target->stub_tables()[0];
 	    }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]