From 7a625e04f2d6c0748edb2c66881d840aff84c81f Mon Sep 17 00:00:00 2001
Message-ID: <7a625e04f2d6c0748edb2c66881d840aff84c81f.1768586181.git.sam@gentoo.org>
In-Reply-To: <5a539353bd3d7080ad98504f908b12a017f41e80.1768586181.git.sam@gentoo.org>
References: <5a539353bd3d7080ad98504f908b12a017f41e80.1768586181.git.sam@gentoo.org>
From: Sam James <sam@gentoo.org>
Date: Tue, 15 Jul 2025 04:50:21 +0100
Subject: [PATCH 4/4] gas: disable SFrame warnings if default-enabled

When bootstrapping Binutils in packaging, I saw:
```
{standard input}: Assembler messages:
{standard input}: Warning: no SFrame FDE emitted; non-SP/FP register 10 in .cfi_def_cfa
{standard input}: Warning: no SFrame FDE emitted; .cfi_escape with op (0xf)
[...]
FAIL: bootstrap with strip
```

Disable all the "no SFrame FDE emitted" warnings if SFrames are default-enabled:
they will still appear with explicit --gsframe=yes. For distributions to
deploy default-enabled SFrames, SFrames need to be opportunistic, which
means not creating a lot of noise in build logs or aborting the build
when SFrames cannot be generated (unless --gsframe is passed explicitly,
of course).

Note that this commit does not preclude the possibility of us emitting
a warning in the default-enabled case in future if it's merited, just it
doesn't seem we ought to in these cases.

gas/
	PR gas/33126
	* gen-sframe.c (sframe_xlate_do_def_cfa): Disable warning.
	(sframe_xlate_do_def_cfa_register): Ditto.
	(sframe_xlate_do_def_cfa_offset): Ditto.
	(sframe_xlate_do_val_offset): Ditto.
	(sframe_xlate_do_register): Ditto.
	(sframe_xlate_do_remember_state): Ditto.
	(sframe_xlate_do_aarch64_negate_ra_state_with_pc): Ditto.
	(sframe_xlate_do_gnu_window_save): Ditto.
	(sframe_xlate_do_escape_expr): Ditto.
	(sframe_xlate_do_cfi_escape): Ditto.
	(sframe_xlate_do_cfi_undefined): Ditto.
	(sframe_do_cfi_insn): Ditto.
	(sframe_do_fde): Ditto.
	* gen-sframe.h (sframe_as_warn): New macro.

