[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