From 1d349f56fb2efbf245a0eca23d3421952cb71ce6 Mon Sep 17 00:00:00 2001 From: Indu Bhagat Date: Mon, 24 Nov 2025 12:16:05 -0800 Subject: [PATCH] [SFrame-V3] gas: sframe: doc: testsuite: add new command line option --gsframe-3 This option will allow users to select emission of SFrame stack trace information as per the SFrame version 3 specification. Currenly, SFrame version 3 is also the default. In future, as SFrame evolves, similar command line args may be added for future versions. gas/ * as.c (enum gen_sframe_version): New definition. (parse_args): Add option processing for --gsframe-3. * as.h (enum gen_sframe_version): New declaration. * doc/as.texi: Document the new option. * gen-sframe.c (sframe_set_version): Use enum gen_sframe_version as version. (output_sframe): Likewise. gas/testsuite/ * gas/cfi-sframe/cfi-sframe.exp: New test. * gas/cfi-sframe/cfi-sframe-common-1d.d: Test new command line option --gsframe-3. * gas/cfi-sframe/cfi-sframe-common-1d.s: Likewise. --- gas/as.c | 15 +++++++++++- gas/as.h | 7 ++++++ gas/doc/as.texi | 7 +++++- gas/gen-sframe.c | 23 +++++++++++-------- .../gas/cfi-sframe/cfi-sframe-common-1d.d | 13 +++++++++++ .../gas/cfi-sframe/cfi-sframe-common-1d.s | 3 +++ gas/testsuite/gas/cfi-sframe/cfi-sframe.exp | 1 + 7 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1d.d create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1d.s diff --git a/gas/as.c b/gas/as.c index efcc80deef1..1491f6162fd 100644 --- a/gas/as.c +++ b/gas/as.c @@ -118,6 +118,9 @@ bool flag_generate_build_notes = DEFAULT_GENERATE_BUILD_NOTES; #if DEFAULT_SFRAME enum gen_sframe_option flag_gen_sframe = GEN_SFRAME_CONFIG_ENABLED; #endif +/* Version of SFrame stack trace info to generate. Default version is + SFRAME_VERSION_3. */ +enum gen_sframe_version flag_gen_sframe_version = GEN_SFRAME_VERSION_3; segT reg_section; segT expr_section; @@ -318,7 +321,11 @@ Options:\n\ generate GNU Build notes if none are present in the input\n")); fprintf (stream, _("\ --gsframe[={no|yes}] whether to generate SFrame stack trace information\n\ - (default: %s)\n"), DEFAULT_SFRAME ? "yes" : "no"); + (default: %s)\n\ + Default version emitted is V3\n"), + DEFAULT_SFRAME ? "yes" : "no"); + fprintf (stream, _("\ + --gsframe- generate SFrame version information. 3 == \n")); # if defined (TARGET_USE_SCFI) && defined (TARGET_USE_GINSN) fprintf (stream, _("\ --scfi=experimental Synthesize DWARF CFI for hand-written asm\n\ @@ -513,6 +520,7 @@ parse_args (int * pargc, char *** pargv) OPTION_NO_PAD_SECTIONS, OPTION_MULTIBYTE_HANDLING, /* = STD_BASE + 40 */ OPTION_SFRAME, + OPTION_SFRAME_3, OPTION_SCFI, OPTION_INFO, OPTION_NOINFO @@ -547,6 +555,7 @@ parse_args (int * pargc, char *** pargv) ,{"sectname-subst", no_argument, NULL, OPTION_SECTNAME_SUBST} ,{"generate-missing-build-notes", required_argument, NULL, OPTION_ELF_BUILD_NOTES} ,{"gsframe", optional_argument, NULL, OPTION_SFRAME} + ,{"gsframe-3", no_argument, NULL, OPTION_SFRAME_3} # if defined (TARGET_USE_SCFI) && defined (TARGET_USE_GINSN) ,{"scfi", required_argument, NULL, OPTION_SCFI} # endif @@ -1058,6 +1067,10 @@ This program has absolutely no warranty.\n")); flag_gen_sframe = GEN_SFRAME_ENABLED; break; + case OPTION_SFRAME_3: + flag_gen_sframe_version = GEN_SFRAME_VERSION_3; + break; + #endif /* OBJ_ELF */ case 'Z': diff --git a/gas/as.h b/gas/as.h index b743ba95cc7..2455888bc3c 100644 --- a/gas/as.h +++ b/gas/as.h @@ -380,6 +380,13 @@ enum gen_sframe_option /* State of the setting for SFrame section creation. */ COMMON enum gen_sframe_option flag_gen_sframe; +enum gen_sframe_version +{ + GEN_SFRAME_VERSION_3 = 3, +}; + +COMMON enum gen_sframe_version flag_gen_sframe_version; + /* name of emitted object file */ COMMON const char *out_file_name; diff --git a/gas/doc/as.texi b/gas/doc/as.texi index 5c5f499c85c..743bd580d9c 100644 --- a/gas/doc/as.texi +++ b/gas/doc/as.texi @@ -241,6 +241,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}. [@b{--gdwarf-cie-version}=@var{VERSION}] [@b{--generate-missing-build-notes=[no|yes]}] [@b{--gsframe}] [@b{--gsframe=[no|yes]}] + [@b{--gsframe-3}] [@b{--hash-size}=@var{N}] [@b{--help}] [@b{--target-help}] [@b{--info}] [@b{--no-info}] @@ -864,7 +865,11 @@ configure option. Create @var{.sframe} section from CFI directives. The explicit @option{--gsframe=yes} option behaves the same as @option{--gsframe}. Generation can be suppressed with @option{--gsframe=no}. The default can be -controlled by a configure option @option{--enable-default-sframe}. +controlled by a configure option @option{--enable-default-sframe}. The current +version of the emitted SFrame stack trace data is SFRAME_VERSION_3. + +@item --gsframe-3 +Generate SFrame stack trace information as per Version 3 of the specification. @end ifset diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c index 664e62be1c9..f542e25c21a 100644 --- a/gas/gen-sframe.c +++ b/gas/gen-sframe.c @@ -331,16 +331,17 @@ sframe_v3_set_func_info (unsigned int fde_type, unsigned int fre_type, /* SFrame version specific operations setup. */ static void -sframe_set_version (uint32_t sframe_version ATTRIBUTE_UNUSED) +sframe_set_version (enum gen_sframe_version flag_ver) { - sframe_ver_ops.format_version = SFRAME_VERSION_3; - - /* These operations remain the same for SFRAME_VERSION_3 as fre_info and - func_info have not changed from SFRAME_VERSION_2 and SFRAME_VERSION_1. */ - - sframe_ver_ops.set_fre_info = sframe_v1_set_fre_info; - - sframe_ver_ops.set_func_info = sframe_v3_set_func_info; + if (flag_ver == GEN_SFRAME_VERSION_3) + { + sframe_ver_ops.format_version = SFRAME_VERSION_3; + /* These operations remain the same for SFRAME_VERSION_3 as fre_info and + func_info layout has not changed from SFRAME_VERSION_2 and + SFRAME_VERSION_1. */ + sframe_ver_ops.set_fre_info = sframe_v1_set_fre_info; + sframe_ver_ops.set_func_info = sframe_v3_set_func_info; + } } /* SFrame set FRE info. */ @@ -2429,8 +2430,10 @@ output_sframe (segT sframe_seg) { (void) sframe_seg; + /* Currently only SFRAME_VERSION_3 can be emitted. */ + gas_assert (flag_gen_sframe_version == GEN_SFRAME_VERSION_3); /* Setup the version specific access functions. */ - sframe_set_version (SFRAME_VERSION_3); + sframe_set_version (flag_gen_sframe_version); /* Process all fdes and create SFrame stack trace information. */ create_sframe_all (); diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1d.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1d.d new file mode 100644 index 00000000000..23690412678 --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1d.d @@ -0,0 +1,13 @@ +#as: --gsframe-3 +#readelf: --sframe +#name: Generate SFrame V3 section +Contents of the SFrame section .sframe: + Header : + + Version: SFRAME_VERSION_3 + Flags: SFRAME_F_FDE_FUNC_START_PCREL +#... + Num FDEs: 1 + Num FREs: 1 + +#... diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1d.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1d.s new file mode 100644 index 00000000000..ac9c6ca2cf3 --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1d.s @@ -0,0 +1,3 @@ + .cfi_sections .sframe + .cfi_startproc + .cfi_endproc diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp index d7a2afbaf3d..bb1cbbf3d71 100644 --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp @@ -37,6 +37,7 @@ if { ([istarget "x86_64-*-*"] || [istarget "aarch64*-*-*"] run_dump_test "cfi-sframe-common-1" run_dump_test "cfi-sframe-common-1b" run_dump_test "cfi-sframe-common-1c" + run_dump_test "cfi-sframe-common-1d" run_dump_test "cfi-sframe-common-2" run_dump_test "cfi-sframe-common-3" run_dump_test "cfi-sframe-common-4" -- 2.47.3