* [PATCH] ELF: Discard a section if any of its linked-to section has been discarded
@ 2020-02-07 2:14 H.J. Lu
2020-02-07 3:30 ` Alan Modra
2020-02-08 18:14 ` Fangrui Song
0 siblings, 2 replies; 5+ messages in thread
From: H.J. Lu @ 2020-02-07 2:14 UTC (permalink / raw)
To: binutils
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/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 +
19 files changed, 82 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/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.24.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] ELF: Discard a section if any of its linked-to section has been discarded
2020-02-07 2:14 [PATCH] ELF: Discard a section if any of its linked-to section has been discarded H.J. Lu
@ 2020-02-07 3:30 ` Alan Modra
2020-02-08 18:14 ` Fangrui Song
1 sibling, 0 replies; 5+ messages in thread
From: Alan Modra @ 2020-02-07 3:30 UTC (permalink / raw)
To: H.J. Lu; +Cc: binutils
On Thu, Feb 06, 2020 at 06:14:31PM -0800, H.J. Lu wrote:
> 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.
OK.
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] ELF: Discard a section if any of its linked-to section has been discarded
2020-02-07 2:14 [PATCH] ELF: Discard a section if any of its linked-to section has been discarded H.J. Lu
2020-02-07 3:30 ` Alan Modra
@ 2020-02-08 18:14 ` Fangrui Song
2020-02-08 20:23 ` H.J. Lu
1 sibling, 1 reply; 5+ messages in thread
From: Fangrui Song @ 2020-02-08 18:14 UTC (permalink / raw)
To: H.J. Lu; +Cc: binutils
On 2020-02-06, H.J. Lu wrote:
>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/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 +
> 19 files changed, 82 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/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.24.1
Is the second rule listed on
https://sourceware.org/ml/binutils/2020-02/msg00035.html respected?
> For a non-SHF_ALLOC section, it is a GC root only if all the following
> conditions are satisfied:
> ...
> * it is not in a section group with at least one SHF_ALLOC section.
> If it belongs to such a section group, we expect a
> SHF_ALLOC section in the section group responsible for making the
> whole group alive. This semantic is at least expected by
If A (with SHF_LINK_ORDER) is in a section group with no SHF_ALLOC
section, we should not garbage collect A.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] ELF: Discard a section if any of its linked-to section has been discarded
2020-02-08 18:14 ` Fangrui Song
@ 2020-02-08 20:23 ` H.J. Lu
0 siblings, 0 replies; 5+ messages in thread
From: H.J. Lu @ 2020-02-08 20:23 UTC (permalink / raw)
To: Fangrui Song; +Cc: Binutils
On Sat, Feb 8, 2020 at 10:14 AM Fangrui Song <i@maskray.me> wrote:
>
> On 2020-02-06, H.J. Lu wrote:
> >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.
>
> Is the second rule listed on
> https://sourceware.org/ml/binutils/2020-02/msg00035.html respected?
>
> > For a non-SHF_ALLOC section, it is a GC root only if all the following
> > conditions are satisfied:
> > ...
> > * it is not in a section group with at least one SHF_ALLOC section.
> > If it belongs to such a section group, we expect a
> > SHF_ALLOC section in the section group responsible for making the
> > whole group alive. This semantic is at least expected by
>
> If A (with SHF_LINK_ORDER) is in a section group with no SHF_ALLOC
> section, we should not garbage collect A.
Testcase please.
--
H.J.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] ELF: Discard a section if any of its linked-to section has been discarded
@ 2020-02-03 14:39 H.J. Lu
0 siblings, 0 replies; 5+ messages in thread
From: H.J. Lu @ 2020-02-03 14:39 UTC (permalink / raw)
To: binutils
Add ldelf_before_place_orphans to call before lang_place_orphans to
discard a section if any of its linked-to section has been discarded.
This patch depends on
https://sourceware.org/ml/binutils/2020-02/msg00038.html
for the section flag 'o' in .section directive in linker tests.
H.J.
---
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/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 +
19 files changed, 82 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/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.24.1
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2020-02-08 20:23 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-07 2:14 [PATCH] ELF: Discard a section if any of its linked-to section has been discarded H.J. Lu
2020-02-07 3:30 ` Alan Modra
2020-02-08 18:14 ` Fangrui Song
2020-02-08 20:23 ` H.J. Lu
-- strict thread matches above, loose matches on Subject: below --
2020-02-03 14:39 H.J. Lu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).