]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[SFrame-V3] gas: sframe: testsuite: skip SFrame FDE if .cfi_register SP, reg
authorIndu Bhagat <indu.bhagat@oracle.com>
Fri, 16 Jan 2026 00:43:12 +0000 (16:43 -0800)
committerIndu Bhagat <indu.bhagat@oracle.com>
Fri, 16 Jan 2026 01:02:26 +0000 (17:02 -0800)
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.

gas/gen-sframe.c
gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-4.d [new file with mode: 0644]
gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-4.s [new file with mode: 0644]
gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-5.d [new file with mode: 0644]
gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-5.s [new file with mode: 0644]
gas/testsuite/gas/cfi-sframe/cfi-sframe.exp

index d1f6e3780f6b71a42209b4cc522225fe3a00299f..e5850e5aa00e53447a5f60d14fe087dbe5ef6040 100644 (file)
@@ -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 (file)
index 0000000..1703d81
--- /dev/null
@@ -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 (file)
index 0000000..7c0beda
--- /dev/null
@@ -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 (file)
index 0000000..198e549
--- /dev/null
@@ -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 (file)
index 0000000..fbfee95
--- /dev/null
@@ -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
index b516e531fe086845ed597342cbffeb19546086b1..4fbb04f838f7d77a56b405d85bb3aead98bba937 100644 (file)
@@ -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"