[PATCH,V3 3/4] gas: sframe: handle .cfi_undefined

Indu Bhagat indu.bhagat@oracle.com
Sun May 18 07:52:32 GMT 2025
Fix PR gas/32952 - sframe: incorrect handling of .cfi_undefined in gas

In context of SFrame generation, it is incorrect to simply ignore all
.cfi_undefined.  We may ignore only those .cfi_undefined which are for
registers of no interest (similar to whats done for other CFI
directives).

gas/
        * gen-sframe.c (sframe_xlate_do_cfi_undefined): New definition.
        (sframe_do_cfi_insn): Handle .cfi_undefined.
gas/testsuite/
        * gas/cfi-sframe/cfi-sframe.exp: Add new tests.
        * gas/cfi-sframe/cfi-sframe-common-10.d: New test.
        * gas/cfi-sframe/cfi-sframe-common-10.s: New test.
	* gas/cfi-sframe/cfi-sframe-x86_64-empty-4.d: New test.
	* gas/cfi-sframe/cfi-sframe-x86_64-empty-4.s: New test.

---
[Changes in V3]
  - It is only necessary to check for the appropriate substring in the
    warning meesage.  "no SFrame FDE emitted" need not necessarily be
    checked.
[End of changes in V3]

[Changes in V2]
 - Correct the name of new test.
 - Use cfi_insn->u.r as DW_CFA_undefined has a register operand only.
 - Reword the warning text.
[End of changes in V2]
---
 gas/gen-sframe.c                              | 28 +++++++++++++++++++
 .../gas/cfi-sframe/cfi-sframe-common-10.d     | 22 +++++++++++++++
 .../gas/cfi-sframe/cfi-sframe-common-10.s     | 12 ++++++++
 .../cfi-sframe/cfi-sframe-x86_64-empty-4.d    | 17 +++++++++++
 .../cfi-sframe/cfi-sframe-x86_64-empty-4.s    |  6 ++++
 gas/testsuite/gas/cfi-sframe/cfi-sframe.exp   |  2 ++
 6 files changed, 87 insertions(+)
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-common-10.d
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-common-10.s
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-4.d
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-4.s

diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index aedeb3603a0..a29c959db1c 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -1508,6 +1508,32 @@ sframe_xlate_do_cfi_escape (const struct sframe_xlate_ctx *xlate_ctx,
   return err;
 }
 
+/* Translate DW_CFA_undefined into SFrame context.
+
+   DW_CFA_undefined op indicates that from now on, the previous value of
+   register can’t be restored anymore.  In SFrame stack trace, we cannot
+   represent such a semantic.  So, we skip generating an SFrame FDE for this,
+   when a register of interest is used with DW_CFA_undefined.
+
+   Return SFRAME_XLATE_OK if success.  */
+
+static int
+sframe_xlate_do_cfi_undefined (const struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED,
+			       const struct cfi_insn_data *cfi_insn)
+{
+  if (cfi_insn->u.r == SFRAME_CFA_FP_REG
+      || cfi_insn->u.r == SFRAME_CFA_RA_REG
+      || cfi_insn->u.r == SFRAME_CFA_SP_REG)
+    {
+      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.  */
+    }
+
+  /* Safe to skip.  */
+  return SFRAME_XLATE_OK;
+}
+
 /* Returns the DWARF call frame instruction name or fake CFI name for the
    specified CFI opcode, or NULL if the value is not recognized.  */
 
@@ -1611,6 +1637,8 @@ sframe_do_cfi_insn (struct sframe_xlate_ctx *xlate_ctx,
        These do not impact the coverage of the basic stack tracing
        information as conveyed in the SFrame format.  */
     case DW_CFA_undefined:
+      err = sframe_xlate_do_cfi_undefined (xlate_ctx, cfi_insn);
+      break;
     case DW_CFA_same_value:
       break;
     default:
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-10.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-10.d
new file mode 100644
index 00000000000..106e05d160b
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-10.d
@@ -0,0 +1,22 @@
+#as: --gsframe
+#objdump: --sframe=.sframe
+#name: SFrame cfi_undefined test
+#...
+Contents of the SFrame section .sframe:
+
+  Header :
+
+    Version: SFRAME_VERSION_2
+    Flags: NONE
+#?    CFA fixed FP offset: \-?\d+
+#?    CFA fixed RA offset: \-?\d+
+    Num FDEs: 1
+    Num FREs: 2
+
+  Function Index :
+    func idx \[0\]: pc = 0x0, size = 8 bytes
+    STARTPC + CFA + FP + RA +
+#...
+    0+0004 +sp\+16 +u +[uf] +
+
+#pass
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-10.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-10.s
new file mode 100644
index 00000000000..7761edaf2b7
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-10.s
@@ -0,0 +1,12 @@
+## cfi_undefined when used with "not interesting" registers (from the
+## perspective of SFrame section, non SP/FP/RA registers are not
+## interesting) does not affect the asynchronicity of the SFrame
+## stack trace information.  Such CFI directives can be skipped for SFrame
+## stack trace info generation.
+	.cfi_startproc
+	.long 0
+	.cfi_def_cfa_offset 16
+	.cfi_undefined 1
+	.cfi_undefined 2
+	.long 0
+	.cfi_endproc
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-4.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-4.d
new file mode 100644
index 00000000000..43f09e09d27
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-4.d
@@ -0,0 +1,17 @@
+#as: --gsframe
+#warning: SP reg 7 in \.cfi\_undefined
+#objdump: --sframe=.sframe
+#name: DW_CFA_undefined with register SP
+#...
+Contents of the SFrame section .sframe:
+
+  Header :
+
+    Version: SFRAME_VERSION_2
+    Flags: NONE
+#?    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-4.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-4.s
new file mode 100644
index 00000000000..fae3bbf932a
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-4.s
@@ -0,0 +1,6 @@
+	.cfi_startproc
+	.long 0
+	.cfi_def_cfa_offset 16
+	.cfi_undefined 7
+	.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 b353e27ce56..ad5602fc373 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
@@ -79,6 +79,7 @@ if  { ([istarget "x86_64-*-*"] || [istarget "aarch64*-*-*"]) \
     run_dump_test "cfi-sframe-common-7"
     run_dump_test "cfi-sframe-common-8"
     run_dump_test "cfi-sframe-common-9"
+    run_dump_test "cfi-sframe-common-10"
 
     run_dump_test "common-empty-1"
     run_dump_test "common-empty-2"
@@ -94,6 +95,7 @@ if { [istarget "x86_64-*-*"] && [gas_sframe_check] } then {
 	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"
+	run_dump_test "cfi-sframe-x86_64-empty-4"
 	set ASFLAGS "$old_ASFLAGS"
     }
 }
-- 
2.43.0



More information about the Binutils mailing list