Gold: Don't fail on R_X86_64_[REX_]GOTPCRELX relocations
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 22 Oct 2015 11:56:10 +0000 (04:56 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 22 Oct 2015 11:56:57 +0000 (04:56 -0700)
This patch updates gold to treat the R_X86_64_GOTPCRELX and
R_X86_64_REX_GOTPCRELX relocations proposed in

https://groups.google.com/forum/#!topic/x86-64-abi/n9AWHogmVY0

the same as R_X86_64_GOTPCREL.  FIXME: Gold should perform the
transformations as suggested.

elfcpp/

* x86_64.h (R_X86_64_GOTPCRELX): New.
(R_X86_64_REX_GOTPCRELX): Likewise.

gold/

* x86_64.cc (Target_x86_64<size>::Scan::get_reference_flags):
Treat R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX the same
as R_X86_64_GOTPCREL.
(Target_x86_64<size>::Scan::local): Likewise.
(Target_x86_64<size>::Scan::possible_function_pointer_reloc):
Likewise.
(Target_x86_64<size>::Scan::global): Likewise.
(Target_x86_64<size>::Relocate::relocate): Likewise.
(Target_x86_64<size>::Relocatable_size_for_reloc::get_size_for_reloc):
Likewise.

elfcpp/ChangeLog
elfcpp/x86_64.h
gold/ChangeLog
gold/x86_64.cc

index c0f1698d0b4c8f66c6ef4e71ae6d6190e0cb5c4f..24df27b35ff4c99d843dce784e46e3e3c7c7a6ff 100644 (file)
@@ -1,3 +1,8 @@
+2015-10-22  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * x86_64.h (R_X86_64_GOTPCRELX): New.
+       (R_X86_64_REX_GOTPCRELX): Likewise.
+
 2015-10-22  H.J. Lu  <hongjiu.lu@intel.com>
 
        * i386.h (R_386_GOT32X): New.
index e97ff5234b75e37d61b2f3c573c9b046a134d405..52cb9ae2ba7a56452e91d3c2b17ec41fa47524b1 100644 (file)
@@ -94,6 +94,10 @@ enum
   R_X86_64_RELATIVE64 = 38,      // 64-bit adjust by program base
   R_X86_64_PC32_BND = 39,  // PC relative 32 bit signed with BND prefix
   R_X86_64_PLT32_BND = 40, // 32 bit PLT address with BND prefix
+  R_X86_64_GOTPCRELX = 41, // 32 bit signed PC relative offset to GOT
+                          // without REX prefix, relaxable.
+  R_X86_64_REX_GOTPCRELX = 42, // 32 bit signed PC relative offset to GOT
+                              // with REX prefix, relaxable.
   // GNU vtable garbage collection extensions.
   R_X86_64_GNU_VTINHERIT = 250,
   R_X86_64_GNU_VTENTRY = 251
index c0af0291d0e65512e094000d3e46311989dd0d3e..46a0636d8e6f2b1662e786a75730144c5267191d 100644 (file)
@@ -1,3 +1,16 @@
+2015-10-22  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * x86_64.cc (Target_x86_64<size>::Scan::get_reference_flags):
+       Treat R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX the same
+       as R_X86_64_GOTPCREL.
+       (Target_x86_64<size>::Scan::local): Likewise.
+       (Target_x86_64<size>::Scan::possible_function_pointer_reloc):
+       Likewise.
+       (Target_x86_64<size>::Scan::global): Likewise.
+       (Target_x86_64<size>::Relocate::relocate): Likewise.
+       (Target_x86_64<size>::Relocatable_size_for_reloc::get_size_for_reloc):
+       Likewise.
+
 2015-10-22  H.J. Lu  <hongjiu.lu@intel.com>
 
        * i386.cc (Target_i386::Scan::get_reference_flags(): Treat
index 007af1d4c42a0d862474f442b3a916d1a8762b9a..c728a0061877cb7918c9895d0335c582d60dd30a 100644 (file)
@@ -2191,6 +2191,8 @@ Target_x86_64<size>::Scan::get_reference_flags(unsigned int r_type)
     case elfcpp::R_X86_64_GOT32:
     case elfcpp::R_X86_64_GOTPCREL64:
     case elfcpp::R_X86_64_GOTPCREL:
+    case elfcpp::R_X86_64_GOTPCRELX:
+    case elfcpp::R_X86_64_REX_GOTPCRELX:
     case elfcpp::R_X86_64_GOTPLT64:
       // Absolute in GOT.
       return Symbol::ABSOLUTE_REF;
@@ -2475,6 +2477,8 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
     case elfcpp::R_X86_64_GOT32:
     case elfcpp::R_X86_64_GOTPCREL64:
     case elfcpp::R_X86_64_GOTPCREL:
+    case elfcpp::R_X86_64_GOTPCRELX:
+    case elfcpp::R_X86_64_REX_GOTPCRELX:
     case elfcpp::R_X86_64_GOTPLT64:
       {
        // The symbol requires a GOT section.
@@ -2485,7 +2489,9 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
        // mov foo@GOTPCREL(%rip), %reg
        // to lea foo(%rip), %reg.
        // in Relocate::relocate.
-       if (r_type == elfcpp::R_X86_64_GOTPCREL
+       if ((r_type == elfcpp::R_X86_64_GOTPCREL
+            || r_type == elfcpp::R_X86_64_GOTPCRELX
+            || r_type == elfcpp::R_X86_64_REX_GOTPCRELX)
            && reloc.get_r_offset() >= 2
            && !is_ifunc)
          {
@@ -2713,6 +2719,8 @@ Target_x86_64<size>::Scan::possible_function_pointer_reloc(unsigned int r_type)
     case elfcpp::R_X86_64_GOT32:
     case elfcpp::R_X86_64_GOTPCREL64:
     case elfcpp::R_X86_64_GOTPCREL:
+    case elfcpp::R_X86_64_GOTPCRELX:
+    case elfcpp::R_X86_64_REX_GOTPCRELX:
     case elfcpp::R_X86_64_GOTPLT64:
       {
        return true;
@@ -2901,6 +2909,8 @@ Target_x86_64<size>::Scan::global(Symbol_table* symtab,
     case elfcpp::R_X86_64_GOT32:
     case elfcpp::R_X86_64_GOTPCREL64:
     case elfcpp::R_X86_64_GOTPCREL:
+    case elfcpp::R_X86_64_GOTPCRELX:
+    case elfcpp::R_X86_64_REX_GOTPCRELX:
     case elfcpp::R_X86_64_GOTPLT64:
       {
        // The symbol requires a GOT entry.
@@ -2910,7 +2920,9 @@ Target_x86_64<size>::Scan::global(Symbol_table* symtab,
        // mov foo@GOTPCREL(%rip), %reg
        // to lea foo(%rip), %reg.
        // in Relocate::relocate, then there is nothing to do here.
-       if (r_type == elfcpp::R_X86_64_GOTPCREL
+       if ((r_type == elfcpp::R_X86_64_GOTPCREL
+            || r_type == elfcpp::R_X86_64_GOTPCRELX
+            || r_type == elfcpp::R_X86_64_REX_GOTPCRELX)
            && reloc.get_r_offset() >= 2
            && Target_x86_64<size>::can_convert_mov_to_lea(gsym))
          {
@@ -3538,6 +3550,8 @@ Target_x86_64<size>::Relocate::relocate(
       break;
 
     case elfcpp::R_X86_64_GOTPCREL:
+    case elfcpp::R_X86_64_GOTPCRELX:
+    case elfcpp::R_X86_64_REX_GOTPCRELX:
       {
       // Convert
       // mov foo@GOTPCREL(%rip), %reg
@@ -4320,6 +4334,8 @@ Target_x86_64<size>::Relocatable_size_for_reloc::get_size_for_reloc(
     case elfcpp::R_X86_64_GOT64:
     case elfcpp::R_X86_64_GOTPCREL64:
     case elfcpp::R_X86_64_GOTPCREL:
+    case elfcpp::R_X86_64_GOTPCRELX:
+    case elfcpp::R_X86_64_REX_GOTPCRELX:
     case elfcpp::R_X86_64_GOTPLT64:
       return 8;