Signed-off-by: Sam James <sam@gentoo.org>
---
 gas/gen-sframe.c | 36 ++++++++++++++++++------------------
 gas/gen-sframe.h |  8 ++++++++
 2 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index 0241d4424b6..868decfc0d3 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -1264,7 +1264,7 @@ sframe_xlate_do_def_cfa (struct sframe_xlate_ctx *xlate_ctx,
   bool bound_p = sframe_fre_stack_offset_bound_p (offset, true);
   if (!bound_p)
     {
-      as_warn (_("no SFrame FDE emitted; "
+      sframe_as_warn (_("no SFrame FDE emitted; "
 		 ".cfi_def_cfa with unsupported offset value"));
       return SFRAME_XLATE_ERR_NOTREPRESENTED;
     }
@@ -1285,7 +1285,7 @@ sframe_xlate_do_def_cfa (struct sframe_xlate_ctx *xlate_ctx,
     {
       if (!sframe_support_flex_fde_p ())
 	{
-	  as_warn (_("no SFrame FDE emitted; "
+	  sframe_as_warn (_("no SFrame FDE emitted; "
 		     "non-SP/FP register %u in .cfi_def_cfa"),
 		   cfi_insn->u.ri.reg);
 	  return SFRAME_XLATE_ERR_NOTREPRESENTED;
@@ -1322,7 +1322,7 @@ sframe_xlate_do_def_cfa_register (struct sframe_xlate_ctx *xlate_ctx,
     {
       if (!sframe_support_flex_fde_p ())
 	{
-	  as_warn (_("no SFrame FDE emitted; "
+	  sframe_as_warn (_("no SFrame FDE emitted; "
 		     "non-SP/FP register %u in .cfi_def_cfa_register"),
 		   cfi_insn->u.ri.reg);
 	  return SFRAME_XLATE_ERR_NOTREPRESENTED;
@@ -1368,7 +1368,7 @@ sframe_xlate_do_def_cfa_offset (struct sframe_xlate_ctx *xlate_ctx,
 	}
       else
 	{
-	  as_warn (_("no SFrame FDE emitted; "
+	  sframe_as_warn (_("no SFrame FDE emitted; "
 		     ".cfi_def_cfa_offset with unsupported offset value"));
 	  return SFRAME_XLATE_ERR_NOTREPRESENTED;
 	}
@@ -1377,7 +1377,7 @@ sframe_xlate_do_def_cfa_offset (struct sframe_xlate_ctx *xlate_ctx,
     {
       /* No CFA base register in effect.  Non-SP/FP CFA base register should
 	 not occur, as sframe_xlate_do_def_cfa[_register] would detect this.  */
-      as_warn (_("no SFrame FDE emitted; "
+      sframe_as_warn (_("no SFrame FDE emitted; "
 		 ".cfi_def_cfa_offset without CFA base register in effect"));
       return SFRAME_XLATE_ERR_NOTREPRESENTED;
     }
@@ -1406,7 +1406,7 @@ sframe_xlate_do_offset (struct sframe_xlate_ctx *xlate_ctx,
       && cfi_insn->u.ri.reg == SFRAME_CFA_RA_REG
       && cfi_insn->u.ri.offset != sframe_cfa_ra_offset ())
     {
-      as_warn (_("no SFrame FDE emitted; %s register %u in .cfi_offset"),
+      sframe_as_warn (_("no SFrame FDE emitted; %s register %u in .cfi_offset"),
 	       sframe_register_name (cfi_insn->u.ri.reg), cfi_insn->u.ri.reg);
       return SFRAME_XLATE_ERR_NOTREPRESENTED;  /* Not represented.  */
     }
@@ -1477,7 +1477,7 @@ sframe_xlate_do_val_offset (const struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_U
 	      || (sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG
 		  && cfi_insn->u.ri.offset != SFRAME_S390X_SP_VAL_OFFSET))))
     {
-      as_warn (_("no SFrame FDE emitted; %s with %s reg %u"),
+      sframe_as_warn (_("no SFrame FDE emitted; %s with %s reg %u"),
 	       cfi_esc_p ? ".cfi_escape DW_CFA_val_offset" : ".cfi_val_offset",
 	       sframe_register_name (cfi_insn->u.ri.reg), cfi_insn->u.ri.reg);
       return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented.  */
@@ -1540,7 +1540,7 @@ sframe_xlate_do_register (struct sframe_xlate_ctx *xlate_ctx,
 	  && sframe_get_abi_arch () != SFRAME_ABI_S390X_ENDIAN_BIG)
       || cfi_insn->u.rr.reg1 == SFRAME_CFA_FP_REG)
     {
-      as_warn (_("no SFrame FDE emitted; %s register %u in .cfi_register"),
+      sframe_as_warn (_("no SFrame FDE emitted; %s register %u in .cfi_register"),
 	       sframe_register_name (cfi_insn->u.rr.reg1), cfi_insn->u.rr.reg1);
       return SFRAME_XLATE_ERR_NOTREPRESENTED;  /* Not represented.  */
     }
@@ -1562,7 +1562,7 @@ sframe_xlate_do_remember_state (struct sframe_xlate_ctx *xlate_ctx)
      info for the function involved.  */
   if (!cur_fre)
     {
-      as_warn (_("no SFrame FDE emitted; "
+      sframe_as_warn (_("no SFrame FDE emitted; "
 		 ".cfi_remember_state without prior SFrame FRE state"));
       return SFRAME_XLATE_ERR_INVAL;
     }
@@ -1664,7 +1664,7 @@ static int
 sframe_xlate_do_aarch64_negate_ra_state_with_pc (struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED,
 						 const struct cfi_insn_data *cfi_insn ATTRIBUTE_UNUSED)
 {
-  as_warn (_("no SFrame FDE emitted; .cfi_negate_ra_state_with_pc"));
+  sframe_as_warn (_("no SFrame FDE emitted; .cfi_negate_ra_state_with_pc"));
   /* The used signing method should be encoded inside the FDE in SFrame v3.
      For now, PAuth_LR extension is not supported with SFrame.  */
   return SFRAME_XLATE_ERR_NOTREPRESENTED;  /* Not represented.  */
@@ -1691,7 +1691,7 @@ sframe_xlate_do_gnu_window_save (struct sframe_xlate_ctx *xlate_ctx,
       || abi_arch == SFRAME_ABI_AARCH64_ENDIAN_LITTLE)
     return sframe_xlate_do_aarch64_negate_ra_state (xlate_ctx, cfi_insn);
 
-  as_warn (_("no SFrame FDE emitted; .cfi_window_save"));
+  sframe_as_warn (_("no SFrame FDE emitted; .cfi_window_save"));
   return SFRAME_XLATE_ERR_NOTREPRESENTED;  /* Not represented.  */
 }
 
@@ -1916,7 +1916,7 @@ sframe_xlate_do_escape_expr (struct sframe_xlate_ctx *xlate_ctx,
 	   || (sframe_ra_tracking_p () && reg == SFRAME_CFA_RA_REG)
 	   || reg == sframe_xlate_ctx_get_cur_cfa_reg (xlate_ctx))
     {
-      as_warn (_("no SFrame FDE emitted; "
+      sframe_as_warn (_("no SFrame FDE emitted; "
 		 ".cfi_escape DW_CFA_expression with %s reg %u"),
 	       sframe_register_name (reg), reg);
       err = SFRAME_XLATE_ERR_NOTREPRESENTED;
@@ -2142,7 +2142,7 @@ sframe_xlate_do_cfi_escape (struct sframe_xlate_ctx *xlate_ctx,
 	 OS-specific CFI opcodes), skip inspecting the DWARF expression.
 	 This may impact the asynchronicity due to loss of coverage.
 	 Continue to warn the user and bail out.  */
-      as_warn (_("no SFrame FDE emitted; .cfi_escape with op (%#lx)"),
+      sframe_as_warn (_("no SFrame FDE emitted; .cfi_escape with op (%#lx)"),
 	       (unsigned long)firstop);
       err = SFRAME_XLATE_ERR_NOTREPRESENTED;
     }
@@ -2172,7 +2172,7 @@ sframe_xlate_do_cfi_undefined (const struct sframe_xlate_ctx *xlate_ctx ATTRIBUT
   if (cfi_insn->u.r == SFRAME_CFA_FP_REG
       || cfi_insn->u.r == SFRAME_CFA_SP_REG)
     {
-      as_warn (_("no SFrame FDE emitted; %s reg %u in .cfi_undefined"),
+      sframe_as_warn (_("no SFrame FDE emitted; %s reg %u in .cfi_undefined"),
 	       sframe_register_name (cfi_insn->u.r), cfi_insn->u.r);
       return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented.  */
     }
@@ -2361,7 +2361,7 @@ sframe_do_cfi_insn (struct sframe_xlate_ctx *xlate_ctx,
 
 	if (!cfi_name)
 	  cfi_name = _("(unknown)");
-	as_warn (_("no SFrame FDE emitted; CFI insn %s (%#x)"),
+	sframe_as_warn (_("no SFrame FDE emitted; CFI insn %s (%#x)"),
 		 cfi_name, op);
 	err = SFRAME_XLATE_ERR_NOTREPRESENTED;
       }
@@ -2385,7 +2385,7 @@ sframe_do_fde (struct sframe_xlate_ctx *xlate_ctx,
   /* SFrame format cannot represent a non-default DWARF return column reg.  */
   if (xlate_ctx->dw_fde->return_column != DWARF2_DEFAULT_RETURN_COLUMN)
     {
-      as_warn (_("no SFrame FDE emitted; non-default RA register %u"),
+      sframe_as_warn (_("no SFrame FDE emitted; non-default RA register %u"),
 	       xlate_ctx->dw_fde->return_column);
       return SFRAME_XLATE_ERR_NOTREPRESENTED;
     }
@@ -2427,7 +2427,7 @@ sframe_do_fde (struct sframe_xlate_ctx *xlate_ctx,
      Start PC of a function to a known symbol in the file?  */
   if (xlate_ctx->num_xlate_fres > UINT16_MAX)
     {
-      as_warn (_("no SFrame FDE emitted; Number of FREs exceeds UINT16_MAX"));
+      sframe_as_warn (_("no SFrame FDE emitted; Number of FREs exceeds UINT16_MAX"));
       return SFRAME_XLATE_ERR_NOTREPRESENTED;
     }
 
@@ -2444,7 +2444,7 @@ sframe_do_fde (struct sframe_xlate_ctx *xlate_ctx,
 	  if (fre->ra_loc != SFRAME_FRE_ELEM_LOC_STACK
 	      && fre->fp_loc == SFRAME_FRE_ELEM_LOC_STACK)
 	    {
-	      as_warn (_("no SFrame FDE emitted; FP without RA on stack"));
+	      sframe_as_warn (_("no SFrame FDE emitted; FP without RA on stack"));
 	      return SFRAME_XLATE_ERR_NOTREPRESENTED;
 	    }
 	}
diff --git a/gas/gen-sframe.h b/gas/gen-sframe.h
index 1a1f887d508..062deaa6e70 100644
--- a/gas/gen-sframe.h
+++ b/gas/gen-sframe.h
@@ -21,6 +21,14 @@
 #ifndef GENSFRAME_H
 #define GENSFRAME_H
 
+/* Warnings shouldn't be emitted for the default-enabled case, only when
+   --gsframe is explicitly passed by the user.  */
+#define sframe_as_warn(format, ...) \
+  do {					       \
+    if (flag_gen_sframe == GEN_SFRAME_ENABLED) \
+      as_warn (format, ##__VA_ARGS__);	       \
+  } while (0)
+
 /* Errors shouldn't be emitted either if SFrames are default-enabled, as
    we interpret default-enabled as "opportunistic SFrames".  Users don't
    want to be bothered by something preventing emission of SFrames in
-- 
2.52.0

