From 095319fe532cf586dcda63d0927a907c83c696b1 Mon Sep 17 00:00:00 2001 From: Indu Bhagat Date: Fri, 25 Jul 2025 01:47:20 -0700 Subject: [PATCH] gas: sframe: command line option takes precedence over gas directive to emit .sframe section. Fix PR gas/33175 sframe: --gsframe=no does not disable when .cfi_sections directive with .sframe --gsframe=no should also disable generation of SFrame section when explicit CFI directive: .cfi_sections .sframe is specified in the input. This means we need to track whether SFrame generation was explicitly disabled by the user. Introduce a new enum to facilitate disambiguation between GEN_SFRAME_DEFAULT_NONE and GEN_SFRAME_DISABLED. While fixing the bug by adding the enum, keep the upcoming requirement in mind: we will also need to disambiguate between --enable-default-sframe and user-specified --gsframe/--gsframe=yes. The intent is to not display SFrame related warnings or errors like: as_bad (_(".sframe not supported for target")); for unsupported targets if --enable-default-sframe is in effect. This implies we need to have a four state enum ( GEN_SFRAME_DEFAULT_NONE, GEN_SFRAME_CONFIG_ENABLED, GEN_SFRAME_DISABLED, GEN_SFRAME_ENABLED) gas/ PR gas/33175 * dw2gencfi.c (cfi_finish): Check state of flag_gen_sframe to determine whether any SFrame section is generated. * as.h (enum gen_sframe_option): New definition. * as.c (parse_args): Keep track of whether the flag is explicitly enabled or disabled gas/testsuite/ PR gas/33175 * gas/cfi-sframe/cfi-sframe-common-1.d: Remove redundant --gsframe. * gas/cfi-sframe/cfi-sframe.exp: Add new test. * gas/cfi-sframe/cfi-sframe-common-1c.d: New test. No SFrame section if explicit --gsframe=no. * gas/cfi-sframe/cfi-sframe-common-1c.s: New test. --- gas/as.c | 6 ++--- gas/as.h | 26 +++++++++++++++++-- gas/dw2gencfi.c | 11 +++++--- .../gas/cfi-sframe/cfi-sframe-common-1.d | 2 +- .../gas/cfi-sframe/cfi-sframe-common-1c.d | 5 ++++ .../gas/cfi-sframe/cfi-sframe-common-1c.s | 3 +++ gas/testsuite/gas/cfi-sframe/cfi-sframe.exp | 1 + 7 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1c.d create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1c.s diff --git a/gas/as.c b/gas/as.c index bc38cdf93c4..58ed0a59e21 100644 --- a/gas/as.c +++ b/gas/as.c @@ -1042,14 +1042,14 @@ This program has absolutely no warranty.\n")); if (optarg) { if (strcasecmp (optarg, "no") == 0) - flag_gen_sframe = 0; + flag_gen_sframe = GEN_SFRAME_DISABLED; else if (strcasecmp (optarg, "yes") == 0) - flag_gen_sframe = 1; + flag_gen_sframe = GEN_SFRAME_ENABLED; else as_fatal (_("Invalid --gsframe option: `%s'"), optarg); } else - flag_gen_sframe = 1; + flag_gen_sframe = GEN_SFRAME_ENABLED; break; #endif /* OBJ_ELF */ diff --git a/gas/as.h b/gas/as.h index 872c6ddf393..8f2facbaa19 100644 --- a/gas/as.h +++ b/gas/as.h @@ -355,8 +355,30 @@ COMMON int flag_execstack; /* TRUE if .note.GNU-stack section with SEC_CODE should be created */ COMMON int flag_noexecstack; -/* TRUE if .sframe section should be created. */ -COMMON int flag_gen_sframe; +/* PR gas/33175. + Add enumerators to disambiguate between configure-time + enablement (or not) vs user-specficied enablement/disablement (the latter + via command line). The expected usage of these states is: + - user-specified command line takes precedence over configure-time + setting and .cfi_sections directive usage. + - .cfi_sections usage takes precedence over configure-time setting. */ +enum gen_sframe_option +{ + /* Default. SFrame generation not enabled at configure time. GNU as will + not generate SFrame sections by default, unless enabled by user via + command line. */ + GEN_SFRAME_DEFAULT_NONE, + /* SFrame generation enabled at configure time. GNU as will generate SFrame + sections for all objects, unless disabled by user via command line. */ + GEN_SFRAME_CONFIG_ENABLED, + /* User specified disablement via --gsframe=no. */ + GEN_SFRAME_DISABLED, + /* User specified enablement via --gsframe or --gsframe=yes. */ + GEN_SFRAME_ENABLED, +}; + +/* State of the setting for SFrame section creation. */ +COMMON enum gen_sframe_option flag_gen_sframe; /* name of emitted object file */ COMMON const char *out_file_name; diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c index 57fffab2951..c28856cdf24 100644 --- a/gas/dw2gencfi.c +++ b/gas/dw2gencfi.c @@ -2596,10 +2596,13 @@ cfi_finish (void) flag_traditional_format = save_flag_traditional_format; } - /* Generate SFrame section if the user specifies: - - the command line option to gas, or - - .sframe in the .cfi_sections directive. */ - if (flag_gen_sframe || (all_cfi_sections & CFI_EMIT_sframe) != 0) + /* Generate SFrame section if the user: + - enables via the command line option, or + - specifies .sframe in the .cfi_sections directive and does not disable + via the command line. */ + if (flag_gen_sframe == GEN_SFRAME_ENABLED + || ((all_cfi_sections & CFI_EMIT_sframe) != 0 + && flag_gen_sframe != GEN_SFRAME_DISABLED)) { #ifdef support_sframe_p if (support_sframe_p () && !SUPPORT_FRAME_LINKONCE) diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1.d index 8c746809bc8..9c341b49b4a 100644 --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1.d +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1.d @@ -1,4 +1,4 @@ -#as: --gsframe +#as: #objdump: --sframe=.sframe #name: SFrame generation using CFI directive .cfi_sections #... diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1c.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1c.d new file mode 100644 index 00000000000..3493d580d22 --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1c.d @@ -0,0 +1,5 @@ +#as: --gsframe=no +#readelf: -S +#name: No SFrame section with explicit --gsframe=no +#failif +[ ]*\[.*\][ ]+\.sframe[ ]+GNU_SFRAME.* diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1c.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1c.s new file mode 100644 index 00000000000..ac9c6ca2cf3 --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1c.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 82669cd0475..9380c98fc3d 100644 --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp @@ -36,6 +36,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-2" run_dump_test "cfi-sframe-common-3" run_dump_test "cfi-sframe-common-4" -- 2.47.2