x86-64: Add R_X86_64_converted_reloc_bit
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 6 Sep 2017 12:06:35 +0000 (05:06 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 6 Sep 2017 12:06:35 +0000 (05:06 -0700)
Add R_X86_64_converted_reloc_bit to relocation type to indicate if a
relocation is converted from a GOTPCREL relocation.  Linker now generates

failed to convert GOTPCREL relocation; relink with --no-relax

for all cases, including relocations against local symbols.

bfd/

* elf64-x86-64.c (R_X86_64_converted_reloc_bit): New.
(elf_x86_64_info_to_howto): Get the real relocation type by
masking out R_X86_64_converted_reloc_bit.
(elf_x86_64_check_tls_transition): Get the real relocation type
by masking out R_X86_64_converted_reloc_bit.
(elf_x86_64_convert_load_reloc): Set R_X86_64_converted_reloc_bit
instead of setting converted_reloc.
(elf_x86_64_relocate_section): Check R_X86_64_converted_reloc_bit
instead of converted_reloc. Get the real relocation type by
masking out R_X86_64_converted_reloc_bit.
(elf_x86_64_link_setup_gnu_properties): Verify that the value of
R_X86_64_converted_reloc_bit is valid.
* elfxx-x86.h (converted_reloc): Removed.

ld/

* testsuite/ld-x86-64/pr19609-2a.d: Updated.
* testsuite/ld-x86-64/pr19609-2b.d: Likewise.
* testsuite/ld-x86-64/pr19609-4a.d: Likewise.
* testsuite/ld-x86-64/pr19609-4c.d: Likewise.

bfd/ChangeLog
bfd/elf64-x86-64.c
bfd/elfxx-x86.h
ld/ChangeLog
ld/testsuite/ld-x86-64/pr19609-2a.d
ld/testsuite/ld-x86-64/pr19609-2b.d
ld/testsuite/ld-x86-64/pr19609-4a.d
ld/testsuite/ld-x86-64/pr19609-4c.d

index f323dfaa6456a56eba68b30fe61d04ea20651e99..96223833ef5f282afe1d26fbed2acc664ebcee96 100644 (file)
@@ -1,3 +1,19 @@
+2017-09-06  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elf64-x86-64.c (R_X86_64_converted_reloc_bit): New.
+       (elf_x86_64_info_to_howto): Get the real relocation type by
+       masking out R_X86_64_converted_reloc_bit.
+       (elf_x86_64_check_tls_transition): Get the real relocation type
+       by masking out R_X86_64_converted_reloc_bit.
+       (elf_x86_64_convert_load_reloc): Set R_X86_64_converted_reloc_bit
+       instead of setting converted_reloc.
+       (elf_x86_64_relocate_section): Check R_X86_64_converted_reloc_bit
+       instead of converted_reloc. Get the real relocation type by
+       masking out R_X86_64_converted_reloc_bit.
+       (elf_x86_64_link_setup_gnu_properties): Verify that the value of
+       R_X86_64_converted_reloc_bit is valid.
+       * elfxx-x86.h (converted_reloc): Removed.
+
 2017-09-06  H.J. Lu  <hongjiu.lu@intel.com>
 
        * elf32-i386.c (elf_i386_relocate_section): Don't change r_type
index 8807447c32616ec94f98345a10212e0afc3bbf63..8f1ac1a3587fcaa77a7582982dca2e8db0d08ab1 100644 (file)
@@ -196,6 +196,9 @@ static reloc_howto_type x86_64_elf_howto_table[] =
        FALSE)
 };
 
