[binutils-gdb] [SFrame-V3] gas: sframe: testsuite: skip SFrame FDE if .cfi_register SP, reg

Indu Bhagat ibhagat@sourceware.org
Fri Jan 16 01:05:17 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=72cd17f0be64f10386631bca93c8f82f2cb46d89

commit 72cd17f0be64f10386631bca93c8f82f2cb46d89
Author: Indu Bhagat <indu.bhagat@oracle.com>
Date:   Thu Jan 15 16:43:12 2026 -0800

    [SFrame-V3] gas: sframe: testsuite: skip SFrame FDE if .cfi_register SP, reg
    
    SFrame does not track the SP.  For recovery of the SP, SFrame relies on
    the architecture/ABI's CFA definition:
    
      CFA = SP [+ offset   // on s390x]
    
    Which results in the following implicit CFA value offset rule for SP:
    
      SP = CFA [- offset   // on s390x]
    
    Where offset is zero for most architectures/ABIs, except s390x.
    
    Therefore .cfi_register SP, reg directives must be rejected, as such
    semantics cannot be represented in SFrame yet.
    
    gas/
            * gas/gen-sframe.c (s390_sframe_xlate_do_register): Check for
            REG_SP and reject while generating a warning.
            (sframe_xlate_do_register): Likewise.
    gas/testsuite/
            * gas/cfi-sframe/cfi-sframe-s390x-err-4.d: New test.
            * gas/cfi-sframe/cfi-sframe-s390x-err-4.s: Likewise.
            * gas/cfi-sframe/cfi-sframe-x86_64-empty-5.d: Likewise.
            * gas/cfi-sframe/cfi-sframe-x86_64-empty-5.s: Likewise.
            * gas/cfi-sframe/cfi-sframe.exp: Add new tests.

Diff:
---
 gas/gen-sframe.c                                     | 20 ++++++++++++++++----
 .../gas/cfi-sframe/cfi-sframe-s390x-err-4.d          | 15 +++++++++++++++
 .../gas/cfi-sframe/cfi-sframe-s390x-err-4.s          |  5 +++++
 .../gas/cfi-sframe/cfi-sframe-x86_64-empty-5.d       | 17 +++++++++++++++++
 .../gas/cfi-sframe/cfi-sframe-x86_64-empty-5.s       |  8 ++++++++
 gas/testsuite/gas/cfi-sframe/cfi-sframe.exp          |  2 ++
 6 files changed, 63 insertions(+), 4 deletions(-)

diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index d1f6e3780f6..e5850e5aa00 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -1485,6 +1485,13 @@ s390_sframe_xlate_do_register (struct sframe_xlate_ctx *xlate_ctx,
 	   && cfi_insn->u.rr.reg1 == SFRAME_CFA_RA_REG)
     sframe_fre_set_ra_track (cur_fre,
 			     SFRAME_V2_S390X_OFFSET_ENCODE_REGNUM (cfi_insn->u.rr.reg2));
+  /* SFrame does not track SP explicitly.  */
+  else if (cfi_insn->u.rr.reg1 == SFRAME_CFA_SP_REG)
+    {
+      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.  */
+    }
 
   return SFRAME_XLATE_OK;
 }
@@ -1523,6 +1530,7 @@ sframe_xlate_do_register (struct sframe_xlate_ctx *xlate_ctx,
 	  cur_fre->fp_deref_p = false;
 	  cur_fre->merge_candidate = false;
 	  xlate_ctx->flex_p = true;
+	  return SFRAME_XLATE_OK;
 	}
       else if (cfi_insn->u.rr.reg1 == SFRAME_CFA_RA_REG)
 	{
@@ -1532,12 +1540,16 @@ sframe_xlate_do_register (struct sframe_xlate_ctx *xlate_ctx,
 	  cur_fre->ra_deref_p = false;
 	  cur_fre->merge_candidate = false;
 	  xlate_ctx->flex_p = true;
+	  return SFRAME_XLATE_OK;
 	}
+      /* Recovering REG_SP from an alternate register is not represented in
+	 SFrame.  Fallthrough if SFRAME_CFA_SP_REG and error out.  */
     }
-  else if (cfi_insn->u.rr.reg1 == SFRAME_CFA_RA_REG
-	   /* Ignore SP reg, as it can be recovered from the CFA tracking
-	      info.  */
-	   || cfi_insn->u.rr.reg1 == SFRAME_CFA_FP_REG)
+
+  if (cfi_insn->u.rr.reg1 == SFRAME_CFA_RA_REG
+      /* SFrame does not track SP explicitly.  */
+      || cfi_insn->u.rr.reg1 == SFRAME_CFA_SP_REG
+      || cfi_insn->u.rr.reg1 == SFRAME_CFA_FP_REG)
     {
       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);
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-4.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-4.d
new file mode 100644
index 00000000000..1703d817ea9
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-4.d
@@ -0,0 +1,15 @@
+#name: SFrame generation on s390x - .cfi_register with SP
+#as: --gsframe
+#warning: SP register 15 in \.cfi\_register
+#objdump: --sframe=.sframe
+#...
+Contents of the SFrame section .sframe:
+
+  Header :
+
+    Version: SFRAME_VERSION_3
+    Flags: SFRAME_F_FDE_FUNC_START_PCREL
+    Num FDEs: 0
+    Num FREs: 0
+
+#pass
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-4.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-4.s
new file mode 100644
index 00000000000..7c0bedab9f2
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-4.s
@@ -0,0 +1,5 @@
+	.cfi_sections .sframe
+	.cfi_startproc
+	.cfi_register r15, r5
+	br	%r7
+	.cfi_endproc
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-5.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-5.d
new file mode 100644
index 00000000000..198e549a5c4
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-5.d
@@ -0,0 +1,17 @@
+#as: --gsframe
+#warning: SP register 7 in \.cfi\_register
+#objdump: --sframe=.sframe
+#name: SP register 7 in .cfi_register
+#...
+Contents of the SFrame section .sframe:
+
+  Header :
+
+    Version: SFRAME_VERSION_3
+    Flags: SFRAME_F_FDE_FUNC_START_PCREL
+#?    CFA fixed FP offset: \-?\d+
+#?    CFA fixed RA offset: \-?\d+
+    Num FDEs: 0
+    Num FREs: 0
+
+#pass
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-5.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-5.s
new file mode 100644
index 00000000000..fbfee957bea
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-5.s
@@ -0,0 +1,8 @@
+# Currently, SFrame does not track REG_SP explicitly.  Ensure graceful
+# behaviour: generate no SFrame FDE for the function, and warn the user.
+	.cfi_startproc
+	.long 0
+	.cfi_def_cfa_offset 16
+	.cfi_register rsp, rcx
+	.long 0
+	.cfi_endproc
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
index b516e531fe0..4fbb04f838f 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
@@ -73,6 +73,7 @@ if { [istarget "x86_64-*-*"] && [gas_sframe_check] } then {
 	run_dump_test "cfi-sframe-x86_64-empty-2"
 	run_dump_test "cfi-sframe-x86_64-empty-3"
 	run_dump_test "cfi-sframe-x86_64-empty-4"
+	run_dump_test "cfi-sframe-x86_64-empty-5"
 	run_dump_test "cfi-sframe-x86_64-empty-pr33277"
 	run_dump_test "cfi-sframe-x86_64-ra-undefined-1"
 	run_dump_test "cfi-sframe-x86_64-ra-undefined-flex-1"
@@ -98,6 +99,7 @@ if { [istarget "s390x*-*-*"] && [gas_sframe_check] } then {
     run_dump_test "cfi-sframe-s390x-err-1"
     run_dump_test "cfi-sframe-s390x-err-2"
     run_dump_test "cfi-sframe-s390x-err-3"
+    run_dump_test "cfi-sframe-s390x-err-4"
     run_dump_test "cfi-sframe-s390x-fpra-offset-1"
     run_dump_test "cfi-sframe-s390x-fpra-offset-2"
     run_dump_test "cfi-sframe-s390x-fpra-register-1"


More information about the Binutils-cvs mailing list