diff options
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elflink.c | 10 | ||||
-rw-r--r-- | ld/ChangeLog | 8 | ||||
-rw-r--r-- | ld/scripttempl/elf.sc | 13 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr22677.d | 18 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr22677.s | 16 |
6 files changed, 64 insertions, 7 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a174a4c..8f2feae 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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 diff --git a/bfd/elflink.c b/bfd/elflink.c index 15d9c7e..4c92a04 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/ChangeLog b/ld/ChangeLog index 83545d5..34fdb1f 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -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. diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc index 3de86b0..139773d 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 0000000..0d4ddf6 --- /dev/null +++ b/ld/testsuite/ld-elf/pr22677.d @@ -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 index 0000000..16f8bc3 --- /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 |