+/* Set if a relocation is converted from a GOTPCREL relocation.  */
+#define R_X86_64_converted_reloc_bit (1 << 7)
+
 #define IS_X86_64_PCREL_TYPE(TYPE)     \
   (   ((TYPE) == R_X86_64_PC8)         \
    || ((TYPE) == R_X86_64_PC16)                \
@@ -337,6 +340,9 @@ elf_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
   unsigned r_type;
 
   r_type = ELF32_R_TYPE (dst->r_info);
+  if (r_type != (unsigned int) R_X86_64_GNU_VTINHERIT
+      && r_type != (unsigned int) R_X86_64_GNU_VTENTRY)
+    r_type &= ~R_X86_64_converted_reloc_bit;
   cache_ptr->howto = elf_x86_64_rtype_to_howto (abfd, r_type);
   BFD_ASSERT (r_type == cache_ptr->howto->type);
 }
@@ -1145,13 +1151,17 @@ elf_x86_64_check_tls_transition (bfd *abfd,
       if (h == NULL
          || !((struct elf_x86_link_hash_entry *) h)->tls_get_addr)
        return FALSE;
-      else if (largepic)
-       return ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PLTOFF64;
-      else if (indirect_call)
-       return ELF32_R_TYPE (rel[1].r_info) == R_X86_64_GOTPCRELX;
       else
-       return (ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PC32
-               || ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
+       {
+         r_type = (ELF32_R_TYPE (rel[1].r_info)
+                   & ~R_X86_64_converted_reloc_bit);
+         if (largepic)
+           return r_type == R_X86_64_PLTOFF64;
+         else if (indirect_call)
+           return r_type == R_X86_64_GOTPCRELX;
+         else
+           return (r_type == R_X86_64_PC32 || r_type == R_X86_64_PLT32);
+       }
 
     case R_X86_64_GOTTPOFF:
       /* Check transition from IE access model:
@@ -1598,9 +1608,6 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
     return TRUE;
 
 convert:
-  if (h != NULL)
-    ((struct elf_x86_link_hash_entry *) h)->converted_reloc = 1;
-
   if (opcode == 0xff)
     {
       /* We have "call/jmp *foo@GOTPCREL(%rip)".  */
@@ -1742,7 +1749,8 @@ rewrite_modrm_rex:
       bfd_put_8 (abfd, opcode, contents + roff - 2);
     }
 
-  irel->r_info = htab->r_info (r_symndx, r_type);
+  irel->r_info = htab->r_info (r_symndx,
+                              r_type | R_X86_64_converted_reloc_bit);
 
   *converted = TRUE;
 
@@ -2527,6 +2535,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
       bfd_vma st_size;
       bfd_boolean resolved_to_zero;
       bfd_boolean relative_reloc;
+      bfd_boolean converted_reloc;
 
       r_type = ELF32_R_TYPE (rel->r_info);
       if (r_type == (int) R_X86_64_GNU_VTINHERIT
@@ -2537,6 +2546,9 @@ elf_x86_64_relocate_section (bfd *output_bfd,
          continue;
        }
 
+      converted_reloc = (r_type & R_X86_64_converted_reloc_bit) != 0;
+      r_type &= ~R_X86_64_converted_reloc_bit;
+
       if (r_type >= (int) R_X86_64_standard)
        return _bfd_unrecognized_reloc (input_bfd, input_section, r_type);
 
@@ -4011,7 +4023,7 @@ check_relocation_error:
 
          if (r == bfd_reloc_overflow)
            {
-             if (eh != NULL && eh->converted_reloc)
+             if (converted_reloc)
                {
                  info->callbacks->einfo
                    (_("%F%P: failed to convert GOTPCREL relocation; relink with --no-relax\n"));
@@ -5250,6 +5262,14 @@ elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info)
 {
   struct elf_x86_plt_layout_table plt_layout;
 
+  if ((int) R_X86_64_standard >= (int) R_X86_64_converted_reloc_bit
+      || (int) R_X86_64_max <= (int) R_X86_64_converted_reloc_bit
+      || ((int) (R_X86_64_GNU_VTINHERIT | R_X86_64_converted_reloc_bit)
+         != (int) R_X86_64_GNU_VTINHERIT)
+      || ((int) (R_X86_64_GNU_VTENTRY | R_X86_64_converted_reloc_bit)
+         != (int) R_X86_64_GNU_VTENTRY))
+    abort ();
+
   plt_layout.is_vxworks = FALSE;
   if (get_elf_x86_64_backend_data (info->output_bfd)->os == is_normal)
     {
index 775e025477266d6ab6458e13f0bd648148c9db26..9c0dcbbe8792baa7d244d5c0a4c01ec252bbba6c 100644 (file)
@@ -110,11 +110,6 @@ struct elf_x86_link_hash_entry
      is only used by x86-64.  */
   unsigned int needs_copy : 1;
 
-  /* TRUE if a symbol with GOTPCREL relocations which have been converted
-     to R_X86_64_PC32, R_X86_64_32 or R_X86_64_32S.  This is only used by
-     x86-64 for now.  */
-  unsigned int converted_reloc : 1;
-
   /* Reference count of C/C++ function pointer relocations in read-write
      section which can be resolved at run-time.  */
   bfd_signed_vma func_pointer_refcount;
index 73137958480c83b76a1b095d937a6a5e430bc52c..98318e9f24333201b6c3442f7b181459de1c7d45 100644 (file)
@@ -1,3 +1,10 @@
+2017-09-06  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * testsuite/ld-x86-64/pr19609-2a.d: Updated.
+       * testsuite/ld-x86-64/pr19609-2b.d: Likewise.
+       * testsuite/ld-x86-64/pr19609-4a.d: Likewise.
+       * testsuite/ld-x86-64/pr19609-4c.d: Likewise.
+
 2017-09-05  H.J. Lu  <hongjiu.lu@intel.com>
 
        * testsuite/ld-x86-64/pr19609-5d.d: Updated.
index e2c6c893accdbb7233c8f335ce8ea5625b01d1d7..2bed641dc243f3f0770abca27b7e849e50d82038 100644 (file)
@@ -1,4 +1,4 @@
 #source: pr19609-2.s
 #as: --64 -mrelax-relocations=yes
 #ld: -melf_x86_64 -Ttext=0x70000000 -Tdata=0xa0000000
-#error: .*relocation truncated to fit: R_X86_64_32S .*
+#error: failed to convert GOTPCREL relocation; relink with --no-relax
index ead498740e0548e69c5d6619b62db3507bfcb973..3741ebbc158bfa43df80f44ee7fcf850305639b0 100644 (file)
@@ -1,4 +1,4 @@
 #source: pr19609-2.s
 #as: --x32 -mrelax-relocations=yes
 #ld: -melf32_x86_64 -Ttext=0x70000000 -Tdata=0xa0000000
-#error: .*relocation truncated to fit: R_X86_64_32S .*
+#error: failed to convert GOTPCREL relocation; relink with --no-relax
index ce952ed4f6483ece8e4abbc599f9e82c7787dc0e..f08843c5001a998fd15efe248efcb26bea86a946 100644 (file)
@@ -1,5 +1,4 @@
 #source: pr19609-4.s
 #as: --64 -mrelax-relocations=yes
 #ld: -melf_x86_64 -Ttext=0x70000000 -Tdata=0xa0000000
-#error: .*relocation truncated to fit: R_X86_64_32S .*
-#error: .*relocation truncated to fit: R_X86_64_32S .*
+#error: failed to convert GOTPCREL relocation; relink with --no-relax
index ce952ed4f6483ece8e4abbc599f9e82c7787dc0e..f08843c5001a998fd15efe248efcb26bea86a946 100644 (file)
@@ -1,5 +1,4 @@
 #source: pr19609-4.s
 #as: --64 -mrelax-relocations=yes
 #ld: -melf_x86_64 -Ttext=0x70000000 -Tdata=0xa0000000
-#error: .*relocation truncated to fit: R_X86_64_32S .*
-#error: .*relocation truncated to fit: R_X86_64_32S .*
+#error: failed to convert GOTPCREL relocation; relink with --no-relax