[PATCH, V3] gas: sframe: partially process DWARF unwind info in CFI_escape
Indu Bhagat
indu.bhagat@oracle.com
Thu Feb 13 01:14:28 GMT 2025
CFI_escape is most commonly used to include DWARF expressions in the
unwind information. One may also use CFI_escape to add OS-specific CFI
opcodes. Up until now, SFrame generation process would skip generating
SFrame FDE at the mere sight of a CFI_escape opcode.
Fine tune the handling of CFI_escape for SFrame generation by explicitly
checking for few "harmless" (in context of SFrame generation)
CFI_escape DWARF info:
- DW_CFA_expression affecting registers of no significance to SFrame
stack trace info
- DW_CFA_value_offset affecting registers of no significance to SFrame
stack trace info
Expose the current cfi_escape_data structure in dw2gencfi.c to the
relevant header file to allow SFrame generation APIs to use it too.
Valid unwind info may be split across multiple .cfi_escape directives.
Conversely, it is also allowed to simply put multiple DWARF expressions
and/or operations in a single .cfi_escape directive. Handling all of
these cases correctly will need parsing/processing that is not deemed
worth the effort in context of SFrame generation; We continue to skip
generating SFrame FDE for these cases and warn the user.
In future, SFrame stack trace may support non-SP/FP as base register
(albeit in limited form). Add an explicit check in
sframe_xlate_do_escape_expr (to test against the current CFA register)
to ensure the functionality continues to work.
Use differentiated warning text in sframe_xlate_do_val_offset to avoid
confusion to the user as the same function is used for handling
.cfi_val_offset and .cfi_escape DW_CFA_val_offset,...
Also, add a common test with DWARF reg 12 which is non SP / FP on x86_64
and aarch64 (and s390x too).
gas/
* gas/dw2gencfi.c (struct cfi_escape_data): Move from ...
* gas/dw2gencfi.h (struct cfi_escape_data): ... to.
* gas/gen-sframe.c (sframe_xlate_do_val_offset): Include string
for .cfi_escape conditionally.
(sframe_xlate_do_escape_expr): New definition.
(sframe_xlate_do_escape_val_offset): Likewise.
(sframe_xlate_do_cfi_escape): Likewise.
(sframe_do_cfi_insn): Handle CFI_escape explicitly.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe.exp: Add new tests.
* gas/cfi-sframe/cfi-sframe-common-9.d: New test.
* gas/cfi-sframe/cfi-sframe-common-9.s: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-1.s: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-2.s: New test.
---
[Changes in V3]
- Scaling of offset before invoking sframe_xlate_do_val_offset.
- Adjust the commit log.
- Squash the two commits in V2 into a single commit and adjust the
warning text.
- Use stack for temp cfi_insn. Use initialized init style.
- Addressed other review comments.
- Adjust code comments to reflect that not reading bytes as ULEB data
is acceptable, given the other checks in place. Other code comment
adjustments reflecting the discussion during review.
- Consistently check for X_op as O_constant where necessary.
- Adjust code comments in the testcase.
[End of changes in V3]
[Changes in V2]
- Use pointer-to-const when applicable for local vars.
- Early exit if there is no cfi_escape expression.
- Restructure functionality to accommodate the fact that a valid
unwind info may be split across multiple .cfi_escape. If this is the
case, the current implementation bails out. Handling this case does
not appear to be worth the effort.
- Include checking with SFRAME_CFA_RA_REG because we need to detect the
cases when .cfi_escape can affect RA.
- Use if conditional instead of assert block.
[End of changes in V2]
---
gas/dw2gencfi.c | 6 -
gas/dw2gencfi.h | 6 +
gas/gen-sframe.c | 207 +++++++++++++++++-
.../gas/cfi-sframe/cfi-sframe-common-9.d | 22 ++
.../gas/cfi-sframe/cfi-sframe-common-9.s | 18 ++
.../cfi-sframe/cfi-sframe-x86_64-empty-1.d | 17 ++
.../cfi-sframe/cfi-sframe-x86_64-empty-1.s | 11 +
.../cfi-sframe/cfi-sframe-x86_64-empty-2.d | 17 ++
.../cfi-sframe/cfi-sframe-x86_64-empty-2.s | 11 +
gas/testsuite/gas/cfi-sframe/cfi-sframe.exp | 3 +
10 files changed, 305 insertions(+), 13 deletions(-)
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-common-9.d
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-common-9.s
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-1.s
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-2.s
diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c
index 012af0ff33e..41e15cd1463 100644
--- a/gas/dw2gencfi.c
+++ b/gas/dw2gencfi.c
@@ -368,12 +368,6 @@ generic_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
}
#endif
-struct cfi_escape_data
-{
- struct cfi_escape_data *next;
- expressionS exp;
-};
-
struct cie_entry
{
struct cie_entry *next;
diff --git a/gas/dw2gencfi.h b/gas/dw2gencfi.h
index 42eb3863a0a..9b0e5979c0d 100644
--- a/gas/dw2gencfi.h
+++ b/gas/dw2gencfi.h
@@ -93,6 +93,12 @@ extern void cfi_add_CFA_restore_state (void);
#define MULTIPLE_FRAME_SECTIONS (SUPPORT_FRAME_LINKONCE || SUPPORT_COMPACT_EH \
|| TARGET_MULTIPLE_EH_FRAME_SECTIONS)
+struct cfi_escape_data
+{
+ struct cfi_escape_data *next;
+ expressionS exp;
+};
+
struct cfi_insn_data
{
struct cfi_insn_data *next;
diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index 13478efab6b..52a707e82ca 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -1117,11 +1117,15 @@ sframe_xlate_do_offset (struct sframe_xlate_ctx *xlate_ctx,
}
/* Translate DW_CFA_val_offset into SFrame context.
- Return SFRAME_XLATE_OK if success. */
+ Return SFRAME_XLATE_OK if success.
+
+ When cfi_esc_p is true, the cfi_insn argument is hand-crafted using
+ CFI_escape data. See sframe_xlate_do_escape_val_offset. */
static int
-sframe_xlate_do_val_offset (struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED,
- struct cfi_insn_data *cfi_insn)
+sframe_xlate_do_val_offset (const struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED,
+ const struct cfi_insn_data *cfi_insn,
+ bool cfi_esc_p)
{
/* Previous value of register is CFA + offset. However, if the specified
register is not interesting (SP, FP, or RA reg), the current
@@ -1134,7 +1138,8 @@ sframe_xlate_do_val_offset (struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED,
/* Ignore SP reg, if offset matches assumed default rule. */
|| (cfi_insn->u.ri.reg == SFRAME_CFA_SP_REG && cfi_insn->u.ri.offset != 0))
{
- as_warn (_("skipping SFrame FDE; %s register %u in .cfi_val_offset"),
+ as_warn (_("skipping SFrame FDE; %s with %s reg %u"),
+ cfi_esc_p ? ".cfi_escape DW_CFA_val_offset" : ".cfi_val_offset",
sframe_register_name (cfi_insn->u.ri.reg), cfi_insn->u.ri.reg);
return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
}
@@ -1310,6 +1315,192 @@ sframe_xlate_do_gnu_window_save (struct sframe_xlate_ctx *xlate_ctx,
return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
}
+/* Handle DW_CFA_expression in .cfi_escape.
+
+ As with sframe_xlate_do_cfi_escape, the intent of this function is to detect
+ only the simple-to-process but common cases, where skipping over the escape
+ expr data does not affect correctness of the SFrame stack trace data. */
+
+static int
+sframe_xlate_do_escape_expr (const struct sframe_xlate_ctx *xlate_ctx,
+ const struct cfi_insn_data *cfi_insn)
+{
+ const struct cfi_escape_data *e = cfi_insn->u.esc;
+ const struct sframe_row_entry *cur_fre = NULL;
+ int err = SFRAME_XLATE_OK;
+ unsigned int reg = 0;
+ unsigned int i = 0;
+
+ /* Check roughly for an expression
+ DW_CFA_expression: r1 (rdx) (DW_OP_bregN (reg): XXX). */
+#define CFI_ESC_NUM_EXP 4
+ offsetT items[CFI_ESC_NUM_EXP] = {0};
+ while (e->next)
+ {
+ e = e->next;
+ if ((i == 2 && items[1] == 0) /* Zero length in DWARF expr. */
+ || i >= CFI_ESC_NUM_EXP || e->exp.X_op != O_constant)
+ return SFRAME_XLATE_ERR_NOTREPRESENTED;
+ items[i] = e->exp.X_add_number;
+ i++;
+ }
+
+ if (i <= CFI_ESC_NUM_EXP - 1)
+ return SFRAME_XLATE_ERR_NOTREPRESENTED;
+
+ cur_fre = xlate_ctx->cur_fre;
+ /* reg operand to DW_CFA_expression is ULEB128. For the purpose at hand,
+ however, the register value will be less than 127 (CFI_ESC_NUM_EXP set
+ to 4). */
+ reg = items[0];
+#undef CFI_ESC_NUM_EXP
+
+ if (reg == SFRAME_CFA_SP_REG || reg == SFRAME_CFA_FP_REG
+#ifdef SFRAME_FRE_RA_TRACKING
+ || (sframe_ra_tracking_p () && reg == SFRAME_CFA_RA_REG)
+#endif
+ || reg == cur_fre->cfa_base_reg)
+ {
+ as_warn (_("skipping SFrame FDE; "
+ ".cfi_escape DW_CFA_expression with %s reg %u"),
+ sframe_register_name (reg), reg);
+ err = SFRAME_XLATE_ERR_NOTREPRESENTED;
+ }
+
+ return err;
+}
+
+/* Handle DW_CFA_val_offset in .cfi_escape.
+
+ As with sframe_xlate_do_cfi_escape, the intent of this function is to detect
+ only the simple-to-process but common cases, where skipping over the escape
+ expr data does not affect correctness of the SFrame stack trace data. */
+
+static int
+sframe_xlate_do_escape_val_offset (const struct sframe_xlate_ctx *xlate_ctx,
+ const struct cfi_insn_data *cfi_insn)
+{
+ const struct cfi_escape_data *e = cfi_insn->u.esc;
+ int err = SFRAME_XLATE_OK;
+ unsigned int i = 0;
+ unsigned int reg;
+ offsetT offset;
+
+ /* Check for (DW_CFA_val_offset reg scaled_offset) sequence. */
+#define CFI_ESC_NUM_EXP 2
+ offsetT items[CFI_ESC_NUM_EXP] = {0};
+ while (e->next)
+ {
+ e = e->next;
+ if (i >= CFI_ESC_NUM_EXP || e->exp.X_op != O_constant)
+ return SFRAME_XLATE_ERR_NOTREPRESENTED;
+ items[i] = e->exp.X_add_number;
+ i++;
+ }
+ if (i <= CFI_ESC_NUM_EXP - 1)
+ return SFRAME_XLATE_ERR_NOTREPRESENTED;
+
+ /* Both arguments to DW_CFA_val_offset are ULEB128. Especially with APX (on
+ x86) we're going to see DWARF register numbers above 127, for the extended
+ GPRs. And large enough stack frames would also require multi-byte offset
+ representation. However, since we limit our focus on cases when
+ CFI_ESC_NUM_EXP is 2, reading UELB can be skipped. IOW, although not
+ ideal, SFrame FDE generation in case of an APX register in
+ DW_CFA_val_offset is being skipped (PS: this does _not_ mean incorrect
+ SFrame stack trace data).
+
+ Recall that the intent here is to check for simple and prevalent cases,
+ when feasible. */
+
+ reg = items[0];
+ offset = items[1];
+#undef CFI_ESC_NUM_EXP
+
+ /* Invoke sframe_xlate_do_val_offset itself for checking. */
+ struct cfi_insn_data temp = { .insn = DW_CFA_val_offset };
+ temp.u.ri.reg = reg;
+ temp.u.ri.offset = offset * DWARF2_CIE_DATA_ALIGNMENT;
+ err = sframe_xlate_do_val_offset (xlate_ctx, &temp, true);
+
+ return err;
+}
+
+/* Handle CFI_escape in SFrame context.
+
+ .cfi_escape CFI directive allows the user to add arbitrary bytes to the
+ unwind info. DWARF expressions commonly follow after CFI_escape (fake CFI)
+ DWARF opcode. One might also use CFI_escape to add OS-specific CFI opcodes
+ even.
+
+ Complex unwind info added using .cfi_escape directive _may_ be of no
+ consequence for SFrame when the affected registers are not SP, FP, RA or
+ CFA. The challenge in confirming the afore-mentioned is that it needs full
+ parsing (and validation) of the bytes presented after .cfi_escape. Here we
+ take a case-by-case approach towards skipping _some_ instances of
+ .cfi_escape: skip those that can be *easily* determined to be harmless in
+ the context of SFrame stack trace information.
+
+ This function partially processes bytes following .cfi_escape and returns
+ SFRAME_XLATE_OK if OK to skip. */
+
+static int
+sframe_xlate_do_cfi_escape (const struct sframe_xlate_ctx *xlate_ctx,
+ const struct cfi_insn_data *cfi_insn)
+{
+ const struct cfi_escape_data *e;
+ int err = SFRAME_XLATE_OK;
+ offsetT firstop;
+
+ e = cfi_insn->u.esc;
+
+ if (!e)
+ return SFRAME_XLATE_ERR_INVAL;
+
+ if (e->exp.X_op != O_constant)
+ return SFRAME_XLATE_ERR_NOTREPRESENTED;
+
+ firstop = e->exp.X_add_number;
+ switch (firstop)
+ {
+ case DW_CFA_nop:
+ /* One or more nops together are harmless for SFrame. */
+ while (e->next)
+ {
+ e = e->next;
+ if (e->exp.X_op != O_constant || e->exp.X_add_number != DW_CFA_nop)
+ {
+ err = SFRAME_XLATE_ERR_NOTREPRESENTED;
+ break;
+ }
+ }
+ break;
+
+ case DW_CFA_expression:
+ return sframe_xlate_do_escape_expr (xlate_ctx, cfi_insn);
+
+ case DW_CFA_val_offset:
+ return sframe_xlate_do_escape_val_offset (xlate_ctx, cfi_insn);
+
+ /* FIXME - Also add processing for DW_CFA_GNU_args_size in future? */
+
+ default:
+ err = SFRAME_XLATE_ERR_NOTREPRESENTED;
+ break;
+ }
+
+ if (err == SFRAME_XLATE_ERR_NOTREPRESENTED)
+ {
+ /* In all other cases (e.g., DW_CFA_def_cfa_expression or other
+ OS-specific CFI opcodes), skip inspecting the DWARF expression.
+ This may impact the asynchronicity due to loss of coverage.
+ Continue to warn the user and bail out. */
+ as_warn (_("skipping SFrame FDE; .cfi_escape with op (%#lx)"),
+ (unsigned long)firstop);
+ }
+
+ return err;
+}
+
/* Returns the DWARF call frame instruction name or fake CFI name for the
specified CFI opcode, or NULL if the value is not recognized. */
@@ -1384,7 +1575,7 @@ sframe_do_cfi_insn (struct sframe_xlate_ctx *xlate_ctx,
err = sframe_xlate_do_offset (xlate_ctx, cfi_insn);
break;
case DW_CFA_val_offset:
- err = sframe_xlate_do_val_offset (xlate_ctx, cfi_insn);
+ err = sframe_xlate_do_val_offset (xlate_ctx, cfi_insn, false);
break;
case DW_CFA_remember_state:
err = sframe_xlate_do_remember_state (xlate_ctx);
@@ -1406,6 +1597,9 @@ sframe_do_cfi_insn (struct sframe_xlate_ctx *xlate_ctx,
case DW_CFA_register:
err = sframe_xlate_do_register (xlate_ctx, cfi_insn);
break;
+ case CFI_escape:
+ err = sframe_xlate_do_cfi_escape (xlate_ctx, cfi_insn);
+ break;
/* Following CFI opcodes are not processed at this time.
These do not impact the coverage of the basic stack tracing
information as conveyed in the SFrame format. */
@@ -1413,8 +1607,7 @@ sframe_do_cfi_insn (struct sframe_xlate_ctx *xlate_ctx,
case DW_CFA_same_value:
break;
default:
- /* Following skipped operations do, however, impact the asynchronicity:
- - CFI_escape. */
+ /* Other skipped operations may, however, impact the asynchronicity. */
{
const char *cfi_name = sframe_get_cfi_name (op);
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-9.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-9.d
new file mode 100644
index 00000000000..80c92357073
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-9.d
@@ -0,0 +1,22 @@
+#as: --gsframe
+#objdump: --sframe=.sframe
+#name: SFrame cfi_escape 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-9.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-9.s
new file mode 100644
index 00000000000..d0cb71e2e9a
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-9.s
@@ -0,0 +1,18 @@
+## CFI_escape may be used to encode DWARF expressions among other things.
+## Depending on the register applicable for the DWARF expression, skipping
+## SFrame FDE may be OK: SFrame stack trace information is relevant for SP, FP
+## and RA only. In this test, CFI_escape is safe to skip (does not affect
+## correctness of SFrame data). The register 0xc is non SP / FP on both
+## aarch64 and x86_64.
+ .cfi_startproc
+ .long 0
+ .cfi_def_cfa_offset 16
+# DW_CFA_expression,reg 0xc,length 2,DW_OP_breg6,SLEB(-8)
+ .cfi_escape 0x10,0xc,0x2,0x76,0x78
+# DW_CFA_nop
+ .cfi_escape 0x0
+ .cfi_escape 0x0,0x0,0x0,0x0
+# DW_CFA_val_offset,reg 0xc,ULEB scaled offset(32)
+ .cfi_escape 0x14,0xc,0x4
+ .long 0
+ .cfi_endproc
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d
new file mode 100644
index 00000000000..01239944863
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d
@@ -0,0 +1,17 @@
+#as: --gsframe
+#warning: skipping SFrame FDE; \.cfi_escape DW\_CFA\_expression with SP reg 7
+#objdump: --sframe=.sframe
+#name: CFI_escape with register of significance to SFrame
+#...
+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-1.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-1.s
new file mode 100644
index 00000000000..cfb1a95d7c5
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-1.s
@@ -0,0 +1,11 @@
+## CFI_escape may be used to encode DWARF expressions among other things.
+## In this test, a DWARF expression involving a register of interest (REG_SP on
+## x86_64, which is also the CFA in the current FRE) is seen. SFrame
+## generation, is skipped and a warning issued to the user.
+ .cfi_startproc
+ .long 0
+ .cfi_def_cfa_offset 16
+# DW_CFA_expression,reg 0x7,length 2,DW_OP_breg6,SLEB(-8)
+ .cfi_escape 0x10,0x7,0x2,0x76,0x78
+ .long 0
+ .cfi_endproc
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d
new file mode 100644
index 00000000000..482803b65a2
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d
@@ -0,0 +1,17 @@
+#as: --gsframe
+#warning: skipping SFrame FDE; \.cfi\_escape DW\_CFA\_val\_offset with FP reg 6
+#objdump: --sframe=.sframe
+#name: CFI_escape with register of significance to SFrame II
+#...
+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-2.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-2.s
new file mode 100644
index 00000000000..90e108e96ad
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-2.s
@@ -0,0 +1,11 @@
+## CFI_escape may be used to encode DWARF expressions among other things.
+## In this test, a DWARF expression involving a register of interest (REG_SP on
+## x86_64, which is also the CFA in the current FRE) is seen. SFrame
+## generation, is skipped and a warning issued to the user.
+ .cfi_startproc
+ .long 0
+ .cfi_def_cfa_offset 16
+# DW_CFA_val_offset,rbp,ULEB scaled offset(16)
+ .cfi_escape 0x14,0x6,0x2
+ .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 b119b9da73d..fdf7d9518cb 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
@@ -78,6 +78,7 @@ if { ([istarget "x86_64-*-*"] || [istarget "aarch64*-*-*"]) \
run_dump_test "cfi-sframe-common-6"
run_dump_test "cfi-sframe-common-7"
run_dump_test "cfi-sframe-common-8"
+ run_dump_test "cfi-sframe-common-9"
run_dump_test "common-empty-1"
run_dump_test "common-empty-2"
@@ -89,6 +90,8 @@ if { [istarget "x86_64-*-*"] && [gas_sframe_check] } then {
if { [gas_x86_64_check] } then {
set ASFLAGS "$ASFLAGS --64"
run_dump_test "cfi-sframe-x86_64-1"
+ run_dump_test "cfi-sframe-x86_64-empty-1"
+ run_dump_test "cfi-sframe-x86_64-empty-2"
set ASFLAGS "$old_ASFLAGS"
}
}
--
2.43.0
More information about the Binutils
mailing list