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