This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] ld: Keep PREINIT_ARRAY/INIT_ARRAY/FINI_ARRAY sections for -r --gc-section
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: binutils at sourceware dot org
- Date: Thu, 11 Jan 2018 08:57:14 -0800
- Subject: [PATCH] ld: Keep PREINIT_ARRAY/INIT_ARRAY/FINI_ARRAY sections for -r --gc-section
- Authentication-results: sourceware.org; auth=none
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
We must keep all PREINIT_ARRAY, INIT_ARRAY as well as FINI_ARRAY sections
for ld -r --gc-section.
OK for master?
H.J.
---
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-section.
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/elflink.c | 10 +++++++++-
ld/scripttempl/elf.sc | 13 +++++++------
ld/testsuite/ld-elf/pr22677.d | 14 ++++++++++++++
ld/testsuite/ld-elf/pr22677.s | 16 ++++++++++++++++
4 files changed, 46 insertions(+), 7 deletions(-)
create mode 100644 ld/testsuite/ld-elf/pr22677.d
create mode 100644 ld/testsuite/ld-elf/pr22677.s
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 15d9c7e57b..4c92a048ce 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -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 )))
{
diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
index 3de86b0fcf..139773dad0 100644
--- a/ld/scripttempl/elf.sc
+++ b/ld/scripttempl/elf.sc
@@ -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
index 0000000000..57993c04c9
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22677.d
@@ -0,0 +1,14 @@
+#ld: -r --gc-section -u foo
+#readelf: -S --wide
+#xfail: cr16-*-* crx-*-* msp430-*-*
+# msp430 puts the init_array and fini_array inside the .rodata section.
+# 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
index 0000000000..16f8bc3149
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22677.s
@@ -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
--
2.14.3