From 9b538ba71fc7dbab65371e3e4e5f7e093ff25023 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 6 Feb 2020 19:42:52 -0800 Subject: [PATCH] ELF: Discard a section if any of its linked-to sections has been discarded Add ldelf_before_place_orphans to call before lang_place_orphans to discard a section if any of its linked-to sections has been discarded. PR ld/25022 * emultempl/aix.em (ld_${EMULATION_NAME}_emulation): Add before_place_orphans_default. * emultempl/armcoff.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/beos.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/generic.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/linux.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/msp430.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/pe.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/pep.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/ticoff.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/vanilla.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/elf.em (ld_${EMULATION_NAME}_emulation): Use ldelf_before_place_orphans. * ldelf.c (ldelf_before_place_orphans): New. * ldelf.h (ldelf_before_place_orphans): Likewise. * ldemul.c (ldemul_before_place_orphans): Likewise. (before_place_orphans_default): Likewise. * ldemul.h (ldemul_before_place_orphans): Likewise. (before_place_orphans_default): Likewise. (ld_emulation_xfer_struct): Add before_place_orphans. * ldlang.c (lang_process): Call ldemul_before_place_orphans before lang_place_orphans. * testsuite/ld-elf/pr25022.d: New file. * testsuite/ld-elf/pr25022.s: Likewise. * testsuite/ld-elf/pr25022.t: Likewise. --- ld/ChangeLog | 29 +++++++++++++++++++++++++++++ ld/emultempl/aix.em | 1 + ld/emultempl/armcoff.em | 1 + ld/emultempl/beos.em | 1 + ld/emultempl/elf.em | 1 + ld/emultempl/generic.em | 1 + ld/emultempl/linux.em | 1 + ld/emultempl/msp430.em | 1 + ld/emultempl/pe.em | 1 + ld/emultempl/pep.em | 1 + ld/emultempl/ticoff.em | 1 + ld/emultempl/vanilla.em | 1 + ld/ldelf.c | 29 +++++++++++++++++++++++++++++ ld/ldelf.h | 1 + ld/ldemul.c | 11 +++++++++++ ld/ldemul.h | 7 +++++++ ld/ldlang.c | 2 ++ ld/testsuite/ld-elf/pr25022.d | 9 +++++++++ ld/testsuite/ld-elf/pr25022.s | 11 +++++++++++ ld/testsuite/ld-elf/pr25022.t | 1 + 20 files changed, 111 insertions(+) create mode 100644 ld/testsuite/ld-elf/pr25022.d create mode 100644 ld/testsuite/ld-elf/pr25022.s create mode 100644 ld/testsuite/ld-elf/pr25022.t diff --git a/ld/ChangeLog b/ld/ChangeLog index 3ad571f1691..221e2d3117f 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,32 @@ +2020-02-06 H.J. Lu + + PR ld/25022 + * emultempl/aix.em (ld_${EMULATION_NAME}_emulation): Add + before_place_orphans_default. + * emultempl/armcoff.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/beos.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/generic.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/linux.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/msp430.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/pe.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/pep.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/ticoff.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/vanilla.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/elf.em (ld_${EMULATION_NAME}_emulation): Use + ldelf_before_place_orphans. + * ldelf.c (ldelf_before_place_orphans): New. + * ldelf.h (ldelf_before_place_orphans): Likewise. + * ldemul.c (ldemul_before_place_orphans): Likewise. + (before_place_orphans_default): Likewise. + * ldemul.h (ldemul_before_place_orphans): Likewise. + (before_place_orphans_default): Likewise. + (ld_emulation_xfer_struct): Add before_place_orphans. + * ldlang.c (lang_process): Call ldemul_before_place_orphans + before lang_place_orphans. + * testsuite/ld-elf/pr25022.d: New file. + * testsuite/ld-elf/pr25022.s: Likewise. + * testsuite/ld-elf/pr25022.t: Likewise. + 2020-02-06 H.J. Lu PR ld/25490 diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em index c39491eab43..2da38709899 100644 --- a/ld/emultempl/aix.em +++ b/ld/emultempl/aix.em @@ -1541,6 +1541,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = { after_parse_default, gld${EMULATION_NAME}_after_open, after_check_relocs_default, + before_place_orphans_default, after_allocation_default, gld${EMULATION_NAME}_set_output_arch, gld${EMULATION_NAME}_choose_target, diff --git a/ld/emultempl/armcoff.em b/ld/emultempl/armcoff.em index 0528c637b68..c539e2facca 100644 --- a/ld/emultempl/armcoff.em +++ b/ld/emultempl/armcoff.em @@ -263,6 +263,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = after_parse_default, gld${EMULATION_NAME}_after_open, after_check_relocs_default, + before_place_orphans_default, after_allocation_default, set_output_arch_default, ldemul_default_target, diff --git a/ld/emultempl/beos.em b/ld/emultempl/beos.em index 97cde99c335..2c3e5e5370d 100644 --- a/ld/emultempl/beos.em +++ b/ld/emultempl/beos.em @@ -763,6 +763,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = after_parse_default, gld_${EMULATION_NAME}_after_open, after_check_relocs_default, + before_place_orphans_default, after_allocation_default, set_output_arch_default, ldemul_default_target, diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em index 42c552b36ed..bb7e5375303 100644 --- a/ld/emultempl/elf.em +++ b/ld/emultempl/elf.em @@ -880,6 +880,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = ${LDEMUL_AFTER_PARSE-ldelf_after_parse}, ${LDEMUL_AFTER_OPEN-gld${EMULATION_NAME}_after_open}, ${LDEMUL_AFTER_CHECK_RELOCS-after_check_relocs_default}, + ${LDEMUL_BEFORE_PLACE_ORPHANS-ldelf_before_place_orphans}, ${LDEMUL_AFTER_ALLOCATION-gld${EMULATION_NAME}_after_allocation}, ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default}, ${LDEMUL_CHOOSE_TARGET-ldemul_default_target}, diff --git a/ld/emultempl/generic.em b/ld/emultempl/generic.em index e140514e8ef..a39c9332075 100644 --- a/ld/emultempl/generic.em +++ b/ld/emultempl/generic.em @@ -138,6 +138,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = ${LDEMUL_AFTER_PARSE-after_parse_default}, ${LDEMUL_AFTER_OPEN-after_open_default}, ${LDEMUL_AFTER_CHECK_RELOCS-after_check_relocs_default}, + ${LDEMUL_BEFORE_PLACE_ORPHANS-before_place_orphans_default}, ${LDEMUL_AFTER_ALLOCATION-after_allocation_default}, ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default}, ${LDEMUL_CHOOSE_TARGET-ldemul_default_target}, diff --git a/ld/emultempl/linux.em b/ld/emultempl/linux.em index fea8da486dc..f4ae6cfba29 100644 --- a/ld/emultempl/linux.em +++ b/ld/emultempl/linux.em @@ -190,6 +190,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = after_parse_default, after_open_default, after_check_relocs_default, + before_place_orphans_default, after_allocation_default, set_output_arch_default, ldemul_default_target, diff --git a/ld/emultempl/msp430.em b/ld/emultempl/msp430.em index df940672bac..861c1dcda0a 100644 --- a/ld/emultempl/msp430.em +++ b/ld/emultempl/msp430.em @@ -825,6 +825,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = ${LDEMUL_AFTER_PARSE-after_parse_default}, msp430_elf_after_open, after_check_relocs_default, + before_place_orphans_default, msp430_elf_after_allocation, ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default}, ${LDEMUL_CHOOSE_TARGET-ldemul_default_target}, diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index 97fb1468aac..db23b221d66 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -2354,6 +2354,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = gld_${EMULATION_NAME}_after_parse, gld_${EMULATION_NAME}_after_open, after_check_relocs_default, + before_place_orphans_default, after_allocation_default, set_output_arch_default, ldemul_default_target, diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em index e8f5ca503fb..3d09a0a6b13 100644 --- a/ld/emultempl/pep.em +++ b/ld/emultempl/pep.em @@ -2153,6 +2153,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = gld_${EMULATION_NAME}_after_parse, gld_${EMULATION_NAME}_after_open, after_check_relocs_default, + before_place_orphans_default, after_allocation_default, set_output_arch_default, ldemul_default_target, diff --git a/ld/emultempl/ticoff.em b/ld/emultempl/ticoff.em index 2b6fae64a08..60c0da9f1b1 100644 --- a/ld/emultempl/ticoff.em +++ b/ld/emultempl/ticoff.em @@ -163,6 +163,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = after_parse_default, after_open_default, after_check_relocs_default, + before_place_orphans_default, after_allocation_default, set_output_arch_default, ldemul_default_target, diff --git a/ld/emultempl/vanilla.em b/ld/emultempl/vanilla.em index e17316fb5a2..ae6f6e4175d 100644 --- a/ld/emultempl/vanilla.em +++ b/ld/emultempl/vanilla.em @@ -64,6 +64,7 @@ struct ld_emulation_xfer_struct ld_vanilla_emulation = after_parse_default, after_open_default, after_check_relocs_default, + before_place_orphans_default, after_allocation_default, vanilla_set_output_arch, ldemul_default_target, diff --git a/ld/ldelf.c b/ld/ldelf.c index 2e27cf48a81..3ac3bb4e0a5 100644 --- a/ld/ldelf.c +++ b/ld/ldelf.c @@ -2134,3 +2134,32 @@ ldelf_place_orphan (asection *s, const char *secname, int constraint) return lang_insert_orphan (s, secname, constraint, after, place, NULL, NULL); } + +void +ldelf_before_place_orphans (void) +{ + bfd *abfd; + + for (abfd = link_info.input_bfds; + abfd != (bfd *) NULL; abfd = abfd->link.next) + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour + && bfd_count_sections (abfd) != 0 + && !bfd_input_just_syms (abfd)) + { + asection *isec; + for (isec = abfd->sections; isec != NULL; isec = isec->next) + { + /* Discard a section if any of its linked-to section has + been discarded. */ + asection *linked_to_sec; + for (linked_to_sec = elf_linked_to_section (isec); + linked_to_sec != NULL; + linked_to_sec = elf_linked_to_section (linked_to_sec)) + if (discarded_section (linked_to_sec)) + { + isec->output_section = bfd_abs_section_ptr; + break; + } + } + } +} diff --git a/ld/ldelf.h b/ld/ldelf.h index 492649b2934..2a58a0c1359 100644 --- a/ld/ldelf.h +++ b/ld/ldelf.h @@ -30,3 +30,4 @@ extern bfd_boolean ldelf_open_dynamic_archive (const char *, search_dirs_type *, lang_input_statement_type *); extern lang_output_section_statement_type *ldelf_place_orphan (asection *, const char *, int); +extern void ldelf_before_place_orphans (void); diff --git a/ld/ldemul.c b/ld/ldemul.c index 1f5228d2a4a..fa6dfdd18ed 100644 --- a/ld/ldemul.c +++ b/ld/ldemul.c @@ -71,6 +71,12 @@ ldemul_after_check_relocs (void) ld_emulation->after_check_relocs (); } +void +ldemul_before_place_orphans (void) +{ + ld_emulation->before_place_orphans (); +} + void ldemul_after_allocation (void) { @@ -266,6 +272,11 @@ after_check_relocs_default (void) { } +void +before_place_orphans_default (void) +{ +} + void after_allocation_default (void) { diff --git a/ld/ldemul.h b/ld/ldemul.h index bde74dfa9a1..44e3a92aa7e 100644 --- a/ld/ldemul.h +++ b/ld/ldemul.h @@ -36,6 +36,8 @@ extern void ldemul_after_open (void); extern void ldemul_after_check_relocs (void); +extern void ldemul_before_place_orphans + (void); extern void ldemul_after_allocation (void); extern void ldemul_before_allocation @@ -80,6 +82,8 @@ extern void after_open_default (void); extern void after_check_relocs_default (void); +extern void before_place_orphans_default + (void); extern void after_allocation_default (void); extern void before_allocation_default @@ -129,6 +133,9 @@ typedef struct ld_emulation_xfer_struct { /* Run after checking relocations. */ void (*after_check_relocs) (void); + /* Run before placing orphans. */ + void (*before_place_orphans) (void); + /* Run after allocating output sections. */ void (*after_allocation) (void); diff --git a/ld/ldlang.c b/ld/ldlang.c index 91c160b5604..528ed22c1bc 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -7837,6 +7837,8 @@ lang_process (void) output statement, so that it isn't reordered. */ process_insert_statements (&lang_os_list.head->header.next); + ldemul_before_place_orphans (); + /* Find any sections not attached explicitly and handle them. */ lang_place_orphans (); diff --git a/ld/testsuite/ld-elf/pr25022.d b/ld/testsuite/ld-elf/pr25022.d new file mode 100644 index 00000000000..9a397523a31 --- /dev/null +++ b/ld/testsuite/ld-elf/pr25022.d @@ -0,0 +1,9 @@ +#ld: -T pr25022.t +#readelf: -SW +#xfail: msp*-* +# msp* doesn't use ldelf_before_place_orphans. + +#failif +#... + +\[ *[0-9]+\] \.(bar|moo|zed) +.* +#... diff --git a/ld/testsuite/ld-elf/pr25022.s b/ld/testsuite/ld-elf/pr25022.s new file mode 100644 index 00000000000..ace4f25f2bc --- /dev/null +++ b/ld/testsuite/ld-elf/pr25022.s @@ -0,0 +1,11 @@ + .section .foo,"a" + .dc.a 0 + + .section .moo,"ao",%progbits,.zed + .dc.a 0 + + .section .bar,"ao",%progbits,.foo + .dc.a 0 + + .section .zed,"ao",%progbits,.foo + .dc.a 0 diff --git a/ld/testsuite/ld-elf/pr25022.t b/ld/testsuite/ld-elf/pr25022.t new file mode 100644 index 00000000000..bb9aa81e0f3 --- /dev/null +++ b/ld/testsuite/ld-elf/pr25022.t @@ -0,0 +1 @@ +SECTIONS { /DISCARD/ : { *(.foo) } } -- 2.30.2