diff --git a/bfd/elf-sframe.c b/bfd/elf-sframe.c index 511a297054b..33e4df5b1c7 100644 --- a/bfd/elf-sframe.c +++ b/bfd/elf-sframe.c @@ -211,6 +211,9 @@ _bfd_elf_parse_sframe (bfd *abfd, bfd_size_type sf_size; int decerr = 0; + if (info->discard_sframe) + sec->flags |= SEC_EXCLUDE; + /* Prior versions of assembler and ld were generating SFrame sections with section type SHT_PROGBITS. Issue an error for lack of support for such objects now. Even if section size is zero, a valid section type is diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 012457827e0..8ad10ce6bd1 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->discard_sframe) { 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 0348da9f0a1..901b858fb34 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -4827,7 +4827,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->discard_sframe) { 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 d715fcbd6fb..eac72b8c388 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 discard_sframe: 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 3f2a9ae9832..c219662d2e3 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 0af36e9e310..f1ba6af5269 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 3dcd0aaca72..bd10f0a145b 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 @@ -19211,6 +19212,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 @@ -19218,6 +19220,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` @@ -19273,6 +19276,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 @@ -19481,6 +19487,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 a0a1361a0eb..8c5e9606ac0 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/elf64_s390.sh b/ld/emulparams/elf64_s390.sh index b58314800d1..750e83b714f 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 fb4fcd6ae17..747114bc4b4 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..b7cc10bd981 --- /dev/null +++ b/ld/emulparams/sframe-info.sh @@ -0,0 +1,15 @@ +SFRAME_INFO=yes + +PARSE_AND_LIST_LONGOPTS_SFRAME=' + {"discard-sframe", no_argument, NULL, + OPTION_DISCARD_SFRAME}, +' + +PARSE_AND_LIST_ARGS_CASES_SFRAME=' + case OPTION_DISCARD_SFRAME: + link_info.discard_sframe = 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/emultempl/aarch64elf.em b/ld/emultempl/aarch64elf.em index e15eb432458..cd3a6c63d99 100644 --- a/ld/emultempl/aarch64elf.em +++ b/ld/emultempl/aarch64elf.em @@ -487,6 +487,7 @@ PARSE_AND_LIST_LONGOPTS=' { "fix-cortex-a53-835769", no_argument, NULL, OPTION_FIX_ERRATUM_835769}, { "fix-cortex-a53-843419", optional_argument, NULL, OPTION_FIX_ERRATUM_843419}, { "no-apply-dynamic-relocs", no_argument, NULL, OPTION_NO_APPLY_DYNAMIC_RELOCS}, + { "discard-sframe", no_argument, NULL, OPTION_DISCARD_SFRAME}, ' PARSE_AND_LIST_OPTIONS=' @@ -495,6 +496,7 @@ PARSE_AND_LIST_OPTIONS=' fprintf (file, _(" --no-wchar-size-warning Don'\''t warn about objects with incompatible\n" " wchar_t sizes\n")); fprintf (file, _(" --pic-veneer Always generate PIC interworking veneers\n")); + fprintf (file, _(" --discard-sframe Don'\''t generate SFrame stack trace info in output\n")); fprintf (file, _("\ --stub-group-size=N Maximum size of a group of input sections that\n\ can be handled by one stub section. A negative\n\ @@ -632,6 +634,11 @@ PARSE_AND_LIST_ARGS_CASES=' fatal (_("%P: invalid number `%s'\''\n"), optarg); } break; + + case OPTION_DISCARD_SFRAME: + link_info.discard_sframe = true; + break; + ' # We have our own before_allocation etc. functions, but they call diff --git a/ld/ld.texi b/ld/ld.texi index 1ec56c08337..7cadc853af9 100644 --- a/ld/ld.texi +++ b/ld/ld.texi @@ -3251,9 +3251,13 @@ section and ELF @code{PT_GNU_EH_FRAME} segment header. @item --no-ld-generated-unwind-info Request creation of @code{.eh_frame} unwind info for linker generated code sections like PLT. This option is on by default -if linker generated unwind info is supported. This option also -controls the generation of @code{.sframe} stack trace info for linker -generated code sections like PLT. +if linker generated unwind info is supported. + +@kindex --discard-sframe +@item --discard-sframe +Discard @code{.sframe} stack trace info from the output. This option also +prohibits the creation of SFrame stack trace data for linker generated code +sections like PLT. This option is off by default. @kindex --enable-new-dtags @kindex --disable-new-dtags diff --git a/ld/ldlex.h b/ld/ldlex.h index 1efbe58002b..85e06b6fcc4 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_DISCARD_SFRAME, /* Used by emultempl/aarch64elf.em. */ OPTION_FIX_ERRATUM_835769, OPTION_FIX_ERRATUM_843419, diff --git a/ld/lexsup.c b/ld/lexsup.c index 843b809bacb..158abb6dd8f 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, _("\ + --discard-sframe 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"); diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index 8791df3f3d3..a0a8867dca1 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -430,4 +430,5 @@ if { [supports_dt_relr] } { if { ![skip_sframe_tests] } { run_dump_test "sframe-simple-1" + run_dump_test "sframe-command-line-1" } diff --git a/ld/testsuite/ld-aarch64/sframe-command-line-1.d b/ld/testsuite/ld-aarch64/sframe-command-line-1.d new file mode 100644 index 00000000000..a9255d4abaa --- /dev/null +++ b/ld/testsuite/ld-aarch64/sframe-command-line-1.d @@ -0,0 +1,8 @@ +#as: --gsframe +#source: sframe-foo.s +#source: sframe-bar.s +#readelf: --sframe +#ld: -shared --discard-sframe +#name: Command line option --discard-sframe + +Section '.sframe' has no debugging data. diff --git a/ld/testsuite/ld-s390/s390.exp b/ld/testsuite/ld-s390/s390.exp index b81ebe280da..0fdfb39c5aa 100644 --- a/ld/testsuite/ld-s390/s390.exp +++ b/ld/testsuite/ld-s390/s390.exp @@ -192,5 +192,6 @@ if [istarget "s390x-*-*"] { if { ![skip_sframe_tests] } { run_dump_test "sframe-simple-1" run_dump_test "sframe-plt-1" + run_dump_test "sframe-command-line-1" } } diff --git a/ld/testsuite/ld-s390/sframe-command-line-1.d b/ld/testsuite/ld-s390/sframe-command-line-1.d new file mode 100644 index 00000000000..90ce394f5cf --- /dev/null +++ b/ld/testsuite/ld-s390/sframe-command-line-1.d @@ -0,0 +1,8 @@ +#as: --gsframe +#source: sframe-foo.s +#source: sframe-bar.s +#readelf: --sframe +#ld: -shared --no-rosegment --discard-sframe +#name: Command line option --discard-sframe + +Section '.sframe' has no debugging data. diff --git a/ld/testsuite/ld-x86-64/sframe-command-line-1.d b/ld/testsuite/ld-x86-64/sframe-command-line-1.d new file mode 100644 index 00000000000..3f54ff9f83a --- /dev/null +++ b/ld/testsuite/ld-x86-64/sframe-command-line-1.d @@ -0,0 +1,8 @@ +#as: --gsframe +#source: sframe-foo.s +#source: sframe-bar.s +#readelf: --sframe +#ld: -shared --no-rosegment -z separate-code --discard-sframe +#name: Command line option --discard-sframe + +Section '.sframe' has no debugging data. diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index f80f718c15b..df2bb5ea1bd 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -587,6 +587,7 @@ run_dump_test "tls-le-pic-3-x32" if { ![skip_sframe_tests] } { run_dump_test "sframe-simple-1" + run_dump_test "sframe-command-line-1" run_dump_test "sframe-reloc-1" run_dump_test "sframe-plt-1" run_dump_test "sframe-ibt-plt-1"