[PATCH, V3] gas: sframe: command line option takes precedence

Indu Bhagat indu.bhagat@oracle.com
Fri Jul 25 06:45:34 GMT 2025


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 explcitly disabled by the user.  Introduce a new enum to
facilitate disambiguation between GEN_SFRAME_CONFIG_DISABLED 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.

---
[Changes in V3]
 - Adjust comments for the enum and flag_gen_sframe and add comments for
   the enumerators.
 - Rename GEN_SFRAME_CONFIG_DISABLED to GEN_SFRAME_DEFAULT_NONE.
[End of changes in V3]

[Changes in V2]
  - Sam's usecase of configure time enablement and hiding warnings and
    errors if --enable-default-sframe is in effect means that we need to
    disambguate between --enable-default-sframe and
    --gsframe/--gsframe=yes passed by the user.  Introduce a four state
    enum now.
[End of Changes in V2]
---
 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.43.0



More information about the Binutils mailing list