[AArch64] Allow COPY relocation elimination
authorJiong Wang <jiong.wang@arm.com>
Wed, 7 Jun 2017 11:05:39 +0000 (12:05 +0100)
committerJiong Wang <jiong.wang@arm.com>
Thu, 8 Jun 2017 08:43:39 +0000 (09:43 +0100)
  As discussed at the PR, this patch tries to avoid COPY relocation generation
and propagate the original relocation into runtime if it was relocating on
writable section.  The ELIMINATE_COPY_RELOCS has been set to true and it's
underlying infrastructure has been improved so that the COPY reloc elimination
at least working on absoluate relocations (ABS64) after this patch.

bfd/
        PR ld/21532
        * elfnn-aarch64.c (ELIMINATE_COPY_RELOCS): Set to 1.
        (elfNN_aarch64_final_link_relocate): Also propagate relocations to
        runtime for copy relocation elimination cases.
        (alias_readonly_dynrelocs): New function.
        (elfNN_aarch64_adjust_dynamic_symbol): Keep the dynamic relocs instead
        of generating copy relocation if it is not against read-only sections.
        (elfNN_aarch64_check_relocs): Likewise.

ld/
        * testsuite/ld-aarch64/copy-reloc-eliminate.d: New test.
        * testsuite/ld-aarch64/copy-reloc-exe-eliminate.s: New test source file.
        * testsuite/ld-aarch64/aarch64-elf.exp: Run new testcase.

bfd/ChangeLog
bfd/elfnn-aarch64.c
ld/ChangeLog
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/copy-reloc-eliminate.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/copy-reloc-exe-eliminate.s [new file with mode: 0644]

index b8286335233f430c1ce80c5a97f2c6338f03f925..a14ff72259781430aed0ca363759bbd82ff68d0d 100644 (file)
@@ -1,3 +1,14 @@
+2017-06-08  Jiong Wang <jiong.wang@arm.com>
+
+       PR ld/21532
+       * elfnn-aarch64.c (ELIMINATE_COPY_RELOCS): Set to 1.
+       (elfNN_aarch64_final_link_relocate): Also propagate relocations to
+       runtime for copy relocation elimination cases.
+       (alias_readonly_dynrelocs): New function.
+       (elfNN_aarch64_adjust_dynamic_symbol): Keep the dynamic relocs instead
+       of generating copy relocation if it is not against read-only sections.
+       (elfNN_aarch64_check_relocs): Likewise.
+
 2017-06-06  Jose E. Marchesi  <jose.marchesi@oracle.com>
 
        * elf.c (setup_group): Make sure BFD sections are created for all
index 1edf2a0bdead06a2f808a950c234fcd601714177..542c98a46f0d46649d4c631cb1f9d759e720f5b2 100644 (file)
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC          \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1)
 
-#define ELIMINATE_COPY_RELOCS 0
+#define ELIMINATE_COPY_RELOCS 1
 
 /* Return size of a relocation entry.  HTAB is the bfd's
    elf_aarch64_link_hash_entry.  */
@@ -5169,12 +5169,25 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
       /* When generating a shared object or relocatable executable, these
          relocations are copied into the output file to be resolved at
          run time.  */
-      if ((bfd_link_pic (info)
-          || globals->root.is_relocatable_executable)
-         && (input_section->flags & SEC_ALLOC)
-         && (h == NULL
-             || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-             || h->root.type != bfd_link_hash_undefweak))
+      if (((bfd_link_pic (info)
+           || globals->root.is_relocatable_executable)
+          && (input_section->flags & SEC_ALLOC)
+          && (h == NULL
+              || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+              || h->root.type != bfd_link_hash_undefweak))
+         /* Or we are creating an executable, we may need to keep relocations
+            for symbols satisfied by a dynamic library if we manage to avoid
+            copy relocs for the symbol.  */
+         || (ELIMINATE_COPY_RELOCS
+             && !bfd_link_pic (info)
+             && h != NULL
+             && (input_section->flags & SEC_ALLOC)
+             && h->dynindx != -1
+             && !h->non_got_ref
+             && ((h->def_dynamic
+                  && !h->def_regular)
+                 || h->root.type == bfd_link_hash_undefweak
+                 || h->root.type == bfd_link_hash_undefined)))
        {
          Elf_Internal_Rela outrel;
          bfd_byte *loc;
@@ -6869,6 +6882,25 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
   return TRUE;
 }
 
