This is the mail archive of the binutils@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]

[PATCH 2/2] Check R_386_GOT32/R_386_GOT32X without base register


The R_386_GOT32 and R_386_GOT32X relocations may be used without base
register:

	movl	bar@GOT, %eax

Its calculation is G + A, instead of G + A - GOT, and it can only used
to generate non-PIC executable.  Include the .got.plt section address
for R_386_GOT32 and R_386_GOT32X relocations without base register.
Don't allow R_386_GOT32 and R_386_GOT32X relocations without base
register when making a PIC output.

	PR gold/19177
	* i386.cc (Target_i386::Relocate::relocate): Check R_386_GOT32
	and R_386_GOT32X relocations without base register.
---
 gold/ChangeLog |  6 ++++++
 gold/i386.cc   | 28 ++++++++++++++++++++++++++--
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/gold/ChangeLog b/gold/ChangeLog
index dc1c0ea..c3cf686 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,9 @@
+2015-10-28  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR gold/19177
+	* i386.cc (Target_i386::Relocate::relocate): Check R_386_GOT32
+	and R_386_GOT32X relocations without base register.
+
 2015-10.27  Han Shen  <shenhan@google.com>
 
 	PR gold/19042 - unsupported reloc 311/312.
diff --git a/gold/i386.cc b/gold/i386.cc
index 36c5724..4c18de0 100644
--- a/gold/i386.cc
+++ b/gold/i386.cc
@@ -2790,6 +2790,8 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
 	}
     }
 
+  bool baseless;
+
   switch (r_type)
     {
     case elfcpp::R_386_NONE:
@@ -2839,6 +2841,22 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
 
     case elfcpp::R_386_GOT32:
     case elfcpp::R_386_GOT32X:
+      baseless = (view[-1] & 0xc7) == 0x5;
+      // R_386_GOT32 and R_386_GOT32X don't work without base register
+      // when generating a position-independent output file.
+      if (baseless
+	  && parameters->options().output_is_position_independent())
+	{
+	  if(gsym)
+	    gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+				   _("unexpected reloc %u against global symbol %s without base register in object file when generating a position-independent output file"),
+				   r_type, gsym->demangled_name().c_str());
+	  else
+	    gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+				   _("unexpected reloc %u against local symbol without base register in object file when generating a position-independent output file"),
+				   r_type);
+	}
+
       // Convert
       // mov foo@GOT(%reg), %reg
       // to
@@ -2852,8 +2870,11 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
 	{
 	  view[-2] = 0x8d;
 	  elfcpp::Elf_types<32>::Elf_Addr value;
-	  value = (psymval->value(object, 0)
-	           - target->got_plt_section()->address());
+	  value = psymval->value(object, 0);
+	  // Don't subtract the .got.plt section address for baseless
+	  // addressing.
+	  if (!baseless)
+	    value -= target->got_plt_section()->address();
 	  Relocate_functions<32, false>::rel32(view, value);
 	}
       else
@@ -2875,6 +2896,9 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
 	      got_offset = (object->local_got_offset(r_sym, GOT_TYPE_STANDARD)
 			    - target->got_size());
 	    }
+	  // Add the .got.plt section address for baseless addressing.
+	  if (baseless)
+	    got_offset += target->got_plt_section()->address();
 	  Relocate_functions<32, false>::rel32(view, got_offset);
 	}
       break;
-- 
2.4.3


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