]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
ld: bfd: sframe: KEEP .sframe sections and support gc-sections
authorClaudiu Zissulescu <claudiu.zissulescu-ianculescu@oracle.com>
Fri, 30 Jan 2026 07:27:47 +0000 (23:27 -0800)
committerIndu Bhagat <indu.bhagat@oracle.com>
Fri, 30 Jan 2026 07:27:47 +0000 (23:27 -0800)
Fix PR ld/32769

Currently, specifying --gc-sections causes the linker to discard all
input .sframe sections.  Fix this behaviour by adding KEEP for .sframe
sections, like it is being done for .eh_frame sections, in the default
ELF linker script.

Additionally, add logic in the linker to gc mark .sframe sections.
_bfd_elf_gc_mark () now is aware of SFrame sections. It relies on
elf_section_sframe () to get the SFrame section associated with the
text section.

Also, the _bfd_elf_parse_sframe is changed to return TRUE when the
input sframe section is already parsed. It fixes calling
_bfd_elf_discard_section_sframe function in bfd_elf_discard_info,
enabling correct behavior for discarding unneeded sframe sections.

ld/
PR ld/32769
* scripttempl/elf.sc: KEEP .sframe sections.
bfd/
* elf-bfd.h (struct elf_obj_tdata): Add sframe section pointer.
(elf_sframe_section): New macro.
* elflink.c (_bfd_elf_gc_mark): Handle SFrame sections.
(bfd_elf_gc_sections): Likewise.
(bfd_elf_discard_info): Update for handling gc operations.
* elf-sframe.c (_bfd_elf_parse_sframe): Return TRUE for already
parsed sframe sections.

Co-authored-by: Indu Bhagat <indu.bhagat@oracle.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Claudiu Zissulescu <claudiu.zissulescu-ianculescu@oracle.com>
bfd/elf-bfd.h
bfd/elf-sframe.c
bfd/elflink.c
ld/scripttempl/elf.sc

index 2f67dce461733b9cee54c8f8ee0e21f029b1524c..dbf53756200f39cd82ea1f658066e5cb48b79adf 100644 (file)
@@ -2212,6 +2212,9 @@ struct elf_obj_tdata
   /* A pointer to the .eh_frame section.  */
   asection *eh_frame_section;
 
+  /* A pointer to the .sframe section.  */
+  asection *sframe_section;
+
   /* Symbol buffer.  */
   void *symbuf;
 
@@ -2303,6 +2306,8 @@ struct elf_obj_tdata
 #define elf_dynverref(bfd)     (elf_tdata(bfd) -> dynverref_section)
 #define elf_eh_frame_section(bfd) \
                                (elf_tdata(bfd) -> eh_frame_section)
+#define elf_sframe_section(bfd) \
+                               (elf_tdata(bfd) -> sframe_section)
 #define elf_section_syms(bfd)  (elf_tdata(bfd) -> o->section_syms)
 #define elf_num_section_syms(bfd) (elf_tdata(bfd) -> o->num_section_syms)
 #define core_prpsinfo(bfd)     (elf_tdata(bfd) -> prpsinfo)
index 77d9d33d6022129d51ce3e904c74f4dfec25cb6e..241186f8f2de9a28fca4aa6e1b04920b58e92a11 100644 (file)
@@ -245,13 +245,16 @@ _bfd_elf_parse_sframe (bfd *abfd,
     }
 
   if (sec->size == 0
-      || (sec->flags & SEC_HAS_CONTENTS) == 0
-      || sec->sec_info_type != SEC_INFO_TYPE_NONE)
+      || (sec->flags & SEC_HAS_CONTENTS) == 0)
     {
       /* This file does not contain .sframe information.  */
       return false;
     }
 
