[PATCH v2 2/3] sframe: additonal check in _bfd_x86_elf_link_setup_gnu_properties

claudiu.zissulescu-ianculescu@oracle.com claudiu.zissulescu-ianculescu@oracle.com
Wed Jan 14 10:05:32 GMT 2026


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.

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)
 	{
 	  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)
 	{
 	  flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
 			    | SEC_HAS_CONTENTS | SEC_IN_MEMORY
-- 
2.52.0



More information about the Binutils mailing list