[COMMITTED 12/36] [SFrame-V3] gas: sframe: allow SFrame FDEs with 0 FREs for signal frames
Indu Bhagat
indu.bhagat@oracle.com
Fri Jan 16 06:10:12 GMT 2026
Update the SFrame generation logic in GAS to emit Function Descriptor Entries
(FDEs) for signal frames even when no Frame Row Entries (FREs) could be
generated.
Previously, create_sframe_all () would discard any FDE that failed
translation or resulted in zero FREs. However, for signal frames (marked
with .cfi_signal_frame), preserving the FDE may be valuable even without
stack offsets. The presence of the SFrame FDE with the 'Signal'
attribute may allow stack tracers to identify the frame as a signal
trampoline and potentially apply fallback handling, rather than treating
the PC range as having no stack trace info at all.
The patch modifies create_sframe_all () to detect translation errors for
signal frames, effectively allowing the generation of an empty FDE (0 FREs)
marked with the 'S' attribute.
gas/
* gen-sframe.c (sframe_fde_free): Add NULL check for safety.
(create_sframe_all): Allow FDEs for signal frames even if translation
encountered errors or produced no FREs.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe.exp: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-signal-1.d: New test ensuring
signal frame FDE is emitted with 0 FREs.
* gas/cfi-sframe/cfi-sframe-x86_64-signal-1.s: New test.
---
gas/gen-sframe.c | 20 +++++++++++++------
.../cfi-sframe/cfi-sframe-x86_64-signal-1.d | 18 +++++++++++++++++
.../cfi-sframe/cfi-sframe-x86_64-signal-1.s | 12 +++++++++++
gas/testsuite/gas/cfi-sframe/cfi-sframe.exp | 1 +
4 files changed, 45 insertions(+), 6 deletions(-)
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-signal-1.d
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-signal-1.s
diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index f79f5cdd97f..6818407683a 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -564,7 +564,12 @@ sframe_fde_alloc (void)
static void
sframe_fde_free (struct sframe_func_entry *sframe_fde)
{
- sframe_row_entry_free (sframe_fde->sframe_fres);
+ if (sframe_fde == NULL)
+ return;
+
+ if (sframe_fde->sframe_fres)
+ sframe_row_entry_free (sframe_fde->sframe_fres);
+
XDELETE (sframe_fde);
}
@@ -2098,12 +2103,15 @@ create_sframe_all (void)
/* Initialize the translation context with information anew. */
sframe_xlate_ctx_init (xlate_ctx);
- /* Process and link SFrame FDEs if no error. Also skip adding an SFrame
- FDE if it does not contain any SFrame FREs. There is little use of an
- SFrame FDE if there is no stack tracing information for the
- function. */
+ /* Process and link SFrame FDEs if no error. */
int err = sframe_do_fde (xlate_ctx, dw_fde);
- if (err || xlate_ctx->num_xlate_fres == 0)
+ if (err && get_dw_fde_signal_p (dw_fde))
+ {
+ sframe_xlate_ctx_cleanup (xlate_ctx);
+ err = SFRAME_XLATE_OK;
+ }
+
+ if (err)
{
sframe_xlate_ctx_cleanup (xlate_ctx);
sframe_fde_free (sframe_fde);
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-signal-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-signal-1.d
new file mode 100644
index 00000000000..adffa7dc64e
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-signal-1.d
@@ -0,0 +1,18 @@
+#as: --gsframe
+#warning: \.cfi\_escape with op \(0xf\)
+#objdump: --sframe=.sframe
+#name: Signal Frame with no FREs
+#...
+Contents of the SFrame section .sframe:
+ Header :
+
+ Version: SFRAME_VERSION_3
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
+ CFA fixed RA offset: -8
+ Num FDEs: 1
+ Num FREs: 0
+
+ Function Index :
+
+ func idx \[0\]: pc = 0x0, size = 3 bytes, attr = "S"
+ STARTPC + CFA + FP + RA +
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-signal-1.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-signal-1.s
new file mode 100644
index 00000000000..9394577a9e6
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-signal-1.s
@@ -0,0 +1,12 @@
+ .type foo, @function
+foo:
+ .cfi_startproc
+ .cfi_signal_frame
+# DW_CFA_def_cfa_expression, length, DW_OP_breg9, (sleb)offset, DW_OP_deref
+ .cfi_escape 0xf,0x3,0x79,0x78,0x6
+ nop
+ pop %rbp
+ .cfi_offset rbp, -16
+ ret
+ .cfi_endproc
+ .size foo, .-foo
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
index f7c5abf01b2..d42d2ecae18 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
@@ -63,6 +63,7 @@ if { [istarget "x86_64-*-*"] && [gas_sframe_check] } then {
run_dump_test "cfi-sframe-x86_64-3"
run_dump_test "cfi-sframe-x86_64-pr33170"
run_dump_test "cfi-sframe-x86_64-pr33756"
+ run_dump_test "cfi-sframe-x86_64-signal-1"
run_dump_test "cfi-sframe-x86_64-empty-1"
run_dump_test "cfi-sframe-x86_64-empty-2"
run_dump_test "cfi-sframe-x86_64-empty-3"
--
2.43.0
More information about the Binutils
mailing list