[PATCH v4 1/2] ld: bfd: sframe: KEEP .sframe sections and support gc-sections
claudiu.zissulescu-ianculescu@oracle.com
claudiu.zissulescu-ianculescu@oracle.com
Mon Jan 26 15:51:08 GMT 2026
From: Claudiu Zissulescu <claudiu.zissulescu-ianculescu@oracle.com>
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.
The stub changes in bfd_elf_discard_info skip checking the return
value of _bfd_elf_parse_sframe because it may have already been
parsed.
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.
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>
fix
---
bfd/elf-bfd.h | 5 +++++
bfd/elflink.c | 36 ++++++++++++++++++++++++++----------
ld/scripttempl/elf.sc | 4 ++--
3 files changed, 33 insertions(+), 12 deletions(-)
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index c833b7d101b..94525b3606e 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2177,6 +2177,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;
@@ -2258,6 +2261,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)
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 64c1a57b465..26db981dad3 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -14151,7 +14151,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;
@@ -14164,9 +14164,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;
@@ -14703,6 +14706,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);
}
+
+ /* Now parse each .sframe section. Point each .sframe section
+ to each bfd. */
+ 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. */
@@ -15302,15 +15320,13 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
if (!init_reloc_cookie_for_section (&cookie, info, i, false))
return -1;
- if (_bfd_elf_parse_sframe (abfd, info, i, &cookie))
+ _bfd_elf_parse_sframe (abfd, info, i, &cookie);
+ if (_bfd_elf_discard_section_sframe (i,
+ bfd_elf_reloc_symbol_deleted_p,
+ &cookie))
{
- if (_bfd_elf_discard_section_sframe (i,
- bfd_elf_reloc_symbol_deleted_p,
- &cookie))
- {
- if (i->size != i->rawsize)
- changed = 1;
- }
+ if (i->size != i->rawsize)
+ changed = 1;
}
fini_reloc_cookie_for_section (&cookie, i);
}
diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
index 80b4b512536..8a0efc02c86 100644
--- a/ld/scripttempl/elf.sc
+++ b/ld/scripttempl/elf.sc
@@ -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+*}) }
--
2.52.0
More information about the Binutils
mailing list