mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2026-08-27 00:26:02 -04:00
ld: sframe: do not generate .sframe for PLT if no .sframe is in input BFDs
GNU ld creates SFrame stack trace info for the PLT. For x86 the linker- created .sframe section is created in setup_gnu_properties. For s390 it is created in create_dynamic_sections. For both, the section data is itself emitted a bit later in late_size_sections. Note that for aarch64 the linker does not create .sframe for PLT yet. Recall that a previous patch disentangled --no-ld-generated-unwind-info from the linker-generated .sframe sections: this means that the linker now generates .sframe section (for .plt*) for the first input BFD enthusiatically even when none of the input BFDs have any .sframe section, unless --discard-sframe is also added. The issue is that these (unexpected) linker-generated .sframe sections (on x86_64, and s390) may now trip the linking process, e.g., when using --orphan-handling=error together with a linker script that treats .sframe differently than the default linker script. https://sourceware.org/pipermail/binutils/2026-January/147826.html Further, with SFrame sections to be soon marked KEEP for fixing GC/SFrame (PR ld/32769), the presence of these linker generated SFrame sections will also cause emission of an empty .sframe (for x86_64 and s390x), even when all input bfd's have no .sframe section. This patch avoids creation of .sframe for .plt* if none of the input BFDs had any .sframe section. This then avoids creation of empty .sframe in linked objects on x86_64 and s390x, when none of the inputs have SFrame sections. This also fixes PR ld/33830. For the code changes: Reviewed-by: Jens Remus <jremus@linux.ibm.com> New testcases have (since the above Reviewed-by) been added. Since --no-ld-generated-unwind-info is not supported on aarch64, add target-specific ld tests. Additionally add a generic test (for all targets that support SFrame) to ensure no output .sframe is generated if users says no --gsframe or similar. bfd/ PR ld/33830 * elf-bfd.h (_bfd_elf_sframe_present_input_bfds): New declaration. * elf-sframe.c (_bfd_elf_sframe_present_input_bfds): New definition. * elf64-s390.c (elf_s390_create_dynamic_sections): Do not generate .sframe for .plt unconditionally. * elfxx-x86.c (_bfd_x86_elf_link_setup_gnu_properties): Likewise. ld/testsuite/ PR ld/33830 * ld-s390/no-sframe.ld: Linker script with no specification for SFrame sections. * ld-s390/s390.exp: Add new test. * ld-s390/sframe-command-line-2.d: New testcase that uses --no-ld-generated-unwind-info and a linker script that has no specific rules for .sframe. * ld-x86-64/no-sframe.ld: Likewise for x86_64. * ld-x86-64/sframe-command-line-2.d: Likewise for x86_64. * ld-x86-64/x86-64.exp: Add new test. * ld-sframe/no-ld-generated-sframe.d: Ensure no .sframe in output if no .sframe in input. * ld-sframe/no-sframe.ld: Linker script with no specification for SFrame sections. * ld-sframe/test.s: Add new test.
This commit is contained in:
parent
1d734bf4b9
commit
9d8fa7ffc0
13 changed files with 104 additions and 2 deletions
|
|
@ -2628,6 +2628,8 @@ extern bool _bfd_elf_maybe_strip_eh_frame_hdr
|
|||
|
||||
extern bool _bfd_elf_sframe_present
|
||||
(struct bfd_link_info *) ATTRIBUTE_HIDDEN;
|
||||
extern bool _bfd_elf_sframe_present_input_bfds
|
||||
(struct bfd_link_info *) ATTRIBUTE_HIDDEN;
|
||||
extern bool _bfd_elf_parse_sframe
|
||||
(bfd *, struct bfd_link_info *, asection *, struct elf_reloc_cookie *)
|
||||
ATTRIBUTE_HIDDEN;
|
||||
|
|
|
|||
|
|
@ -171,6 +171,24 @@ sframe_read_value (bfd *abfd, bfd_byte *contents, unsigned int offset,
|
|||
return value;
|
||||
}
|
||||
|
||||
/* Return true if any of the input BFDs contains at least one .sframe
|
||||
section. */
|
||||
|
||||
bool
|
||||
_bfd_elf_sframe_present_input_bfds (struct bfd_link_info *info)
|
||||
{
|
||||
/* Find if any input file has an .sframe section. */
|
||||
for (bfd *pbfd = info->input_bfds; pbfd != NULL; pbfd = pbfd->link.next)
|
||||
if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
|
||||
&& bfd_count_sections (pbfd) != 0)
|
||||
{
|
||||
asection *sec = bfd_get_section_by_name (pbfd, ".sframe");
|
||||
if (sec != NULL)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return true if there is at least one non-empty .sframe section in
|
||||
input files. Can only be called after ld has mapped input to
|
||||
output sections, and before sections are stripped. */
|
||||
|
|
|
|||
|
|
@ -4309,7 +4309,15 @@ elf_s390_create_dynamic_sections (bfd *dynobj,
|
|||
}
|
||||
|
||||
/* Create .sframe section for .plt section. */
|
||||
if (!info->discard_sframe)
|
||||
bool gen_plt_sframe_p = !info->discard_sframe
|
||||
&& _bfd_elf_sframe_present_input_bfds (info);
|
||||
|
||||
/* Do not make SFrame sections for dynobj unconditionally. If there
|
||||
are no SFrame sections for any input files, skip creating the linker
|
||||
created SFrame sections too. Since SFrame sections are marked KEEP,
|
||||
prohibiting these linker-created SFrame sections when unnecessary,
|
||||
helps avoid creating of empty SFrame sections in the output. */
|
||||
if (gen_plt_sframe_p)
|
||||
{
|
||||
flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
|
||||
| SEC_HAS_CONTENTS | SEC_IN_MEMORY
|
||||
|
|
|
|||
|
|
@ -4827,7 +4827,16 @@ _bfd_x86_elf_link_setup_gnu_properties
|
|||
}
|
||||
|
||||
/* .sframe sections are emitted for AMD64 ABI only. */
|
||||
if (ABI_64_P (info->output_bfd) && !info->discard_sframe)
|
||||
bool gen_plt_sframe_p = ABI_64_P (info->output_bfd)
|
||||
&& !info->discard_sframe
|
||||
&& _bfd_elf_sframe_present_input_bfds (info);
|
||||
|
||||
/* Do not make SFrame sections for dynobj unconditionally. If there
|
||||
are no SFrame sections for any input files, skip creating the linker
|
||||
created SFrame sections too. Since SFrame sections are marked KEEP,
|
||||
prohibiting these linker-created SFrame sections, when unnecessary,
|
||||
helps avoid creation of empty SFrame sections in the output. */
|
||||
if (gen_plt_sframe_p)
|
||||
{
|
||||
flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
|
||||
| SEC_HAS_CONTENTS | SEC_IN_MEMORY
|
||||
|
|
|
|||
6
ld/testsuite/ld-s390/no-sframe.ld
Normal file
6
ld/testsuite/ld-s390/no-sframe.ld
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = SIZEOF_HEADERS;
|
||||
.text : { *(.text) }
|
||||
}
|
||||
|
|
@ -192,6 +192,9 @@ if [istarget "s390x-*-*"] {
|
|||
if { ![skip_sframe_tests] } {
|
||||
run_dump_test "sframe-simple-1"
|
||||
run_dump_test "sframe-plt-1"
|
||||
# Test --discard-sframe
|
||||
run_dump_test "sframe-command-line-1"
|
||||
# Test --no-ld-generated-unwind-info
|
||||
run_dump_test "sframe-command-line-2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
ld/testsuite/ld-s390/sframe-command-line-2.d
Normal file
10
ld/testsuite/ld-s390/sframe-command-line-2.d
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#as:
|
||||
#source: sframe-foo.s
|
||||
#ld: --no-ld-generated-unwind-info -T no-sframe.ld -e foo
|
||||
#objdump: -hw
|
||||
#name: No interaction between --no-ld-generated-unwind-info and SFrame
|
||||
|
||||
#failif
|
||||
#...
|
||||
[0-9] .sframe .*
|
||||
#...
|
||||
10
ld/testsuite/ld-sframe/no-ld-generated-sframe.d
Normal file
10
ld/testsuite/ld-sframe/no-ld-generated-sframe.d
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#as:
|
||||
#source: test.s
|
||||
#ld: -T no-sframe.ld
|
||||
#objdump: -hw
|
||||
#name: No SFrame section in output with no --gsframe
|
||||
|
||||
#failif
|
||||
#...
|
||||
[0-9] .sframe .*
|
||||
#...
|
||||
6
ld/testsuite/ld-sframe/no-sframe.ld
Normal file
6
ld/testsuite/ld-sframe/no-sframe.ld
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = SIZEOF_HEADERS;
|
||||
.text : { *(.text) }
|
||||
}
|
||||
11
ld/testsuite/ld-sframe/test.s
Normal file
11
ld/testsuite/ld-sframe/test.s
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
.text
|
||||
.globl foo
|
||||
.type foo, @function
|
||||
foo:
|
||||
.cfi_startproc
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_endproc
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
.long foo
|
||||
6
ld/testsuite/ld-x86-64/no-sframe.ld
Normal file
6
ld/testsuite/ld-x86-64/no-sframe.ld
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = SIZEOF_HEADERS;
|
||||
.text : { *(.text) }
|
||||
}
|
||||
10
ld/testsuite/ld-x86-64/sframe-command-line-2.d
Normal file
10
ld/testsuite/ld-x86-64/sframe-command-line-2.d
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#as:
|
||||
#source: sframe-foo.s
|
||||
#ld: --no-ld-generated-unwind-info -T no-sframe.ld -e foo
|
||||
#objdump: -hw
|
||||
#name: No interaction between --no-ld-generated-unwind-info and SFrame
|
||||
|
||||
#failif
|
||||
#...
|
||||
[0-9] .sframe .*
|
||||
#...
|
||||
|
|
@ -588,7 +588,10 @@ run_dump_test "tls-le-pic-3-x32"
|
|||
if { ![skip_sframe_tests] } {
|
||||
run_dump_test "sframe-simple-1"
|
||||
run_dump_test "sframe-link-1"
|
||||
# Test --discard-sframe
|
||||
run_dump_test "sframe-command-line-1"
|
||||
# Test --no-ld-generated-unwind-info
|
||||
run_dump_test "sframe-command-line-2"
|
||||
run_dump_test "sframe-reloc-1"
|
||||
run_dump_test "sframe-plt-1"
|
||||
run_dump_test "sframe-ibt-plt-1"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue