Blame SOURCES/binutils-2.27-aarch64-copy-relocs.patch

58725c
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
58725c
index 1edf2a0..e27f067 100644 (file)
58725c
--- a/bfd/elfnn-aarch64.c
58725c
+++ b/bfd/elfnn-aarch64.c
58725c
@@ -6869,6 +6889,31 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
58725c
   return TRUE;
58725c
 }
58725c
 
58725c
+/* Return true if we need copy relocation against EH.  */
58725c
+
58725c
+static bfd_boolean
58725c
+need_copy_relocation_p (struct elf_aarch64_link_hash_entry *eh)
58725c
+{
58725c
+  struct elf_dyn_relocs *p;
58725c
+  asection *s;
58725c
+
58725c
+  for (p = eh->dyn_relocs; p != NULL; p = p->next)
58725c
+    {
58725c
+      /* If there is any pc-relative reference, we need to keep copy relocation
58725c
+        to avoid propagating the relocation into runtime that current glibc
58725c
+        does not support.  */
58725c
+      if (p->pc_count)
58725c
+       return TRUE;
58725c
+
58725c
+      s = p->sec->output_section;
58725c
+      /* Need copy relocation if it's against read-only section.  */
58725c
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
58725c
+       return TRUE;
58725c
+    }
58725c
+
58725c
+  return FALSE;
58725c
+}
58725c
+
58725c
 /* Adjust a symbol defined by a dynamic object and referenced by a
58725c
    regular object.  The current definition is in some section of the
58725c
    dynamic object, but we're not including those sections.  We have to
58725c
@@ -6942,6 +6987,19 @@ elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info *info,
58725c
       return TRUE;
58725c
     }
58725c
 
58725c
+  if (ELIMINATE_COPY_RELOCS)
58725c
+    {
58725c
+      struct elf_aarch64_link_hash_entry *eh;
58725c
+      /* If we didn't find any dynamic relocs in read-only sections, then
58725c
+        we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
58725c
+      eh = (struct elf_aarch64_link_hash_entry *) h;
58725c
+      if (!need_copy_relocation_p (eh))
58725c
+       {
58725c
+         h->non_got_ref = 0;
58725c
+         return TRUE;
58725c
+       }
58725c
+    }
58725c
+
58725c
   /* We must allocate the symbol in our .dynbss section, which will
58725c
      become part of the .bss section of the executable.  There will be
58725c
      an entry for this symbol in the .dynsym section.  The dynamic
58725c
diff --git a/ld/testsuite/ld-aarch64/copy-reloc-2.d b/ld/testsuite/ld-aarch64/copy-reloc-2.d
58725c
new file mode 100644 (file)
58725c
index 0000000..87ddccd
58725c
--- /dev/null
58725c
+++ b/ld/testsuite/ld-aarch64/copy-reloc-2.d
58725c
@@ -0,0 +1,7 @@
58725c
+.*
58725c
+DYNAMIC RELOCATION RECORDS
58725c
+OFFSET.*TYPE.*VALUE.*
58725c
+.*R_AARCH64_COPY.*global_[abcd]
58725c
+.*R_AARCH64_COPY.*global_[abcd]
58725c
+.*R_AARCH64_COPY.*global_[abcd]
58725c
+.*R_AARCH64_COPY.*global_[abcd]
58725c
diff --git a/ld/testsuite/ld-aarch64/copy-reloc-eliminate.d b/ld/testsuite/ld-aarch64/copy-reloc-eliminate.d
58725c
new file mode 100644 (file)
58725c
index 0000000..9657d65
58725c
--- /dev/null
58725c
+++ b/ld/testsuite/ld-aarch64/copy-reloc-eliminate.d
58725c
@@ -0,0 +1,4 @@
58725c
+.*
58725c
+DYNAMIC RELOCATION RECORDS
58725c
+OFFSET.*TYPE.*VALUE.*
58725c
+.*R_AARCH64_ABS64.*global_a
58725c
diff --git a/ld/testsuite/ld-aarch64/copy-reloc-exe-2.s b/ld/testsuite/ld-aarch64/copy-reloc-exe-2.s
58725c
new file mode 100644 (file)
58725c
index 0000000..d83658c
58725c
--- /dev/null
58725c
+++ b/ld/testsuite/ld-aarch64/copy-reloc-exe-2.s
58725c
@@ -0,0 +1,32 @@
58725c
+       # expect copy relocation for all these scenarios.
58725c
+       .global p
58725c
+       .global q
58725c
+       .global r
58725c
+       .section        .data.rel.ro,"aw",%progbits
58725c
+       .align  3
58725c
+       .type   p, %object
58725c
+       .size   p, 8
58725c
+p:
58725c
+       .xword  global_a
58725c
+
58725c
+       .type   q, %object
58725c
+       .size   q, 8
58725c
+q:
58725c
+       .xword  global_b
58725c
+
58725c
+       .type   r, %object
58725c
+       .size   r, 8
58725c
+r:
58725c
+       # Any pc-rel relocation as no dynamic linker support on AArch64.
58725c
+       .xword  global_c - .
58725c
+
58725c
+       .text
58725c
+       .global main
58725c
+main:
58725c
+       # Symbols are referenced by any other relocation against read-only
58725c
+       # section.
58725c
+       movz x0, :abs_g0_nc:global_a
58725c
+       adrp x1, global_b
58725c
+       # pc-rel.
58725c
+       adrp x2, global_d
58725c
+       add x2, x2, #:lo12:global_c
58725c
diff --git a/ld/testsuite/ld-aarch64/copy-reloc-exe-eliminate.s b/ld/testsuite/ld-aarch64/copy-reloc-exe-eliminate.s
58725c
new file mode 100644 (file)
58725c
index 0000000..33227aa
58725c
--- /dev/null
58725c
+++ b/ld/testsuite/ld-aarch64/copy-reloc-exe-eliminate.s
58725c
@@ -0,0 +1,7 @@
58725c
+       .global p
58725c
+       .section        .data.rel.ro,"aw",%progbits
58725c
+       .align  3
58725c
+       .type   p, %object
58725c
+       .size   p, 8
58725c
+p:
58725c
+       .xword  global_a
58725c
--- binutils.orig/ld/testsuite/ld-aarch64/copy-reloc-so.s	2017-10-10 16:56:06.347550451 +0100
58725c
+++ binutils-2.27/ld/testsuite/ld-aarch64/copy-reloc-so.s	2017-10-10 16:56:25.926321182 +0100
58725c
@@ -1,6 +1,25 @@
58725c
 	.global global_a
58725c
 	.type	global_a, %object
58725c
 	.size	global_a, 4
58725c
+
58725c
+       .global global_b
58725c
+       .type   global_b, %object
58725c
+       .size   global_b, 4
58725c
+
58725c
+       .global global_c
58725c
+       .type   global_c, %object
58725c
+       .size   global_c, 4
58725c
+
58725c
+       .global global_d
58725c
+       .type   global_d, %object
58725c
+       .size   global_d, 4
58725c
+
58725c
 	.data
58725c
 global_a:
58725c
 	.word 0xcafedead
58725c
+global_b:
58725c
+       .word 0xcafecafe
58725c
+global_c:
58725c
+       .word 0xdeadcafe
58725c
+global_d:
58725c
+       .word 0xdeaddead
58725c
--- binutils.orig/ld/testsuite/ld-aarch64/aarch64-elf.exp	2017-10-10 16:56:06.347550451 +0100
58725c
+++ binutils-2.27/ld/testsuite/ld-aarch64/aarch64-elf.exp	2017-10-10 16:58:19.629989701 +0100
58725c
@@ -292,6 +292,10 @@ set aarch64elflinktests {
58725c
     {} "copy-reloc-so.so"}
58725c
   {"ld-aarch64/exe with copy relocation" "-e0 tmpdir/copy-reloc-so.so" "" ""
58725c
     {copy-reloc-exe.s} {{objdump -R copy-reloc.d}} "copy-reloc"}
58725c
+  {"ld-aarch64/exe with copy relocation 2" "-e0 tmpdir/copy-reloc-so.so" "" ""
58725c
+    {copy-reloc-exe-2.s} {{objdump -R copy-reloc-2.d}} "copy-reloc-2"}
58725c
+  {"ld-aarch64/exe with copy relocation elimination" "-e0 tmpdir/copy-reloc-so.so" "" ""
58725c
+    {copy-reloc-exe-eliminate.s} {{objdump -R copy-reloc-eliminate.d}} "copy-reloc-elimination"}
58725c
 }
58725c
 
58725c
 run_ld_link_tests $aarch64elflinktests
58725c
--- binutils.orig/bfd/elfnn-aarch64.c	2017-10-10 16:56:05.783557056 +0100
58725c
+++ binutils-2.27/bfd/elfnn-aarch64.c	2017-10-10 17:15:02.559298576 +0100
58725c
@@ -246,7 +246,7 @@
58725c
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC		\
58725c
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1)
58725c
 
58725c
-#define ELIMINATE_COPY_RELOCS 0
58725c
+#define ELIMINATE_COPY_RELOCS 1
58725c
 
58725c
 /* Return size of a relocation entry.  HTAB is the bfd's
58725c
    elf_aarch64_link_hash_entry.  */