+/* Return true if we have dynamic relocs against EH or any of its weak
+   aliases, that apply to read-only sections.  */
+
+static bfd_boolean
+alias_readonly_dynrelocs (struct elf_aarch64_link_hash_entry *eh)
+{
+  struct elf_dyn_relocs *p;
+  asection *s;
+
+  for (p = eh->dyn_relocs; p != NULL; p = p->next)
+    {
+      s = p->sec->output_section;
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+       return TRUE;
+    }
+
+  return FALSE;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -6942,6 +6974,19 @@ elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info *info,
       return TRUE;
     }
 
+  if (ELIMINATE_COPY_RELOCS)
+    {
+      struct elf_aarch64_link_hash_entry *eh;
+      /* If we didn't find any dynamic relocs in read-only sections, then
+        we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
+      eh = (struct elf_aarch64_link_hash_entry *) h;
+      if (eh->dyn_relocs && !alias_readonly_dynrelocs (eh))
+       {
+         h->non_got_ref = 0;
+         return TRUE;
+       }
+    }
+
   /* We must allocate the symbol in our .dynbss section, which will
      become part of the .bss section of the executable.  There will be
      an entry for this symbol in the .dynsym section.  The dynamic
@@ -7214,7 +7259,16 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
          /* No need to do anything if we're not creating a shared
             object.  */
-         if (! bfd_link_pic (info))
+         if (!(bfd_link_pic (info)
+               /* If on the other hand, we are creating an executable, we
+                  may need to keep relocations for symbols satisfied by a
+                  dynamic library if we manage to avoid copy relocs for the
+                  symbol.  */
+               || (ELIMINATE_COPY_RELOCS
+                   && !bfd_link_pic (info)
+                   && h != NULL
+                   && (h->root.type == bfd_link_hash_defweak
+                       || !h->def_regular))))
            break;
 
          {
index 36fc28bae985d41c77ee882fbd303756cda98da9..9eaa6466d0cef4682049944891e21589d65b35f9 100644 (file)
@@ -1,3 +1,9 @@
+2017-06-08  Jiong Wang  <jiong.wang@arm.com>
+
+       * testsuite/ld-aarch64/copy-reloc-eliminate.d: New test.
+       * testsuite/ld-aarch64/copy-reloc-exe-eliminate.s: New test source file.
+       * testsuite/ld-aarch64/aarch64-elf.exp: Run new testcase.
+
 2017-06-07  Alan Modra  <amodra@gmail.com>
 
        * testsuite/ld-unique/pr21529.d: xfail aarch64, arm, hppa, ia64,
index ca21e171a1106ccd99d93f7d6b7256253b623c0e..66e7e646960fd3c4efe6e439d1f63567b55fec06 100644 (file)
@@ -335,6 +335,8 @@ set aarch64elflinktests {
     {} "copy-reloc-so.so"}
   {"ld-aarch64/exe with copy relocation" "-e0 tmpdir/copy-reloc-so.so" "" ""
     {copy-reloc-exe.s} {{objdump -R copy-reloc.d}} "copy-reloc"}
+  {"ld-aarch64/exe with copy relocation elimination" "-e0 tmpdir/copy-reloc-so.so" "" ""
+    {copy-reloc-exe-eliminate.s} {{objdump -R copy-reloc-eliminate.d}} "copy-reloc-elimination"}
   {"ld-aarch64/so with global func" "-shared" "" "" {func-in-so.s}
     {} "func-in-so.so"}
   {"ld-aarch64/func sym hash opt for exe"
diff --git a/ld/testsuite/ld-aarch64/copy-reloc-eliminate.d b/ld/testsuite/ld-aarch64/copy-reloc-eliminate.d
new file mode 100644 (file)
index 0000000..9657d65
--- /dev/null
@@ -0,0 +1,4 @@
+.*
+DYNAMIC RELOCATION RECORDS
+OFFSET.*TYPE.*VALUE.*
+.*R_AARCH64_ABS64.*global_a
diff --git a/ld/testsuite/ld-aarch64/copy-reloc-exe-eliminate.s b/ld/testsuite/ld-aarch64/copy-reloc-exe-eliminate.s
new file mode 100644 (file)
index 0000000..33227aa
--- /dev/null
@@ -0,0 +1,7 @@
+       .global p
+       .section        .data.rel.ro,"aw",%progbits
+       .align  3
+       .type   p, %object
+       .size   p, 8
+p:
+       .xword  global_a