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]

[committed, PATCH] x86-64: Add R_X86_64_converted_reloc_bit


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                       | 16 ++++++++++++++
 bfd/elf64-x86-64.c                  | 42 +++++++++++++++++++++++++++----------
 bfd/elfxx-x86.h                     |  5 -----
 ld/ChangeLog                        |  7 +++++++
 ld/testsuite/ld-x86-64/pr19609-2a.d |  2 +-
 ld/testsuite/ld-x86-64/pr19609-2b.d |  2 +-
 ld/testsuite/ld-x86-64/pr19609-4a.d |  3 +--
 ld/testsuite/ld-x86-64/pr19609-4c.d |  3 +--
 8 files changed, 58 insertions(+), 22 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f323dfaa64..96223833ef 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,21 @@
 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
 	when calling elf_i386_tls_transition.  Don't use ELF32_R_TYPE
 	to get the relocation type again.
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 8807447c32..8f1ac1a358 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -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)
     {
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index 775e025477..9c0dcbbe87 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -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;
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 7313795848..98318e9f24 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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.
diff --git a/ld/testsuite/ld-x86-64/pr19609-2a.d b/ld/testsuite/ld-x86-64/pr19609-2a.d
index e2c6c893ac..2bed641dc2 100644
--- a/ld/testsuite/ld-x86-64/pr19609-2a.d
+++ b/ld/testsuite/ld-x86-64/pr19609-2a.d
@@ -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
diff --git a/ld/testsuite/ld-x86-64/pr19609-2b.d b/ld/testsuite/ld-x86-64/pr19609-2b.d
index ead498740e..3741ebbc15 100644
--- a/ld/testsuite/ld-x86-64/pr19609-2b.d
+++ b/ld/testsuite/ld-x86-64/pr19609-2b.d
@@ -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
diff --git a/ld/testsuite/ld-x86-64/pr19609-4a.d b/ld/testsuite/ld-x86-64/pr19609-4a.d
index ce952ed4f6..f08843c500 100644
--- a/ld/testsuite/ld-x86-64/pr19609-4a.d
+++ b/ld/testsuite/ld-x86-64/pr19609-4a.d
@@ -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
diff --git a/ld/testsuite/ld-x86-64/pr19609-4c.d b/ld/testsuite/ld-x86-64/pr19609-4c.d
index ce952ed4f6..f08843c500 100644
--- a/ld/testsuite/ld-x86-64/pr19609-4c.d
+++ b/ld/testsuite/ld-x86-64/pr19609-4c.d
@@ -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
-- 
2.13.5


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