]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
bfd: ld: sframe: set SEC_EXCLUDE when discarding SFrame sections users/ibhagat/try-pr33127-v1
authorIndu Bhagat <indu.bhagat@oracle.com>
Sun, 13 Jul 2025 13:22:54 +0000 (06:22 -0700)
committerIndu Bhagat <indu.bhagat@oracle.com>
Sun, 13 Jul 2025 21:54:39 +0000 (14:54 -0700)
Fix PR libsframe/33127 "ld -r" doesn't remove the sframe relocation
against the discarded section

When an SFrame section is marked for deletion, set its section size to
zero.  And mark it with SEC_EXCLUDE.

Using the testcase provided by H.J. Lu.

bfd/
PR ld/33127
* elf-sframe.c: Set section size to 0 if all FDEs are to be
deleted.  While at it, keep the rawsize updated.
* elflink.c (bfd_elf_discard_info): Set SEC_EXCLUDE to mark for
exclusion from final link.
ld/
PR ld/33127
* testsuite/ld-x86-64/sframe-reloc-2.d: New test.
* testsuite/ld-x86-64/x86-64.exp: Run sframe-reloc-2.

bfd/elf-sframe.c
bfd/elflink.c
ld/testsuite/ld-x86-64/sframe-reloc-2.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index b709e590a2dc9240f8910046d126734f5ac90925..4e20e9ae2280dcda9cd5ccedc9a3bcc8078d3147 100644 (file)
@@ -274,12 +274,14 @@ _bfd_elf_discard_section_sframe
   unsigned int i;
   unsigned int func_desc_offset;
   unsigned int num_fidx;
+  unsigned int num_fidx_deleted = 0;
   struct sframe_dec_info *sfd_info;
 
   changed = false;
   /* FIXME - if relocatable link and changed = true, how does the final
      .rela.sframe get updated ?.  */
   keep = false;
+  sec->rawsize = sec->size;
 
   sfd_info = (struct sframe_dec_info *) elf_section_data (sec)->sec_info;
 
@@ -299,9 +301,16 @@ _bfd_elf_discard_section_sframe
          if (!keep)
            {
              sframe_decoder_mark_func_deleted (sfd_info, i);
+             num_fidx_deleted++;
              changed = true;
            }
        }
+
+      /* PR libsframe/33127
+        Set section size to zero if all FDE are to be deleted.  Using size,
+        later bfd_elf_discard_info will mark this section as SEC_EXCLUDE.  */
+      if (changed && num_fidx_deleted == num_fidx)
+       bfd_set_section_size (sec, 0);
     }
   return changed;
 }
index c4f57cf2f3c6aad1e218b168a6abb948c2071be6..852884e2e5931f3524535d8687ef02ab8d49787e 100644 (file)
@@ -15298,6 +15298,8 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
                {
                  if (i->size != i->rawsize)
                    changed = 1;
+                 if (i->size == 0)
+                   i->flags |= SEC_EXCLUDE;
                }
            }
          fini_reloc_cookie_for_section (&cookie, i);
diff --git a/ld/testsuite/ld-x86-64/sframe-reloc-2.d b/ld/testsuite/ld-x86-64/sframe-reloc-2.d
new file mode 100644 (file)
index 0000000..b1b787d
--- /dev/null
@@ -0,0 +1,11 @@
+#name: SFrame relocatable link - discarded section (PR ld/33127)
+#source: ../ld-elf/eh-group1.s
+#source: ../ld-elf/eh-group2.s
+#as: --gsframe
+#ld: -r
+#readelf: -rW
+
+#failif
+#...
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_NONE *0?
+#...
index a682b1374fa968f4bf876117949004e0910aacb6..8e3297e3cd5b6be3402705960995e98f490e9180 100644 (file)
@@ -568,6 +568,7 @@ run_dump_test "pr32809"
 if { ![skip_sframe_tests] } {
     run_dump_test "sframe-simple-1"
     run_dump_test "sframe-reloc-1"
+    run_dump_test "sframe-reloc-2"
     run_dump_test "sframe-plt-1"
     run_dump_test "sframe-ibt-plt-1"
     run_dump_test "sframe-pltgot-1"