[PATCH v3 1/3] ld: sframe: do not generate .sframe for PLT if no .sframe is in input BFDs
Jens Remus
jremus@linux.ibm.com
Thu Jan 22 08:36:19 GMT 2026
On 1/22/2026 9:00 AM, claudiu.zissulescu-ianculescu@oracle.com wrote:
> From: Indu Bhagat <indu.bhagat@oracle.com>
>
> GNU ld creates SFrame stack trace info for the .plt* sections. These
> linker created sections are created in
> _bfd_x86_elf_link_setup_gnu_properties (), but data is emitted into
> them a bit later in _bfd_x86_elf_late_size_sections ().
This is true for x86, but not s390. Maybe reword as follows:
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 it is emitted into the
section a bit later in late_size_sections. Note that for aarch64 the
linker does not create .sframe for PLT yet.
> With SFrame sections now marked KEEP in scripttempl/elf.sc, and the
> presence of these linker created SFrame sections cause emission of an
> empty .sframe for all ELF targets (IIUC), even when all input bfd's
> have no .sframe section.
Due to the reordering of the patches this is no longer true. Maybe
reword as follows:
A subsequent commit will mark .sframe sections KEEP in the default
linker script (scripttempl/elf.sc), and the presence of these linker-
created .sframe sections cause emission of an empty .sframe section for
all ELF targets (IIUC), even when none of the input BFDs have any
.sframe section.
Can you please explain how the linker-created .sframe sections cause
an empty .sframe section in general? How does the creation of an
.sframe section on x86/s390 affect any other ELF target (e.g. aarch64)?
> This patch is an attempt to avoid creation of empty .sframe in linked
> objects on x86_64 and s390x, when none of the inputs had SFrame sections.
In general I understand that it is a good idea not to produce linker-
created .sframe for PLT if none of the input BFDs have any .sframe.
If a user compiles without --gsframe there should not be .sframe for
the PLT after linking.
But how this relates to empty .sframe sections to be generated is
unclear.
>
> bfd/
> * 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.
> ---
> bfd/elf-bfd.h | 2 ++
> bfd/elf-sframe.c | 18 ++++++++++++++++++
> bfd/elf64-s390.c | 10 +++++++++-
> bfd/elfxx-x86.c | 11 ++++++++++-
> 4 files changed, 39 insertions(+), 2 deletions(-)
For the code changes:
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
>
> diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
> index 4fa4461cba3..c833b7d101b 100644
> --- a/bfd/elf-bfd.h
> +++ b/bfd/elf-bfd.h
> @@ -2581,6 +2581,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;
> diff --git a/bfd/elf-sframe.c b/bfd/elf-sframe.c
> index 33e4df5b1c7..77d9d33d602 100644
> --- a/bfd/elf-sframe.c
> +++ b/bfd/elf-sframe.c
> @@ -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. */
> diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c
> index 8ad10ce6bd1..b6a903db42a 100644
> --- a/bfd/elf64-s390.c
> +++ b/bfd/elf64-s390.c
> @@ -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
> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
> index 901b858fb34..b450aed4038 100644
> --- a/bfd/elfxx-x86.c
> +++ b/bfd/elfxx-x86.c
> @@ -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
Regards,
Jens
--
Jens Remus
Linux on Z Development (D3303)
jremus@de.ibm.com / jremus@linux.ibm.com
IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Ehningen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/
More information about the Binutils
mailing list