From: Indu Bhagat Date: Sun, 13 Jul 2025 13:22:54 +0000 (-0700) Subject: bfd: ld: sframe: set SEC_EXCLUDE when discarding SFrame sections X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2Fusers%2Fibhagat%2Ftry-pr33127-v1;p=thirdparty%2Fbinutils-gdb.git bfd: ld: sframe: set SEC_EXCLUDE when discarding SFrame sections 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. --- diff --git a/bfd/elf-sframe.c b/bfd/elf-sframe.c index b709e590a2d..4e20e9ae228 100644 --- a/bfd/elf-sframe.c +++ b/bfd/elf-sframe.c @@ -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; } diff --git a/bfd/elflink.c b/bfd/elflink.c index c4f57cf2f3c..852884e2e59 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -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 index 00000000000..b1b787dd073 --- /dev/null +++ b/ld/testsuite/ld-x86-64/sframe-reloc-2.d @@ -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? +#... diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index a682b1374fa..8e3297e3cd5 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -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"