+  /* Check if this section was already parsed.  */
+  if (sec->sec_info_type == SEC_INFO_TYPE_SFRAME)
+    return true;
+
   if (bfd_is_abs_section (sec->output_section))
     {
       /* At least one of the sections is being discarded from the
index fcb92c91af98ac9bc91872981030b31a9656db06..29b89d4ab9ed9edc59b714fcc08379efe43f2695 100644 (file)
@@ -14153,7 +14153,7 @@ _bfd_elf_gc_mark (struct bfd_link_info *info,
                  elf_gc_mark_hook_fn gc_mark_hook)
 {
   bool ret;
-  asection *group_sec, *eh_frame;
+  asection *group_sec, *eh_frame, *sframe;
 
   sec->gc_mark = 1;
 
@@ -14166,9 +14166,12 @@ _bfd_elf_gc_mark (struct bfd_link_info *info,
   /* Look through the section relocs.  */
   ret = true;
   eh_frame = elf_eh_frame_section (sec->owner);
+  sframe = elf_sframe_section (sec->owner);
+
   if ((sec->flags & SEC_RELOC) != 0
       && sec->reloc_count > 0
-      && sec != eh_frame)
+      && sec != eh_frame
+      && sec != sframe)
     {
       struct elf_reloc_cookie cookie;
 
@@ -14705,6 +14708,21 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
          fini_reloc_cookie_for_section (&cookie, sec);
          sec = bfd_get_next_section_by_name (NULL, sec);
        }
+
+      /* Handle .sframe section.  */
+      sec = bfd_get_section_by_name (sub, ".sframe");
+      while (sec && init_reloc_cookie_for_section (&cookie, info, sec,
+                                                  false))
+       {
+         _bfd_elf_parse_sframe (sub, info, sec, &cookie);
+
+         if (sec->sec_info
+             && (sec->flags & SEC_LINKER_CREATED) == 0)
+           elf_sframe_section (sub) = sec;
+
+         fini_reloc_cookie_for_section (&cookie, sec);
+         sec = bfd_get_next_section_by_name (NULL, sec);
+       }
     }
 
   /* Apply transitive closure to the vtable entry usage info.  */
index 80b4b512536e724a025e5a7c195e60a4bf6ac22a..8a0efc02c86440ca7ec634fd44506ada1d2b9d57 100644 (file)
@@ -719,7 +719,7 @@ cat <<EOF
   ${OTHER_READONLY_SECTIONS}
   .eh_frame_hdr ${RELOCATING-0} : { *(.eh_frame_hdr)${RELOCATING+ *(.eh_frame_entry .eh_frame_entry.*)} }
   .eh_frame     ${RELOCATING-0} : ONLY_IF_RO { KEEP (*(.eh_frame))${RELOCATING+ *(.eh_frame.*)} }
-  .sframe       ${RELOCATING-0} : ONLY_IF_RO { *(.sframe)${RELOCATING+ *(.sframe.*)} }
+  .sframe       ${RELOCATING-0} : ONLY_IF_RO { KEEP (*(.sframe))${RELOCATING+ *(.sframe.*)} }
   .gcc_except_table ${RELOCATING-0} : ONLY_IF_RO { *(.gcc_except_table${RELOCATING+ .gcc_except_table.*}) }
   .gnu_extab ${RELOCATING-0} : ONLY_IF_RO { *(.gnu_extab*) }
 
@@ -794,7 +794,7 @@ emit_data()
 cat <<EOF
   /* Exception handling.  */
   .eh_frame     ${RELOCATING-0} : ONLY_IF_RW { KEEP (*(.eh_frame))${RELOCATING+ *(.eh_frame.*)} }
-  .sframe       ${RELOCATING-0} : ONLY_IF_RW { *(.sframe)${RELOCATING+ *(.sframe.*)} }
+  .sframe       ${RELOCATING-0} : ONLY_IF_RW { KEEP (*(.sframe))${RELOCATING+ *(.sframe.*)} }
   .gnu_extab    ${RELOCATING-0} : ONLY_IF_RW { *(.gnu_extab) }
   .gcc_except_table ${RELOCATING-0} : ONLY_IF_RW { *(.gcc_except_table${RELOCATING+ .gcc_except_table.*}) }
   .exception_ranges ${RELOCATING-0} : ONLY_IF_RW { *(.exception_ranges${RELOCATING+*}) }