ELF: Discard a section if any of its linked-to sections has been discarded
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 7 Feb 2020 03:42:52 +0000 (19:42 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 7 Feb 2020 03:43:03 +0000 (19:43 -0800)
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.

20 files changed:
ld/ChangeLog
ld/emultempl/aix.em
ld/emultempl/armcoff.em
ld/emultempl/beos.em
ld/emultempl/elf.em
ld/emultempl/generic.em
ld/emultempl/linux.em
ld/emultempl/msp430.em
ld/emultempl/pe.em
ld/emultempl/pep.em
ld/emultempl/ticoff.em
ld/emultempl/vanilla.em
ld/ldelf.c
ld/ldelf.h
ld/ldemul.c
ld/ldemul.h
ld/ldlang.c
ld/testsuite/ld-elf/pr25022.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr25022.s [new file with mode: 0644]
ld/testsuite/ld-elf/pr25022.t [new file with mode: 0644]

index 3ad571f169179811e97e5136a40093ed5cbaa98d..221e2d3117f9173f811a4dd02d3304db9c69f269 100644 (file)
@@ -1,3 +1,32 @@
+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
index c39491eab436299cc103eecb9477c519c7066404..2da3870989906055bceeb7a44739b1c177c78931 100644 (file)
@@ -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,
index 0528c637b6807ab18f4bfce8c5ce89b5c041fb26..c539e2facca90f876dae7fb07b9b90d88fde8e8b 100644 (file)
@@ -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,
index 97cde99c335252562784672909126a802d23986a..2c3e5e5370d039c8ff69e116dd7a134327625908 100644 (file)
@@ -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,
index 42c552b36eda23cde2d6eb16c313ad40f54b7f3a..bb7e5375303869c4150cd223cde51d6b622a808a 100644 (file)
@@ -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},
index e140514e8efdd412e9fcdcaf70727eb1e7703959..a39c9332075852c61878e2e8f86c74897f169bf2 100644 (file)
@@ -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},
index fea8da486dc8acfa2d2dda0c42cd42eaa678ba53..f4ae6cfba2948d1edd9e08d12787f33806b4c627 100644 (file)
@@ -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,
index df940672bac772483709e49094b904a771d6408e..861c1dcda0a1e5cbdd55e686c36a85cef66430dd 100644 (file)
@@ -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},
index 97fb1468aac92ecb11df16191c03a435bbcf6326..db23b221d66adc7ddc64b14aaa4881df9753482a 100644 (file)
@@ -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,
index e8f5ca503fb5695acd95d240da98e574b5095d69..3d09a0a6b13244ad59d349ec912dee5ebcecde3b 100644 (file)
@@ -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,
index 2b6fae64a0844cde40956a61e479afff43b2dd7a..60c0da9f1b16880efb93d74ebd322213a8684c8d 100644 (file)
@@ -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,
index e17316fb5a2c2c43d9ca382d7bc0a3d84f6fec1e..ae6f6e4175dcb1d788b4dd9346d3de5c0647a464 100644 (file)
@@ -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,
index 2e27cf48a816dc78bd76d2f0185a601d2edfb392..3ac3bb4e0a5093c2f6e860fccdaf86a9f2b69464 100644 (file)
@@ -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;
+               }
+         }
+      }
+}
index 492649b29349a5b8cb284722b6336c8ec4690930..2a58a0c1359a9c936e4d0ffa75855338505c6c2c 100644 (file)
@@ -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);
index 1f5228d2a4a1267c1da7e4c426783a78b64ac418..fa6dfdd18edfb199d4807d2766d02135272881b2 100644 (file)
@@ -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)
 {
index bde74dfa9a1640c3043dc1df3e51eec98fb68e71..44e3a92aa7ef26436d71aa3dc6145ab8469e9d54 100644 (file)
@@ -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);
 
index 91c160b560455a173c6c73e32ff7cc7effe85570..528ed22c1bc0902c972e8145ef8d6f070dfd8208 100644 (file)
@@ -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 (file)
index 0000000..9a39752
--- /dev/null
@@ -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 (file)
index 0000000..ace4f25
--- /dev/null
@@ -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 (file)
index 0000000..bb9aa81
--- /dev/null
@@ -0,0 +1 @@
+SECTIONS { /DISCARD/ : { *(.foo) } }