[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