From: Claudiu Zissulescu Date: Fri, 30 Jan 2026 07:27:47 +0000 (-0800) Subject: ld: bfd: sframe: KEEP .sframe sections and support gc-sections X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4b5ff658b4993fae1f347793bddd5c14b76167cd;p=thirdparty%2Fbinutils-gdb.git ld: bfd: sframe: KEEP .sframe sections and support gc-sections 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 Reviewed-by: Jens Remus Signed-off-by: Claudiu Zissulescu --- diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 2f67dce4617..dbf53756200 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -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) diff --git a/bfd/elf-sframe.c b/bfd/elf-sframe.c index 77d9d33d602..241186f8f2d 100644 --- a/bfd/elf-sframe.c +++ b/bfd/elf-sframe.c @@ -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 diff --git a/bfd/elflink.c b/bfd/elflink.c index fcb92c91af9..29b89d4ab9e 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -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. */ 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 <