aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2020-02-06 19:42:52 -0800
committerH.J. Lu <hjl.tools@gmail.com>2020-02-06 19:43:03 -0800
commit9b538ba71fc7dbab65371e3e4e5f7e093ff25023 (patch)
treeda4c23f9a303106a0a01e1770034cfbeb112825d /ld
parent5242a0a000ad7d3f2fa1cd0023f692d53261b302 (diff)
downloadgdb-9b538ba71fc7dbab65371e3e4e5f7e093ff25023.zip
gdb-9b538ba71fc7dbab65371e3e4e5f7e093ff25023.tar.gz
gdb-9b538ba71fc7dbab65371e3e4e5f7e093ff25023.tar.bz2
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.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog29
-rw-r--r--ld/emultempl/aix.em1
-rw-r--r--ld/emultempl/armcoff.em1
-rw-r--r--ld/emultempl/beos.em1
-rw-r--r--ld/emultempl/elf.em1
-rw-r--r--ld/emultempl/generic.em1
-rw-r--r--ld/emultempl/linux.em1
-rw-r--r--ld/emultempl/msp430.em1
-rw-r--r--ld/emultempl/pe.em1
-rw-r--r--ld/emultempl/pep.em1
-rw-r--r--ld/emultempl/ticoff.em1
-rw-r--r--ld/emultempl/vanilla.em1
-rw-r--r--ld/ldelf.c29
-rw-r--r--ld/ldelf.h1
-rw-r--r--ld/ldemul.c11
-rw-r--r--ld/ldemul.h7
-rw-r--r--ld/ldlang.c2
-rw-r--r--ld/testsuite/ld-elf/pr25022.d9
-rw-r--r--ld/testsuite/ld-elf/pr25022.s11
-rw-r--r--ld/testsuite/ld-elf/pr25022.t1
20 files changed, 111 insertions, 0 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 3ad571f..221e2d3 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,34 @@
2020-02-06 H.J. Lu <hongjiu.lu@intel.com>
+ 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 <hongjiu.lu@intel.com>
+
PR ld/25490
* testsuite/ld-elf/pr25490-1.d: New file.
* testsuite/ld-elf/pr25490-1.s: Likewise.
diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em
index c39491e..2da3870 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 0528c63..c539e2f 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 97cde99..2c3e5e5 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 42c552b..bb7e537 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 e140514..a39c933 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 fea8da4..f4ae6cf 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 df94067..861c1dc 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 97fb146..db23b22 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 e8f5ca5..3d09a0a 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 2b6fae6..60c0da9 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 e17316f..ae6f6e4 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 2e27cf4..3ac3bb4 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 492649b..2a58a0c 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 1f5228d..fa6dfdd 100644
--- a/ld/ldemul.c
+++ b/ld/ldemul.c
@@ -72,6 +72,12 @@ ldemul_after_check_relocs (void)
}
void
+ldemul_before_place_orphans (void)
+{
+ ld_emulation->before_place_orphans ();
+}
+
+void
ldemul_after_allocation (void)
{
ld_emulation->after_allocation ();
@@ -267,6 +273,11 @@ after_check_relocs_default (void)
}
void
+before_place_orphans_default (void)
+{
+}
+
+void
after_allocation_default (void)
{
lang_relax_sections (FALSE);
diff --git a/ld/ldemul.h b/ld/ldemul.h
index bde74df..44e3a92 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 91c160b..528ed22 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 0000000..9a39752
--- /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 0000000..ace4f25
--- /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 0000000..bb9aa81
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr25022.t
@@ -0,0 +1 @@
+SECTIONS { /DISCARD/ : { *(.foo) } }