ld: Keep PREINIT_ARRAY/INIT_ARRAY/FINI_ARRAY sections for -r --gc-sections
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 11 Jan 2018 17:42:12 +0000 (09:42 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 11 Jan 2018 17:42:12 +0000 (09:42 -0800)
We must keep all PREINIT_ARRAY, INIT_ARRAY as well as FINI_ARRAY sections
for ld -r --gc-sections.

bfd/

PR ld/22677
* elflink.c (bfd_elf_gc_sections): Keep all PREINIT_ARRAY,
INIT_ARRAY as well as FINI_ARRAY sections for ld -r --gc-sections.

ld/

PR ld/22677
* scripttempl/elf.sc (PREINIT_ARRAY): New.
Don't add .preinit_array for ld -r.
* testsuite/ld-elf/pr22677.d: New file.
* testsuite/ld-elf/pr22677.s: Likewise.

bfd/ChangeLog
bfd/elflink.c
ld/ChangeLog
ld/scripttempl/elf.sc
ld/testsuite/ld-elf/pr22677.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr22677.s [new file with mode: 0644]

index a174a4cfeb341d2941c8bb8b3912c8638f4a8ea5..8f2feae455bc285a097bf54bf577d8609c9244d5 100644 (file)
@@ -1,3 +1,9 @@
+2018-01-11  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/22677
+       * elflink.c (bfd_elf_gc_sections): Keep all PREINIT_ARRAY,
+       INIT_ARRAY as well as FINI_ARRAY sections for ld -r --gc-section.
+
 2017-09-27  Kuan-Lin Chen  <kuanlinchentw@gmail.com>
 
        PR 22662
index 15d9c7e57bfa881f733bf9832e13289761627536..4c92a048cea8ebd359c5b5a4f8770061b671e875 100644 (file)
@@ -13428,11 +13428,19 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
 
       /* Start at sections marked with SEC_KEEP (ref _bfd_elf_gc_keep).
         Also treat note sections as a root, if the section is not part
-        of a group.  */
+        of a group.  We must keep all PREINIT_ARRAY, INIT_ARRAY as
+        well as FINI_ARRAY sections for ld -r.  */
       for (o = sub->sections; o != NULL; o = o->next)
        if (!o->gc_mark
            && (o->flags & SEC_EXCLUDE) == 0
            && ((o->flags & SEC_KEEP) != 0
+               || (bfd_link_relocatable (info)
+                   && ((elf_section_data (o)->this_hdr.sh_type
+                        == SHT_PREINIT_ARRAY)
+                       || (elf_section_data (o)->this_hdr.sh_type
+                           == SHT_INIT_ARRAY)
+                       || (elf_section_data (o)->this_hdr.sh_type
+                           == SHT_FINI_ARRAY)))
                || (elf_section_data (o)->this_hdr.sh_type == SHT_NOTE
                    && elf_next_in_group (o) == NULL )))
          {
index 83545d55aa0919c7d73ec682020cd57379edb2df..34fdb1f031d9b5e9eb3121aa38244fdb6aaf5031 100644 (file)
@@ -1,3 +1,11 @@
+2018-01-11  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/22677
+       * scripttempl/elf.sc (PREINIT_ARRAY): New.
+       Don't add .preinit_array for ld -r.
+       * testsuite/ld-elf/pr22677.d: New file.
+       * testsuite/ld-elf/pr22677.s: Likewise.
+
 2018-01-11  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * ldexp.h (union etree_union): Remove defsym field.
index 3de86b0fcf15b4b504669614fa013486a48337b7..139773dad00cf5ba0ac082d2accee1c09233039d 100644 (file)
@@ -245,6 +245,12 @@ test "${LARGE_SECTIONS}" = "yes" && LARGE_SECTIONS="
     *(.ldata${RELOCATING+ .ldata.* .gnu.linkonce.l.*})
     ${RELOCATING+. = ALIGN(. != 0 ? ${ALIGNMENT} : 1);}
   }"
+PREINIT_ARRAY=".preinit_array   ${RELOCATING-0} :
+  {
+    ${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__preinit_array_start = .);}}
+    KEEP (*(.preinit_array))
+    ${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__preinit_array_end = .);}}
+  }"
 if test "${ENABLE_INITFINI_ARRAY}" = "yes"; then
   SORT_INIT_ARRAY="KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))"
   SORT_FINI_ARRAY="KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))"
@@ -568,12 +574,7 @@ cat <<EOF
   .tdata       ${RELOCATING-0} : { *(.tdata${RELOCATING+ .tdata.* .gnu.linkonce.td.*}) }
   .tbss                ${RELOCATING-0} : { *(.tbss${RELOCATING+ .tbss.* .gnu.linkonce.tb.*})${RELOCATING+ *(.tcommon)} }
 
-  .preinit_array   ${RELOCATING-0} :
-  {
-    ${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__preinit_array_start = .);}}
-    KEEP (*(.preinit_array))
-    ${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__preinit_array_end = .);}}
-  }
+  ${RELOCATING+${PREINIT_ARRAY}}
   ${RELOCATING+${INIT_ARRAY}}
   ${RELOCATING+${FINI_ARRAY}}
   ${SMALL_DATA_CTOR-${RELOCATING+${CTOR}}}
diff --git a/ld/testsuite/ld-elf/pr22677.d b/ld/testsuite/ld-elf/pr22677.d
new file mode 100644 (file)
index 0000000..0d4ddf6
--- /dev/null
@@ -0,0 +1,18 @@
+#ld: -r  --gc-sections -u foo
+#readelf: -S --wide
+#notarget: d30v-*-* dlx-*-* i960-*-* pj*-*-* pru-*-*
+#notarget: alpha-*-* hppa64-*-* i370-*-* i860-*-* ia64-*-* mep-*-* mn10200-*-*
+#xfail: cr16-*-* crx-*-* msp430-*-*
+# msp430 puts the init_array and fini_array inside the .rodata section.
+# generic linker targets don't support --gc-sections, nor do a bunch of
+# others.
+# cr16 and crx use non-standard scripts with memory regions, which don't
+# play well with unique group sections under ld -r.
+
+#...
+  \[[ 0-9]+\] \.preinit_array\.01000[ \t]+PREINIT_ARRAY[ \t0-9a-f]+WA?.*
+#...
+  \[[ 0-9]+\] \.init_array\.01000[ \t]+INIT_ARRAY[ \t0-9a-f]+WA?.*
+#...
+  \[[ 0-9]+\] \.fini_array\.01000[ \t]+FINI_ARRAY[ \t0-9a-f]+WA?.*
+#pass
diff --git a/ld/testsuite/ld-elf/pr22677.s b/ld/testsuite/ld-elf/pr22677.s
new file mode 100644 (file)
index 0000000..16f8bc3
--- /dev/null
@@ -0,0 +1,16 @@
+       .section .preinit_array.01000,"aw",%preinit_array
+       .p2align 2
+       .word 0
+
+       .section .init_array.01000,"aw",%init_array
+       .p2align 2
+       .word 0
+
+       .section .fini_array.01000,"aw",%fini_array
+       .p2align 2
+       .word 0
+
+       .text
+       .globl foo
+foo:
+       .word 0