58725c
@@ -5154,12 +5154,25 @@ elfNN_aarch64_final_link_relocate (reloc
58725c
       /* When generating a shared object or relocatable executable, these
58725c
          relocations are copied into the output file to be resolved at
58725c
          run time.  */
58725c
-      if (((bfd_link_pic (info) == TRUE)
58725c
-	   || globals->root.is_relocatable_executable)
58725c
-	  && (input_section->flags & SEC_ALLOC)
58725c
-	  && (h == NULL
58725c
-	      || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
58725c
-	      || h->root.type != bfd_link_hash_undefweak))
58725c
+      if ((((bfd_link_pic (info) == TRUE)
58725c
+	    || globals->root.is_relocatable_executable)
58725c
+	   && (input_section->flags & SEC_ALLOC)
58725c
+	   && (h == NULL
58725c
+	       || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
58725c
+	       || h->root.type != bfd_link_hash_undefweak))
58725c
+	  /* Or we are creating an executable, we may need to keep relocations
58725c
+	     for symbols satisfied by a dynamic library if we manage to avoid
58725c
+	     copy relocs for the symbol.  */
58725c
+	  || (ELIMINATE_COPY_RELOCS
58725c
+	      && !bfd_link_pic (info)
58725c
+	      && h != NULL
58725c
+	      && (input_section->flags & SEC_ALLOC)
58725c
+	      && h->dynindx != -1
58725c
+	      && !h->non_got_ref
58725c
+	      && ((h->def_dynamic
58725c
+		   && !h->def_regular)
58725c
+		  || h->root.type == bfd_link_hash_undefweak
58725c
+		  || h->root.type == bfd_link_hash_undefined)))
58725c
 	{
58725c
 	  Elf_Internal_Rela outrel;
58725c
 	  bfd_byte *loc;
58725c
@@ -6777,15 +6790,22 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
58725c
 	    h->plt.refcount -= 1;
58725c
 	  break;
58725c
 
58725c
+	case BFD_RELOC_AARCH64_ADD_LO12:
58725c
 	case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
58725c
 	case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
58725c
 	case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
58725c
+	case BFD_RELOC_AARCH64_LDST128_LO12:
58725c
+	case BFD_RELOC_AARCH64_LDST16_LO12:
58725c
+	case BFD_RELOC_AARCH64_LDST32_LO12:
58725c
+	case BFD_RELOC_AARCH64_LDST64_LO12:
58725c
+	case BFD_RELOC_AARCH64_LDST8_LO12:
58725c
+	case BFD_RELOC_AARCH64_LD_LO19_PCREL:
58725c
 	case BFD_RELOC_AARCH64_MOVW_G0_NC:
58725c
 	case BFD_RELOC_AARCH64_MOVW_G1_NC:
58725c
 	case BFD_RELOC_AARCH64_MOVW_G2_NC:
58725c
 	case BFD_RELOC_AARCH64_MOVW_G3:
58725c
 	case BFD_RELOC_AARCH64_NN:
58725c
-	  if (h != NULL && bfd_link_executable (info))
58725c
+	  if (h != NULL && bfd_link_pic (info))
58725c
 	    {
58725c
 	      if (h->plt.refcount > 0)
58725c
 		h->plt.refcount -= 1;
58725c
@@ -7158,6 +7178,41 @@ elfNN_aarch64_check_relocs (bfd *abfd, s
58725c
 
58725c
       switch (bfd_r_type)
58725c
 	{
58725c
+	case BFD_RELOC_AARCH64_MOVW_G0_NC:
58725c
+	case BFD_RELOC_AARCH64_MOVW_G1_NC:
58725c
+	case BFD_RELOC_AARCH64_MOVW_G2_NC:
58725c
+	case BFD_RELOC_AARCH64_MOVW_G3:
58725c
+	  if (bfd_link_pic (info))
58725c
+	    {
58725c
+	      int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
58725c
+	      _bfd_error_handler
58725c
+		/* xgettext:c-format */
58725c
+		(_("%B: relocation %s against `%s' can not be used when making "
58725c
+		   "a shared object; recompile with -fPIC"),
58725c
+		 abfd, elfNN_aarch64_howto_table[howto_index].name,
58725c
+		 (h) ? h->root.root.string : "a local symbol");
58725c
+	      bfd_set_error (bfd_error_bad_value);
58725c
+	      return FALSE;
58725c
+	    }
58725c
+	  /* Fall through.  */
58725c
+
58725c
+	case BFD_RELOC_AARCH64_16_PCREL:
58725c
+	case BFD_RELOC_AARCH64_32_PCREL:
58725c
+	case BFD_RELOC_AARCH64_64_PCREL:
58725c
+	case BFD_RELOC_AARCH64_ADD_LO12:
58725c
+	case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
58725c
+	case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
58725c
+	case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
58725c
+	case BFD_RELOC_AARCH64_LDST128_LO12:
58725c
+	case BFD_RELOC_AARCH64_LDST16_LO12:
58725c
+	case BFD_RELOC_AARCH64_LDST32_LO12:
58725c
+	case BFD_RELOC_AARCH64_LDST64_LO12:
58725c
+	case BFD_RELOC_AARCH64_LDST8_LO12:
58725c
+	case BFD_RELOC_AARCH64_LD_LO19_PCREL:
58725c
+	  if (h == NULL || bfd_link_pic (info))
58725c
+	    break;
58725c
+	  /* Fall through.  */
58725c
+
58725c
 	case BFD_RELOC_AARCH64_NN:
58725c
 
58725c
 	  /* We don't need to handle relocs into sections not going into
58725c
@@ -7176,12 +7231,32 @@ elfNN_aarch64_check_relocs (bfd *abfd, s
58725c
 
58725c
 	  /* No need to do anything if we're not creating a shared
58725c
 	     object.  */
58725c
-	  if (! bfd_link_pic (info))
58725c
-	    break;
58725c
+         if (!(bfd_link_pic (info)
58725c
+               /* If on the other hand, we are creating an executable, we
58725c
+                  may need to keep relocations for symbols satisfied by a
58725c
+                  dynamic library if we manage to avoid copy relocs for the
58725c
+                  symbol.
58725c
+
58725c
+                  NOTE: Currently, there is no support of copy relocs
58725c
+                  elimination on pc-relative relocation types, because there is
58725c
+                  no dynamic relocation support for them in glibc.  We still
58725c
+                  record the dynamic symbol reference for them.  This is
58725c
+                  because one symbol may be referenced by both absolute
58725c
+                  relocation (for example, BFD_RELOC_AARCH64_NN) and
58725c
+                  pc-relative relocation.  We need full symbol reference
58725c
+                  information to make correct decision later in
58725c
+                  elfNN_aarch64_adjust_dynamic_symbol.  */
58725c
+               || (ELIMINATE_COPY_RELOCS
58725c
+                   && !bfd_link_pic (info)
58725c
+                   && h != NULL
58725c
+                   && (h->root.type == bfd_link_hash_defweak
58725c
+                       || !h->def_regular))))
58725c
+	   break;
58725c
 
58725c
 	  {
58725c
 	    struct elf_dyn_relocs *p;
58725c
 	    struct elf_dyn_relocs **head;
58725c
+	    int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
58725c
 
58725c
 	    /* We must copy these reloc types into the output file.
58725c
 	       Create a reloc section in dynobj and make room for
58725c
@@ -7245,6 +7320,8 @@ elfNN_aarch64_check_relocs (bfd *abfd, s
58725c
 
58725c
 	    p->count += 1;
58725c
 
58725c
+	    if (elfNN_aarch64_howto_table[howto_index].pc_relative)
58725c
+	      p->pc_count += 1;
58725c
 	  }
58725c
 	  break;
58725c
 
58725c
@@ -7348,42 +7425,6 @@ elfNN_aarch64_check_relocs (bfd *abfd, s
58725c
 	    break;
58725c
 	  }
58725c
 
58725c
-	case BFD_RELOC_AARCH64_MOVW_G0_NC:
58725c
-	case BFD_RELOC_AARCH64_MOVW_G1_NC:
58725c
-	case BFD_RELOC_AARCH64_MOVW_G2_NC:
58725c
-	case BFD_RELOC_AARCH64_MOVW_G3:
58725c
-	  if (bfd_link_pic (info))
58725c
-	    {
58725c
-	      int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
58725c
-	      (*_bfd_error_handler)
58725c
-		(_("%B: relocation %s against `%s' can not be used when making "
58725c
-		   "a shared object; recompile with -fPIC"),
58725c
-		 abfd, elfNN_aarch64_howto_table[howto_index].name,
58725c
-		 (h) ? h->root.root.string : "a local symbol");
58725c
-	      bfd_set_error (bfd_error_bad_value);
58725c
-	      return FALSE;
58725c
-	    }
58725c
-
58725c
-	case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
58725c
-	case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
58725c
-	case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
58725c
-	  if (h != NULL && bfd_link_executable (info))
58725c
-	    {
58725c
-	      /* If this reloc is in a read-only section, we might
58725c
-		 need a copy reloc.  We can't check reliably at this
58725c
-		 stage whether the section is read-only, as input
58725c
-		 sections have not yet been mapped to output sections.
58725c
-		 Tentatively set the flag for now, and correct in
58725c
-		 adjust_dynamic_symbol.  */
58725c
-	      h->non_got_ref = 1;
58725c
-	      h->plt.refcount += 1;
58725c
-	      h->pointer_equality_needed = 1;
58725c
-	    }
58725c
-	  /* FIXME:: RR need to handle these in shared libraries
58725c
-	     and essentially bomb out as these being non-PIC
58725c
-	     relocations in shared libraries.  */
58725c
-	  break;
58725c
-
58725c
 	case BFD_RELOC_AARCH64_CALL26:
58725c
 	case BFD_RELOC_AARCH64_JUMP26:
58725c
 	  /* If this is a local symbol then we resolve it