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

0b07f1
diff -rupN binutils.orig/bfd/elfnn-aarch64.c binutils-2.28/bfd/elfnn-aarch64.c
0b07f1
--- binutils.orig/bfd/elfnn-aarch64.c	2017-06-08 09:11:46.364977859 +0100
0b07f1
+++ binutils-2.28/bfd/elfnn-aarch64.c	2017-06-08 09:15:46.901961364 +0100
0b07f1
@@ -246,7 +246,7 @@
0b07f1
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC		\
0b07f1
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1)
0b07f1
 
0b07f1
-#define ELIMINATE_COPY_RELOCS 0
0b07f1
+#define ELIMINATE_COPY_RELOCS 1
0b07f1
 
0b07f1
 /* Return size of a relocation entry.  HTAB is the bfd's
0b07f1
    elf_aarch64_link_hash_entry.  */
0b07f1
@@ -5152,12 +5152,25 @@ elfNN_aarch64_final_link_relocate (reloc
0b07f1
       /* When generating a shared object or relocatable executable, these
0b07f1
          relocations are copied into the output file to be resolved at
0b07f1
          run time.  */
0b07f1
-      if (((bfd_link_pic (info) == TRUE)
0b07f1
-	   || globals->root.is_relocatable_executable)
0b07f1
-	  && (input_section->flags & SEC_ALLOC)
0b07f1
-	  && (h == NULL
0b07f1
-	      || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
0b07f1
-	      || h->root.type != bfd_link_hash_undefweak))
0b07f1
+      if (((bfd_link_pic (info)
0b07f1
+	    || globals->root.is_relocatable_executable)
0b07f1
+	   && (input_section->flags & SEC_ALLOC)
0b07f1
+	   && (h == NULL
0b07f1
+	       || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
0b07f1
+	       || h->root.type != bfd_link_hash_undefweak))
0b07f1
+	  /* Or we are creating an executable, we may need to keep relocations
0b07f1
+	     for symbols satisfied by a dynamic library if we manage to avoid
0b07f1
+	     copy relocs for the symbol.  */
0b07f1
+	  || (ELIMINATE_COPY_RELOCS
0b07f1
+	      && !bfd_link_pic (info)
0b07f1
+	      && h != NULL
0b07f1
+	      && (input_section->flags & SEC_ALLOC)
0b07f1
+	      && h->dynindx != -1
0b07f1
+	      && !h->non_got_ref
0b07f1
+	      && ((h->def_dynamic
0b07f1
+		   && !h->def_regular)
0b07f1
+		  || h->root.type == bfd_link_hash_undefweak
0b07f1
+		  || h->root.type == bfd_link_hash_undefined)))
0b07f1
 	{
0b07f1
 	  Elf_Internal_Rela outrel;
0b07f1
 	  bfd_byte *loc;
0b07f1
@@ -6822,6 +6835,25 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
0b07f1
   return TRUE;
0b07f1
 }
0b07f1
 
0b07f1
+/* Return true if we have dynamic relocs against EH or any of its weak
0b07f1
+   aliases, that apply to read-only sections.  */
0b07f1
+
0b07f1
+static bfd_boolean
0b07f1
+alias_readonly_dynrelocs (struct elf_aarch64_link_hash_entry *eh)
0b07f1
+{
0b07f1
+  struct elf_dyn_relocs *p;
0b07f1
+  asection *s;
0b07f1
+
0b07f1
+  for (p = eh->dyn_relocs; p != NULL; p = p->next)
0b07f1
+    {
0b07f1
+      s = p->sec->output_section;
0b07f1
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
0b07f1
+	return TRUE;
0b07f1
+    }
0b07f1
+
0b07f1
+  return FALSE;
0b07f1
+}
0b07f1
+
0b07f1
 /* Adjust a symbol defined by a dynamic object and referenced by a
0b07f1
    regular object.  The current definition is in some section of the
0b07f1
    dynamic object, but we're not including those sections.  We have to
0b07f1
@@ -6895,6 +6927,19 @@ elfNN_aarch64_adjust_dynamic_symbol (str
0b07f1
       return TRUE;
0b07f1
     }
0b07f1
 
0b07f1
+  if (ELIMINATE_COPY_RELOCS)
0b07f1
+    {
0b07f1
+      struct elf_aarch64_link_hash_entry *eh;
0b07f1
+      /* If we didn't find any dynamic relocs in read-only sections, then
0b07f1
+	 we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
0b07f1
+      eh = (struct elf_aarch64_link_hash_entry *) h;
0b07f1
+      if (eh->dyn_relocs && !alias_readonly_dynrelocs (eh))
0b07f1
+	{
0b07f1
+	  h->non_got_ref = 0;
0b07f1
+	  return TRUE;
0b07f1
+	}
0b07f1
+    }
0b07f1
+
0b07f1
   /* We must allocate the symbol in our .dynbss section, which will
0b07f1
      become part of the .bss section of the executable.  There will be
0b07f1
      an entry for this symbol in the .dynsym section.  The dynamic
0b07f1
@@ -7167,7 +7212,16 @@ elfNN_aarch64_check_relocs (bfd *abfd, s
0b07f1
 
0b07f1
 	  /* No need to do anything if we're not creating a shared
0b07f1
 	     object.  */
0b07f1
-	  if (! bfd_link_pic (info))
0b07f1
+	  if (!(bfd_link_pic (info)
0b07f1
+		/* If on the other hand, we are creating an executable, we
0b07f1
+		   may need to keep relocations for symbols satisfied by a
0b07f1
+		   dynamic library if we manage to avoid copy relocs for the
0b07f1
+		   symbol.  */
0b07f1
+		|| (ELIMINATE_COPY_RELOCS
0b07f1
+		    && !bfd_link_pic (info)
0b07f1
+		    && h != NULL
0b07f1
+		    && (h->root.type == bfd_link_hash_defweak
0b07f1
+			|| !h->def_regular))))
0b07f1
 	    break;
0b07f1
 
0b07f1
 	  {
0b07f1
diff -rupN binutils.orig/ld/testsuite/ld-aarch64/aarch64-elf.exp binutils-2.28/ld/testsuite/ld-aarch64/aarch64-elf.exp
0b07f1
--- binutils.orig/ld/testsuite/ld-aarch64/aarch64-elf.exp	2017-06-08 09:11:54.845871503 +0100
0b07f1
+++ binutils-2.28/ld/testsuite/ld-aarch64/aarch64-elf.exp	2017-06-08 09:16:34.984358379 +0100
0b07f1
@@ -323,6 +323,8 @@ set aarch64elflinktests {
0b07f1
     {} "copy-reloc-so.so"}
0b07f1
   {"ld-aarch64/exe with copy relocation" "-e0 tmpdir/copy-reloc-so.so" "" ""
0b07f1
     {copy-reloc-exe.s} {{objdump -R copy-reloc.d}} "copy-reloc"}
0b07f1
+  {"ld-aarch64/exe with copy relocation elimination" "-e0 tmpdir/copy-reloc-so.so" "" ""
0b07f1
+    {copy-reloc-exe-eliminate.s} {{objdump -R copy-reloc-eliminate.d}} "copy-reloc-elimination"}
0b07f1
 }
0b07f1
 
0b07f1
 run_ld_link_tests $aarch64elflinktests
0b07f1
diff -rupN binutils.orig/ld/testsuite/ld-aarch64/copy-reloc-eliminate.d binutils-2.28/ld/testsuite/ld-aarch64/copy-reloc-eliminate.d
0b07f1
--- binutils.orig/ld/testsuite/ld-aarch64/copy-reloc-eliminate.d	1970-01-01 01:00:00.000000000 +0100
0b07f1
+++ binutils-2.28/ld/testsuite/ld-aarch64/copy-reloc-eliminate.d	2017-06-08 09:12:10.191679056 +0100
0b07f1
@@ -0,0 +1,4 @@
0b07f1
+.*
0b07f1
+DYNAMIC RELOCATION RECORDS
0b07f1
+OFFSET.*TYPE.*VALUE.*
0b07f1
+.*R_AARCH64_ABS64.*global_a
0b07f1
diff -rupN binutils.orig/ld/testsuite/ld-aarch64/copy-reloc-exe-eliminate.s binutils-2.28/ld/testsuite/ld-aarch64/copy-reloc-exe-eliminate.s
0b07f1
--- binutils.orig/ld/testsuite/ld-aarch64/copy-reloc-exe-eliminate.s	1970-01-01 01:00:00.000000000 +0100
0b07f1
+++ binutils-2.28/ld/testsuite/ld-aarch64/copy-reloc-exe-eliminate.s	2017-06-08 09:12:10.191679056 +0100
0b07f1
@@ -0,0 +1,7 @@
0b07f1
+	.global	p
0b07f1
+	.section	.data.rel.ro,"aw",%progbits
0b07f1
+	.align	3
0b07f1
+	.type	p, %object
0b07f1
+	.size	p, 8
0b07f1
+p:
0b07f1
+	.xword	global_a
0b07f1
diff -rupN binutils.orig/bfd/elfnn-aarch64.c binutils-2.28/bfd/elfnn-aarch64.c
0b07f1
--- binutils.orig/bfd/elfnn-aarch64.c	2017-06-15 15:30:17.620175425 +0100
0b07f1
+++ binutils-2.28/bfd/elfnn-aarch64.c	2017-06-15 15:31:21.415444817 +0100
0b07f1
@@ -6812,15 +6812,22 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
0b07f1
 	    h->plt.refcount -= 1;
0b07f1
 	  break;
0b07f1
 
0b07f1
+	case BFD_RELOC_AARCH64_ADD_LO12:
0b07f1
 	case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
0b07f1
 	case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
0b07f1
 	case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
0b07f1
+	case BFD_RELOC_AARCH64_LDST128_LO12:
0b07f1
+	case BFD_RELOC_AARCH64_LDST16_LO12:
0b07f1
+	case BFD_RELOC_AARCH64_LDST32_LO12:
0b07f1
+	case BFD_RELOC_AARCH64_LDST64_LO12:
0b07f1
+	case BFD_RELOC_AARCH64_LDST8_LO12:
0b07f1
+	case BFD_RELOC_AARCH64_LD_LO19_PCREL:
0b07f1
 	case BFD_RELOC_AARCH64_MOVW_G0_NC:
0b07f1
 	case BFD_RELOC_AARCH64_MOVW_G1_NC:
0b07f1
 	case BFD_RELOC_AARCH64_MOVW_G2_NC:
0b07f1
 	case BFD_RELOC_AARCH64_MOVW_G3:
0b07f1
 	case BFD_RELOC_AARCH64_NN:
0b07f1
-	  if (h != NULL && bfd_link_executable (info))
0b07f1
+	  if (h != NULL && !bfd_link_pic (info))
0b07f1
 	    {
0b07f1
 	      if (h->plt.refcount > 0)
0b07f1
 		h->plt.refcount -= 1;
0b07f1
@@ -6835,18 +6842,24 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
0b07f1
   return TRUE;
0b07f1
 }
0b07f1
 
0b07f1
-/* Return true if we have dynamic relocs against EH or any of its weak
0b07f1
-   aliases, that apply to read-only sections.  */
0b07f1
+/* Return true if we need copy relocation against EH.  */
0b07f1
 
0b07f1
 static bfd_boolean
0b07f1
-alias_readonly_dynrelocs (struct elf_aarch64_link_hash_entry *eh)
0b07f1
+need_copy_relocation_p (struct elf_aarch64_link_hash_entry *eh)
0b07f1
 {
0b07f1
   struct elf_dyn_relocs *p;
0b07f1
   asection *s;
0b07f1
 
0b07f1
   for (p = eh->dyn_relocs; p != NULL; p = p->next)
0b07f1
     {
0b07f1
+      /* If there is any pc-relative reference, we need to keep copy relocation
0b07f1
+	 to avoid propagating the relocation into runtime that current glibc
0b07f1
+	 does not support.  */
0b07f1
+      if (p->pc_count)
0b07f1
+	return TRUE;
0b07f1
+
0b07f1
       s = p->sec->output_section;
0b07f1
+      /* Need copy relocation if it's against read-only section.  */
0b07f1
       if (s != NULL && (s->flags & SEC_READONLY) != 0)
0b07f1
 	return TRUE;
0b07f1
     }
0b07f1
@@ -6933,7 +6946,7 @@ elfNN_aarch64_adjust_dynamic_symbol (str
0b07f1
       /* If we didn't find any dynamic relocs in read-only sections, then
0b07f1
 	 we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
0b07f1
       eh = (struct elf_aarch64_link_hash_entry *) h;
0b07f1
-      if (eh->dyn_relocs && !alias_readonly_dynrelocs (eh))
0b07f1
+      if (!need_copy_relocation_p (eh))
0b07f1
 	{
0b07f1
 	  h->non_got_ref = 0;
0b07f1
 	  return TRUE;
0b07f1
@@ -7194,6 +7207,41 @@ elfNN_aarch64_check_relocs (bfd *abfd, s
0b07f1
 
0b07f1
       switch (bfd_r_type)
0b07f1
 	{
0b07f1
+	case BFD_RELOC_AARCH64_MOVW_G0_NC:
0b07f1
+	case BFD_RELOC_AARCH64_MOVW_G1_NC:
0b07f1
+	case BFD_RELOC_AARCH64_MOVW_G2_NC:
0b07f1
+	case BFD_RELOC_AARCH64_MOVW_G3:
0b07f1
+	  if (bfd_link_pic (info))
0b07f1
+	    {
0b07f1
+	      int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
0b07f1
+	      _bfd_error_handler
0b07f1
+		/* xgettext:c-format */
0b07f1
+		(_("%B: relocation %s against `%s' can not be used when making "
0b07f1
+		   "a shared object; recompile with -fPIC"),
0b07f1
+		 abfd, elfNN_aarch64_howto_table[howto_index].name,
0b07f1
+		 (h) ? h->root.root.string : "a local symbol");
0b07f1
+	      bfd_set_error (bfd_error_bad_value);
0b07f1
+	      return FALSE;
0b07f1
+	    }
0b07f1
+	  /* Fall through.  */
0b07f1
+
0b07f1
+	case BFD_RELOC_AARCH64_16_PCREL:
0b07f1
+	case BFD_RELOC_AARCH64_32_PCREL:
0b07f1
+	case BFD_RELOC_AARCH64_64_PCREL:
0b07f1
+	case BFD_RELOC_AARCH64_ADD_LO12:
0b07f1
+	case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
0b07f1
+	case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
0b07f1
+	case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
0b07f1
+	case BFD_RELOC_AARCH64_LDST128_LO12:
0b07f1
+	case BFD_RELOC_AARCH64_LDST16_LO12:
0b07f1
+	case BFD_RELOC_AARCH64_LDST32_LO12:
0b07f1
+	case BFD_RELOC_AARCH64_LDST64_LO12:
0b07f1
+	case BFD_RELOC_AARCH64_LDST8_LO12:
0b07f1
+	case BFD_RELOC_AARCH64_LD_LO19_PCREL:
0b07f1
+	  if (h == NULL || bfd_link_pic (info))
0b07f1
+	    break;
0b07f1
+	  /* Fall through.  */
0b07f1
+
0b07f1
 	case BFD_RELOC_AARCH64_NN:
0b07f1
 
0b07f1
 	  /* We don't need to handle relocs into sections not going into
0b07f1
@@ -7216,7 +7264,17 @@ elfNN_aarch64_check_relocs (bfd *abfd, s
0b07f1
 		/* If on the other hand, we are creating an executable, we
0b07f1
 		   may need to keep relocations for symbols satisfied by a
0b07f1
 		   dynamic library if we manage to avoid copy relocs for the
0b07f1
-		   symbol.  */
0b07f1
+		   symbol.
0b07f1
+
0b07f1
+		   NOTE: Currently, there is no support of copy relocs
0b07f1
+		   elimination on pc-relative relocation types, because there is
0b07f1
+		   no dynamic relocation support for them in glibc.  We still
0b07f1
+		   record the dynamic symbol reference for them.  This is
0b07f1
+		   because one symbol may be referenced by both absolute
0b07f1
+		   relocation (for example, BFD_RELOC_AARCH64_NN) and
0b07f1
+		   pc-relative relocation.  We need full symbol reference
0b07f1
+		   information to make correct decision later in
0b07f1
+		   elfNN_aarch64_adjust_dynamic_symbol.  */
0b07f1
 		|| (ELIMINATE_COPY_RELOCS
0b07f1
 		    && !bfd_link_pic (info)
0b07f1
 		    && h != NULL
0b07f1
@@ -7227,6 +7285,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, s
0b07f1
 	  {
0b07f1
 	    struct elf_dyn_relocs *p;
0b07f1
 	    struct elf_dyn_relocs **head;
0b07f1
+	    int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
0b07f1
 
0b07f1
 	    /* We must copy these reloc types into the output file.
0b07f1
 	       Create a reloc section in dynobj and make room for
0b07f1
@@ -7290,6 +7349,8 @@ elfNN_aarch64_check_relocs (bfd *abfd, s
0b07f1
 
0b07f1
 	    p->count += 1;
0b07f1
 
0b07f1
+	    if (elfNN_aarch64_howto_table[howto_index].pc_relative)
0b07f1
+	      p->pc_count += 1;
0b07f1
 	  }
0b07f1
 	  break;
0b07f1
 
0b07f1
@@ -7393,44 +7454,6 @@ elfNN_aarch64_check_relocs (bfd *abfd, s
0b07f1
 	    break;
0b07f1
 	  }
0b07f1
 
0b07f1
-	case BFD_RELOC_AARCH64_MOVW_G0_NC:
0b07f1
-	case BFD_RELOC_AARCH64_MOVW_G1_NC:
0b07f1
-	case BFD_RELOC_AARCH64_MOVW_G2_NC:
0b07f1
-	case BFD_RELOC_AARCH64_MOVW_G3:
0b07f1
-	  if (bfd_link_pic (info))
0b07f1
-	    {
0b07f1
-	      int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
0b07f1
-	      _bfd_error_handler
0b07f1
-		/* xgettext:c-format */
0b07f1
-		(_("%B: relocation %s against `%s' can not be used when making "
0b07f1
-		   "a shared object; recompile with -fPIC"),
0b07f1
-		 abfd, elfNN_aarch64_howto_table[howto_index].name,
0b07f1
-		 (h) ? h->root.root.string : "a local symbol");
0b07f1
-	      bfd_set_error (bfd_error_bad_value);
0b07f1
-	      return FALSE;
0b07f1
-	    }
0b07f1
-	  /* Fall through.  */
0b07f1
-
0b07f1
-	case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
0b07f1
-	case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
0b07f1
-	case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
0b07f1
-	  if (h != NULL && bfd_link_executable (info))
0b07f1
-	    {
0b07f1
-	      /* If this reloc is in a read-only section, we might
0b07f1
-		 need a copy reloc.  We can't check reliably at this
0b07f1
-		 stage whether the section is read-only, as input
0b07f1
-		 sections have not yet been mapped to output sections.
0b07f1
-		 Tentatively set the flag for now, and correct in
0b07f1
-		 adjust_dynamic_symbol.  */
0b07f1
-	      h->non_got_ref = 1;
0b07f1
-	      h->plt.refcount += 1;
0b07f1
-	      h->pointer_equality_needed = 1;
0b07f1
-	    }
0b07f1
-	  /* FIXME:: RR need to handle these in shared libraries
0b07f1
-	     and essentially bomb out as these being non-PIC
0b07f1
-	     relocations in shared libraries.  */
0b07f1
-	  break;
0b07f1
-
0b07f1
 	case BFD_RELOC_AARCH64_CALL26:
0b07f1
 	case BFD_RELOC_AARCH64_JUMP26:
0b07f1
 	  /* If this is a local symbol then we resolve it
0b07f1
diff -rupN binutils.orig/ld/testsuite/ld-aarch64/aarch64-elf.exp binutils-2.28/ld/testsuite/ld-aarch64/aarch64-elf.exp
0b07f1
--- binutils.orig/ld/testsuite/ld-aarch64/aarch64-elf.exp	2017-06-15 15:30:28.779047629 +0100
0b07f1
+++ binutils-2.28/ld/testsuite/ld-aarch64/aarch64-elf.exp	2017-06-15 15:31:21.415444817 +0100
0b07f1
@@ -323,6 +323,8 @@ set aarch64elflinktests {
0b07f1
     {} "copy-reloc-so.so"}
0b07f1
   {"ld-aarch64/exe with copy relocation" "-e0 tmpdir/copy-reloc-so.so" "" ""
0b07f1
     {copy-reloc-exe.s} {{objdump -R copy-reloc.d}} "copy-reloc"}
0b07f1
+  {"ld-aarch64/exe with copy relocation 2" "-e0 tmpdir/copy-reloc-so.so" "" ""
0b07f1
+    {copy-reloc-exe-2.s} {{objdump -R copy-reloc-2.d}} "copy-reloc-2"}
0b07f1
   {"ld-aarch64/exe with copy relocation elimination" "-e0 tmpdir/copy-reloc-so.so" "" ""
0b07f1
     {copy-reloc-exe-eliminate.s} {{objdump -R copy-reloc-eliminate.d}} "copy-reloc-elimination"}
0b07f1
 }
0b07f1
diff -rupN binutils.orig/ld/testsuite/ld-aarch64/copy-reloc-2.d binutils-2.28/ld/testsuite/ld-aarch64/copy-reloc-2.d
0b07f1
--- binutils.orig/ld/testsuite/ld-aarch64/copy-reloc-2.d	1970-01-01 01:00:00.000000000 +0100
0b07f1
+++ binutils-2.28/ld/testsuite/ld-aarch64/copy-reloc-2.d	2017-06-15 15:31:21.415444817 +0100
0b07f1
@@ -0,0 +1,7 @@
0b07f1
+.*
0b07f1
+DYNAMIC RELOCATION RECORDS
0b07f1
+OFFSET.*TYPE.*VALUE.*
0b07f1
+.*R_AARCH64_COPY.*global_[abcd]
0b07f1
+.*R_AARCH64_COPY.*global_[abcd]
0b07f1
+.*R_AARCH64_COPY.*global_[abcd]
0b07f1
+.*R_AARCH64_COPY.*global_[abcd]
0b07f1
diff -rupN binutils.orig/ld/testsuite/ld-aarch64/copy-reloc-exe-2.s binutils-2.28/ld/testsuite/ld-aarch64/copy-reloc-exe-2.s
0b07f1
--- binutils.orig/ld/testsuite/ld-aarch64/copy-reloc-exe-2.s	1970-01-01 01:00:00.000000000 +0100
0b07f1
+++ binutils-2.28/ld/testsuite/ld-aarch64/copy-reloc-exe-2.s	2017-06-15 15:31:21.415444817 +0100
0b07f1
@@ -0,0 +1,32 @@
0b07f1
+	# expect copy relocation for all these scenarios.
0b07f1
+	.global	p
0b07f1
+	.global	q
0b07f1
+	.global	r
0b07f1
+	.section	.data.rel.ro,"aw",%progbits
0b07f1
+	.align	3
0b07f1
+	.type	p, %object
0b07f1
+	.size	p, 8
0b07f1
+p:
0b07f1
+	.xword	global_a
0b07f1
+
0b07f1
+	.type	q, %object
0b07f1
+	.size	q, 8
0b07f1
+q:
0b07f1
+	.xword	global_b
0b07f1
+
0b07f1
+	.type	r, %object
0b07f1
+	.size	r, 8
0b07f1
+r:
0b07f1
+	# Any pc-rel relocation as no dynamic linker support on AArch64.
0b07f1
+	.xword	global_c - .
0b07f1
+
0b07f1
+	.text
0b07f1
+	.global main
0b07f1
+main:
0b07f1
+	# Symbols are referenced by any other relocation against read-only
0b07f1
+	# section.
0b07f1
+	movz x0, :abs_g0_nc:global_a
0b07f1
+	adrp x1, global_b
0b07f1
+	# pc-rel.
0b07f1
+	adrp x2, global_d
0b07f1
+	add x2, x2, #:lo12:global_c
0b07f1
diff -rupN binutils.orig/ld/testsuite/ld-aarch64/copy-reloc-so.s binutils-2.28/ld/testsuite/ld-aarch64/copy-reloc-so.s
0b07f1
--- binutils.orig/ld/testsuite/ld-aarch64/copy-reloc-so.s	2017-06-15 15:30:28.781047606 +0100
0b07f1
+++ binutils-2.28/ld/testsuite/ld-aarch64/copy-reloc-so.s	2017-06-15 15:31:21.415444817 +0100
0b07f1
@@ -1,6 +1,25 @@
0b07f1
 	.global global_a
0b07f1
 	.type	global_a, %object
0b07f1
 	.size	global_a, 4
0b07f1
+
0b07f1
+	.global global_b
0b07f1
+	.type	global_b, %object
0b07f1
+	.size	global_b, 4
0b07f1
+
0b07f1
+	.global global_c
0b07f1
+	.type	global_c, %object
0b07f1
+	.size	global_c, 4
0b07f1
+
0b07f1
+	.global global_d
0b07f1
+	.type	global_d, %object
0b07f1
+	.size	global_d, 4
0b07f1
+
0b07f1
 	.data
0b07f1
 global_a:
0b07f1
 	.word 0xcafedead
0b07f1
+global_b:
0b07f1
+	.word 0xcafecafe
0b07f1
+global_c:
0b07f1
+	.word 0xdeadcafe
0b07f1
+global_d:
0b07f1
+	.word 0xdeaddead