From: Indu Bhagat Date: Wed, 3 Dec 2025 20:50:33 +0000 (-0800) Subject: [SFrame-V3] ld: add --no-sframe-info command line option X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1d4b50c527e8c8da356d4a4a4b66c182a55bb60c;p=thirdparty%2Fbinutils-gdb.git [SFrame-V3] ld: add --no-sframe-info command line option Add a new command line option `--no-sframe-info` to the linker. This option allows users to prevent the linker from generating .sframe sections, including the linker-generated (internal) SFrame sections for PLT entries. Previously, the existing `--no-ld-generated-unwind-info` option controlled whether (not just .eh_frame for PLT entries, but also) SFrame for PLT entries. This change decouples SFrame from other unwind formats (like .eh_frame), allowing for more control over the output binary's SFrame data. The option is added for architectures that currently support SFrame: AArch64, s390x, and x86_64. In a subsequent commit, we will tie this option with discard of all input .sframe sections. TBD: - For aarch64, is adding to both aarch64elf.sh and aarch64linux.sh necessary? The desired outcome is to allow the new command line for aarch64 elf, amd64 elf, s390x elf only. Confirm. bfd/ * elf64-s390.c (elf_s390_create_dynamic_sections): Use no_ld_sframe_info to guard .sframe section creation. * elfxx-x86.c (_bfd_x86_elf_link_setup_gnu_properties): Likewise. include/ * bfdlink.h (struct bfd_link_info): Add no_ld_sframe_info bitfield. ld/ * ldlex.h (enum option_values): Add OPTION_NO_LD_SFRAME_INFO. * lexsup.c (elf_sframe_list_options): New function. (ld_list_options): Add sframe_info argument. Update callers. * emulparams/sframe_info.sh: New file. * emulparams/aarch64elf.sh: Source sframe_info.sh. * emulparams/aarch64linux.sh: Likewise. * emulparams/elf64_s390.sh: Likewise. * emulparams/elf_x86_64.sh: Likewise. * Makefile.am: Update to handle sframe_info.sh and new list options. * configure.ac: Handle SFRAME_INFO target variable. * Makefile.in: Regenerate. * configure: Regenerate. --- diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 7b2b7c21898..ac1708f6b80 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -4309,7 +4309,7 @@ elf_s390_create_dynamic_sections (bfd *dynobj, } /* Create .sframe section for .plt section. */ - if (!info->no_ld_generated_unwind_info) + if (!info->no_ld_sframe_info) { 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 0e1185993ca..d7d12c192cb 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -4840,7 +4840,7 @@ _bfd_x86_elf_link_setup_gnu_properties } /* .sframe sections are emitted for AMD64 ABI only. */ - if (ABI_64_P (info->output_bfd) && !info->no_ld_generated_unwind_info) + if (ABI_64_P (info->output_bfd) && !info->no_ld_sframe_info) { flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY diff --git a/include/bfdlink.h b/include/bfdlink.h index 00fe0f8c7c8..698db231af5 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -475,6 +475,10 @@ struct bfd_link_info linker created sections, TRUE if it should be omitted. */ unsigned int no_ld_generated_unwind_info: 1; + /* TRUE if no .sframe stack trace info should be generated for the output. + This includes linker generated SFrame info as well. */ + unsigned int no_ld_sframe_info: 1; + /* TRUE if BFD should generate a "task linked" object file, similar to relocatable but also with globals converted to statics. */ diff --git a/ld/Makefile.am b/ld/Makefile.am index c006448bdca..b6b1944380a 100644 --- a/ld/Makefile.am +++ b/ld/Makefile.am @@ -42,7 +42,8 @@ ZLIBINC = @zlibinc@ ELF_CFLAGS=-DELF_LIST_OPTIONS=@elf_list_options@ \ -DELF_SHLIB_LIST_OPTIONS=@elf_shlib_list_options@ \ - -DELF_PLT_UNWIND_LIST_OPTIONS=@elf_plt_unwind_list_options@ + -DELF_PLT_UNWIND_LIST_OPTIONS=@elf_plt_unwind_list_options@ \ + -DELF_SFRAME_LIST_OPTIONS=@elf_sframe_list_options@ WARN_CFLAGS = @WARN_CFLAGS@ NO_WERROR = @NO_WERROR@ AM_CFLAGS = $(WARN_CFLAGS) $(ELF_CFLAGS) $(JANSSON_CFLAGS) $(ZSTD_CFLAGS) diff --git a/ld/Makefile.in b/ld/Makefile.in index 0acf5f473e2..060fb5b5152 100644 --- a/ld/Makefile.in +++ b/ld/Makefile.in @@ -520,6 +520,7 @@ docdir = @docdir@ dvidir = @dvidir@ elf_list_options = @elf_list_options@ elf_plt_unwind_list_options = @elf_plt_unwind_list_options@ +elf_sframe_list_options = @elf_sframe_list_options@ elf_shlib_list_options = @elf_shlib_list_options@ enable_initfini_array = @enable_initfini_array@ enable_libctf = @enable_libctf@ @@ -579,7 +580,8 @@ ZLIB = @zlibdir@ -lz ZLIBINC = @zlibinc@ ELF_CFLAGS = -DELF_LIST_OPTIONS=@elf_list_options@ \ -DELF_SHLIB_LIST_OPTIONS=@elf_shlib_list_options@ \ - -DELF_PLT_UNWIND_LIST_OPTIONS=@elf_plt_unwind_list_options@ + -DELF_PLT_UNWIND_LIST_OPTIONS=@elf_plt_unwind_list_options@ \ + -DELF_SFRAME_LIST_OPTIONS=@elf_sframe_list_options@ AM_CFLAGS = $(WARN_CFLAGS) $(ELF_CFLAGS) $(JANSSON_CFLAGS) $(ZSTD_CFLAGS) diff --git a/ld/configure b/ld/configure index 95729556429..a7161189e09 100755 --- a/ld/configure +++ b/ld/configure @@ -644,6 +644,7 @@ EMUL_EXTRA_OFILES EMULATION_OFILES TDIRS EMUL +elf_sframe_list_options elf_plt_unwind_list_options elf_shlib_list_options elf_list_options @@ -11893,7 +11894,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11896 "configure" +#line 11897 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11999,7 +12000,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12002 "configure" +#line 12003 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -19201,6 +19202,7 @@ TDIRS= elf_list_options=false elf_shlib_list_options=false elf_plt_unwind_list_options=false +elf_sframe_list_options=false for targ_alias in `echo $target_alias $enable_targets | sed 's/,/ /g'` do if test "$targ_alias" = "all"; then @@ -19208,6 +19210,7 @@ do elf_list_options=true elf_shlib_list_options=true elf_plt_unwind_list_options=true + elf_sframe_list_options=true else # Canonicalize the secondary target names. result=`$ac_config_sub $targ_alias 2>/dev/null` @@ -19263,6 +19266,9 @@ tdir_$i=$result" if test x${PLT_UNWIND} = xyes; then elf_plt_unwind_list_options=true fi + if test x${SFRAME_INFO} = xyes; then + elf_sframe_list_options=true + fi fi ;; esac @@ -19471,6 +19477,7 @@ _ACEOF + if test x${all_targets} = xtrue; then if test x${have_64_bit_bfd} = xyes; then EMULATION_OFILES='$(ALL_EMULATIONS) $(ALL_64_EMULATIONS)' diff --git a/ld/configure.ac b/ld/configure.ac index 3e44e3361ef..866d31569f2 100644 --- a/ld/configure.ac +++ b/ld/configure.ac @@ -506,6 +506,7 @@ TDIRS= elf_list_options=false elf_shlib_list_options=false elf_plt_unwind_list_options=false +elf_sframe_list_options=false for targ_alias in `echo $target_alias $enable_targets | sed 's/,/ /g'` do if test "$targ_alias" = "all"; then @@ -513,6 +514,7 @@ do elf_list_options=true elf_shlib_list_options=true elf_plt_unwind_list_options=true + elf_sframe_list_options=true else # Canonicalize the secondary target names. result=`$ac_config_sub $targ_alias 2>/dev/null` @@ -568,6 +570,9 @@ tdir_$i=$result" if test x${PLT_UNWIND} = xyes; then elf_plt_unwind_list_options=true fi + if test x${SFRAME_INFO} = xyes; then + elf_sframe_list_options=true + fi fi ;; esac @@ -730,6 +735,7 @@ AC_DEFINE_UNQUOTED([DEFAULT_EMIT_GNU_HASH], AC_SUBST(elf_list_options) AC_SUBST(elf_shlib_list_options) AC_SUBST(elf_plt_unwind_list_options) +AC_SUBST(elf_sframe_list_options) AC_SUBST(EMUL) AC_SUBST(TDIRS) diff --git a/ld/emulparams/aarch64elf.sh b/ld/emulparams/aarch64elf.sh index aa051c76a7a..d4f54de5f51 100644 --- a/ld/emulparams/aarch64elf.sh +++ b/ld/emulparams/aarch64elf.sh @@ -1,3 +1,4 @@ +source_sh ${srcdir}/emulparams/sframe_info.sh source_sh ${srcdir}/emulparams/dt-relr.sh ARCH=aarch64 diff --git a/ld/emulparams/aarch64linux.sh b/ld/emulparams/aarch64linux.sh index 6fe82a70659..97df7cb2d8c 100644 --- a/ld/emulparams/aarch64linux.sh +++ b/ld/emulparams/aarch64linux.sh @@ -1,3 +1,4 @@ +source_sh ${srcdir}/emulparams/sframe_info.sh source_sh ${srcdir}/emulparams/dt-relr.sh ARCH=aarch64 diff --git a/ld/emulparams/elf64_s390.sh b/ld/emulparams/elf64_s390.sh index b58314800d1..c06299af3cb 100644 --- a/ld/emulparams/elf64_s390.sh +++ b/ld/emulparams/elf64_s390.sh @@ -1,4 +1,5 @@ source_sh ${srcdir}/emulparams/plt_unwind.sh +source_sh ${srcdir}/emulparams/sframe_info.sh SCRIPT_NAME=elf ELFSIZE=64 OUTPUT_FORMAT="elf64-s390" diff --git a/ld/emulparams/elf_x86_64.sh b/ld/emulparams/elf_x86_64.sh index 4bab1489b94..d5f5b372abb 100644 --- a/ld/emulparams/elf_x86_64.sh +++ b/ld/emulparams/elf_x86_64.sh @@ -1,4 +1,5 @@ source_sh ${srcdir}/emulparams/plt_unwind.sh +source_sh ${srcdir}/emulparams/sframe_info.sh source_sh ${srcdir}/emulparams/extern_protected_data.sh source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh source_sh ${srcdir}/emulparams/reloc_overflow.sh diff --git a/ld/emulparams/sframe_info.sh b/ld/emulparams/sframe_info.sh new file mode 100644 index 00000000000..b1bc427b43e --- /dev/null +++ b/ld/emulparams/sframe_info.sh @@ -0,0 +1,15 @@ +SFRAME_INFO=yes + +PARSE_AND_LIST_LONGOPTS_SFRAME=' + {"no-sframe-info", no_argument, NULL, + OPTION_NO_LD_SFRAME_INFO}, +' + +PARSE_AND_LIST_ARGS_CASES_SFRAME=' + case OPTION_NO_LD_SFRAME_INFO: + link_info.no_ld_sframe_info = true; + break; +' + +PARSE_AND_LIST_LONGOPTS="$PARSE_AND_LIST_LONGOPTS $PARSE_AND_LIST_LONGOPTS_SFRAME" +PARSE_AND_LIST_ARGS_CASES="$PARSE_AND_LIST_ARGS_CASES $PARSE_AND_LIST_ARGS_CASES_SFRAME" diff --git a/ld/ldlex.h b/ld/ldlex.h index 24cac1cdfc0..3ae5323e70d 100644 --- a/ld/ldlex.h +++ b/ld/ldlex.h @@ -215,6 +215,8 @@ enum option_values /* Used by emulparams/plt_unwind.sh. */ OPTION_LD_GENERATED_UNWIND_INFO, OPTION_NO_LD_GENERATED_UNWIND_INFO, + /* Used by emulparams/sframe_info.sh. */ + OPTION_NO_LD_SFRAME_INFO, /* Used by emultempl/aarch64elf.em. */ OPTION_FIX_ERRATUM_835769, OPTION_FIX_ERRATUM_843419, diff --git a/ld/lexsup.c b/ld/lexsup.c index 5cb77992733..c49bb4c433c 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -2364,13 +2364,23 @@ elf_plt_unwind_list_options (FILE *file) } static void -ld_list_options (FILE *file, bool elf, bool shlib, bool plt_unwind) +elf_sframe_list_options (FILE *file) +{ + fprintf (file, _("\ + --no-sframe-info Don't generate SFrame stack trace info in output\n")); +} + +static void +ld_list_options (FILE *file, bool elf, bool shlib, bool plt_unwind, + bool sframe_info) { if (!elf) return; printf (_("ELF emulations:\n")); if (plt_unwind) elf_plt_unwind_list_options (file); + if (sframe_info) + elf_sframe_list_options (file); elf_static_list_options (file); if (shlib) elf_shlib_list_options (file); @@ -2495,7 +2505,8 @@ help (void) /* xgettext:c-format */ printf (_("%s: emulation specific options:\n"), program_name); ld_list_options (stdout, ELF_LIST_OPTIONS, ELF_SHLIB_LIST_OPTIONS, - ELF_PLT_UNWIND_LIST_OPTIONS); + ELF_PLT_UNWIND_LIST_OPTIONS, + ELF_SFRAME_LIST_OPTIONS); ldemul_list_emulation_options (stdout); printf ("\n");