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

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