[PATCH v2 2/3] sframe: additonal check in _bfd_x86_elf_link_setup_gnu_properties
Jens Remus
jremus@linux.ibm.com
Wed Jan 14 10:34:53 GMT 2026
On 1/14/2026 11:05 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 ().
>
> 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.
>
> 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.
Thanks for taking care of s390x! _bfd_elf_sframe_present_input_bfds is
also a neat improvement.
Nit: Reword the commit subject to e.g.:
ld: sframe: do not generate .sframe for PLT if no .sframe in input BFDs
>
> 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 | 19 +++++++++++++++++++
> bfd/elf64-s390.c | 9 +++++++++
> bfd/elfxx-x86.c | 9 +++++++++
> 4 files changed, 39 insertions(+)
>
> diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
> index 4a9d87f03a2..dc34a856902 100644
> --- a/bfd/elf-bfd.h
> +++ b/bfd/elf-bfd.h
> @@ -2586,6 +2586,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 0ed374bd0b9..474292677c7 100644
> --- a/bfd/elf-sframe.c
> +++ b/bfd/elf-sframe.c
> @@ -171,6 +171,25 @@ 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;
> + for (sec = pbfd->sections; sec != NULL; sec = sec->next)
> + if (elf_section_type (sec) == SHT_GNU_SFRAME)
> + 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 2ff38adfd60..71f534185da 100644
> --- a/bfd/elf64-s390.c
> +++ b/bfd/elf64-s390.c
> @@ -4306,8 +4306,17 @@ elf_s390_create_dynamic_sections (bfd *dynobj,
> }
> }
>
> + bool gen_plt_sframe_p = false;
> /* Create .sframe section for .plt section. */
> if (!info->no_ld_generated_unwind_info)
> + gen_plt_sframe_p = _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)
> {
I am not familiar with coding style, but that looks kind of odd to me.
What about the following? Maybe with the comment right before the
gen_plt_sframe_p definition?
bool gen_plt_sframe_p = !info->no_ld_generated_unwind_info
&& _bfd_elf_sframe_present_input_bfds (info);
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 36ba7919f47..13a2f3bc10f 100644
> --- a/bfd/elfxx-x86.c
> +++ b/bfd/elfxx-x86.c
> @@ -4834,8 +4834,17 @@ _bfd_x86_elf_link_setup_gnu_properties
> }
> }
>
> + bool gen_plt_sframe_p = false;
> /* .sframe sections are emitted for AMD64 ABI only. */
> if (ABI_64_P (info->output_bfd) && !info->no_ld_generated_unwind_info)
> + gen_plt_sframe_p = _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)
> {
Likewise:
bool gen_plt_sframe_p = ABI_64_P (info->output_bfd)
&& !info->no_ld_generated_unwind_info
&& _bfd_elf_sframe_present_input_bfds (info);
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