aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Remus <jremus@linux.ibm.com>2024-02-14 11:59:10 +0100
committerJens Remus <jremus@linux.ibm.com>2024-05-16 13:32:22 +0200
commit1efbe98fca238d9620bbeda5d0f5cb07ec6ce28b (patch)
tree5c860cd72373a59686388aa8ebd0bb35a9a58a21
parent32e39c2061646bf63ca524f5d8bfbd42a87f69bc (diff)
downloadbinutils-1efbe98fca238d9620bbeda5d0f5cb07ec6ce28b.zip
binutils-1efbe98fca238d9620bbeda5d0f5cb07ec6ce28b.tar.gz
binutils-1efbe98fca238d9620bbeda5d0f5cb07ec6ce28b.tar.bz2
gas: User readable warnings if SFrame FDE is not generated
The following generic warning message, which is printed whenever the assembler skips generation of SFrame FDE, is not very helpful for the user: skipping SFrame FDE due to DWARF CFI op <name> (0x<hexval>) Whenever possible print meaningful warning messages, when the assembler skips generation of SFrame FDE: - skipping SFrame FDE due to .cfi_def_cfa defining non-SP/FP register <regno> as CFA base register - skipping SFrame FDE due to .cfi_def_cfa_register defining non-SP/FP register <regno> as CFA base register - skipping SFrame FDE due to .cfi_def_cfa_offset without CFA base register in effect - skipping SFrame FDE due to .cfi_def_cfa_offset with non-SP/FP register <regno> as CFA base register in effect - skipping SFrame FDE due to .cfi_val_offset specifying {FP|RA} register - skipping SFrame FDE due to .cfi_remember_state without SFrame FRE state - skipping SFrame FDE due to .cfi_register specifying {SP|FP|RA} register - skipping SFrame FDE due to non-default return-address register <regno> gas/ * gen-sframe.h (SFRAME_FRE_BASE_REG_INVAL): New macro for invalid SFrame FRE CFA base register value of -1. * gen-sframe.c: User readable warnings if SFrame FDE is not generated. gas/testsuite/ * gas/cfi-sframe/common-empty-1.d: Update generic SFrame test case to updated warning message texts. * gas/cfi-sframe/common-empty-2.d: Likewise. * gas/cfi-sframe/common-empty-3.d: Likewise. Reviewed-by: Andreas Krebbel <krebbel@linux.ibm.com> Signed-off-by: Jens Remus <jremus@linux.ibm.com>
-rw-r--r--gas/gen-sframe.c95
-rw-r--r--gas/gen-sframe.h2
-rw-r--r--gas/testsuite/gas/cfi-sframe/common-empty-1.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/common-empty-2.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/common-empty-3.d2
5 files changed, 75 insertions, 28 deletions
diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index f3449bf..9a1773b 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -869,7 +869,7 @@ sframe_row_entry_new (void)
struct sframe_row_entry *fre = XCNEW (struct sframe_row_entry);
/* Reset cfa_base_reg to -1. A value of 0 will imply some valid register
for the supported arches. */
- fre->cfa_base_reg = -1;
+ fre->cfa_base_reg = SFRAME_FRE_BASE_REG_INVAL;
fre->merge_candidate = true;
/* Reset the mangled RA status bit to zero by default. We will initialize it in
sframe_row_entry_initialize () with the sticky bit if set. */
@@ -924,6 +924,23 @@ sframe_row_entry_initialize (struct sframe_row_entry *cur_fre,
cur_fre->mangled_ra_p = prev_fre->mangled_ra_p;
}
+/* Return SFrame register name for SP, FP, and RA, or NULL if other. */
+
+static const char *
+sframe_register_name (unsigned int reg)
+{
+ if (reg == SFRAME_CFA_SP_REG)
+ return "SP";
+ else if (reg == SFRAME_CFA_FP_REG)
+ return "FP";
+#ifdef SFRAME_FRE_RA_TRACKING
+ else if (reg == SFRAME_CFA_RA_REG)
+ return "RA";
+#endif
+ else
+ return NULL;
+}
+
/* Translate DW_CFA_advance_loc into SFrame context.
Return SFRAME_XLATE_OK if success. */
@@ -992,7 +1009,12 @@ sframe_xlate_do_def_cfa (struct sframe_xlate_ctx *xlate_ctx,
SFrame stack trace info for the function. */
if (cfi_insn->u.r != SFRAME_CFA_SP_REG
&& cfi_insn->u.r != SFRAME_CFA_FP_REG)
- return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
+ {
+ as_warn (_("skipping SFrame FDE due to .cfi_def_cfa defining "
+ "non-SP/FP register %u as CFA base register"),
+ cfi_insn->u.r);
+ return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
+ }
sframe_fre_set_cfa_base_reg (cur_fre, cfi_insn->u.ri.reg);
sframe_fre_set_cfa_offset (cur_fre, cfi_insn->u.ri.offset);
cur_fre->merge_candidate = false;
@@ -1017,7 +1039,12 @@ sframe_xlate_do_def_cfa_register (struct sframe_xlate_ctx *xlate_ctx,
skip creating SFrame stack trace info for the function. */
if (cfi_insn->u.r != SFRAME_CFA_SP_REG
&& cfi_insn->u.r != SFRAME_CFA_FP_REG)
- return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
+ {
+ as_warn (_("skipping SFrame FDE due to .cfi_def_cfa_register defining "
+ "non-SP/FP register %u as CFA base register"),
+ cfi_insn->u.r);
+ return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
+ }
sframe_fre_set_cfa_base_reg (cur_fre, cfi_insn->u.ri.reg);
sframe_fre_set_cfa_offset (cur_fre, last_fre->cfa_offset);
cur_fre->merge_candidate = false;
@@ -1048,7 +1075,16 @@ sframe_xlate_do_def_cfa_offset (struct sframe_xlate_ctx *xlate_ctx,
cur_fre->merge_candidate = false;
}
else
- return SFRAME_XLATE_ERR_NOTREPRESENTED;
+ {
+ if (cur_fre->cfa_base_reg == SFRAME_FRE_BASE_REG_INVAL)
+ as_warn (_("skipping SFrame FDE due to .cfi_def_cfa_offset without "
+ "CFA base register in effect"));
+ else
+ as_warn (_("skipping SFrame FDE due to .cfi_def_cfa_offset with "
+ "non-SP/FP register %u as CFA base register in effect"),
+ cur_fre->cfa_base_reg);
+ return SFRAME_XLATE_ERR_NOTREPRESENTED;
+ }
return SFRAME_XLATE_OK;
}
@@ -1098,13 +1134,16 @@ sframe_xlate_do_val_offset (struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED,
register is not interesting (FP or RA reg), the current DW_CFA_val_offset
instruction can be safely skipped without sacrificing the asynchronicity of
stack trace information. */
- if (cfi_insn->u.r == SFRAME_CFA_FP_REG)
- return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
+ if (cfi_insn->u.r == SFRAME_CFA_FP_REG
#ifdef SFRAME_FRE_RA_TRACKING
- else if (sframe_ra_tracking_p ()
- && cfi_insn->u.r == SFRAME_CFA_RA_REG)
- return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
+ || (sframe_ra_tracking_p () && cfi_insn->u.r == SFRAME_CFA_RA_REG)
#endif
+ )
+ {
+ as_warn (_("skipping SFrame FDE due to .cfi_val_offset specifying %s register"),
+ sframe_register_name (cfi_insn->u.r));
+ return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
+ }
/* Safe to skip. */
return SFRAME_XLATE_OK;
@@ -1126,7 +1165,11 @@ sframe_xlate_do_register (struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED,
|| (cfi_insn->u.rr.reg1 == SFRAME_CFA_RA_REG)
#endif
|| cfi_insn->u.rr.reg1 == SFRAME_CFA_FP_REG)
- return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
+ {
+ as_warn (_("skipping SFrame FDE due to .cfi_register specifying %s register"),
+ sframe_register_name (cfi_insn->u.rr.reg1));
+ return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
+ }
/* Safe to skip. */
return SFRAME_XLATE_OK;
@@ -1144,7 +1187,10 @@ sframe_xlate_do_remember_state (struct sframe_xlate_ctx *xlate_ctx)
early with non-zero error code, this will cause no SFrame stack trace
info for the function involved. */
if (!last_fre)
- return SFRAME_XLATE_ERR_INVAL;
+ {
+ as_warn (_("skipping SFrame FDE due to .cfi_remember_state without SFrame FRE state"));
+ return SFRAME_XLATE_ERR_INVAL;
+ }
if (!xlate_ctx->remember_fre)
xlate_ctx->remember_fre = sframe_row_entry_new ();
@@ -1332,21 +1378,19 @@ sframe_do_cfi_insn (struct sframe_xlate_ctx *xlate_ctx,
default:
/* Following skipped operations do, however, impact the asynchronicity:
- CFI_escape. */
- err = SFRAME_XLATE_ERR_NOTREPRESENTED;
- }
-
- /* An error here will cause no SFrame FDE later. Warn the user because this
- will affect the overall coverage and hence, asynchronicity. */
- if (err)
- {
- const char *cfi_name = sframe_get_cfi_name (op);
-
- if (!cfi_name)
- cfi_name = _("(unknown)");
- as_warn (_("skipping SFrame FDE due to DWARF CFI op %s (%#x)"),
- cfi_name, op);
+ {
+ const char *cfi_name = sframe_get_cfi_name (op);
+
+ if (!cfi_name)
+ cfi_name = _("(unknown)");
+ as_warn (_("skipping SFrame FDE due to DWARF CFI op %s (%#x)"),
+ cfi_name, op);
+ err = SFRAME_XLATE_ERR_NOTREPRESENTED;
+ }
}
+ /* Any error will cause no SFrame FDE later. The user has already been
+ warned. */
return err;
}
@@ -1363,7 +1407,8 @@ sframe_do_fde (struct sframe_xlate_ctx *xlate_ctx,
/* SFrame format cannot represent a non-default DWARF return column reg. */
if (xlate_ctx->dw_fde->return_column != DWARF2_DEFAULT_RETURN_COLUMN)
{
- as_warn (_("skipping SFrame FDE due to non-default DWARF return column"));
+ as_warn (_("skipping SFrame FDE due to non-default return-address register %u"),
+ xlate_ctx->dw_fde->return_column);
return SFRAME_XLATE_ERR_NOTREPRESENTED;
}
diff --git a/gas/gen-sframe.h b/gas/gen-sframe.h
index fbe2fd5..8ed46db 100644
--- a/gas/gen-sframe.h
+++ b/gas/gen-sframe.h
@@ -24,6 +24,8 @@
#define SFRAME_FRE_ELEM_LOC_REG 0
#define SFRAME_FRE_ELEM_LOC_STACK 1
+#define SFRAME_FRE_BASE_REG_INVAL ((unsigned int)-1)
+
/* SFrame Frame Row Entry (FRE).
A frame row entry is a slice of the frame and can be valid for a set of
diff --git a/gas/testsuite/gas/cfi-sframe/common-empty-1.d b/gas/testsuite/gas/cfi-sframe/common-empty-1.d
index d775630..08731b0 100644
--- a/gas/testsuite/gas/cfi-sframe/common-empty-1.d
+++ b/gas/testsuite/gas/cfi-sframe/common-empty-1.d
@@ -1,5 +1,5 @@
#as: --gsframe
-#warning: skipping SFrame FDE due to DWARF CFI op DW_CFA_remember_state \(0xa\)
+#warning: skipping SFrame FDE due to \.cfi_remember_state without SFrame FRE state
#objdump: --sframe=.sframe
#name: Uninteresting cfi directives generate an empty SFrame section
#...
diff --git a/gas/testsuite/gas/cfi-sframe/common-empty-2.d b/gas/testsuite/gas/cfi-sframe/common-empty-2.d
index 20282c7..e759cdd 100644
--- a/gas/testsuite/gas/cfi-sframe/common-empty-2.d
+++ b/gas/testsuite/gas/cfi-sframe/common-empty-2.d
@@ -1,5 +1,5 @@
#as: --gsframe
-#warning: skipping SFrame FDE due to DWARF CFI op DW_CFA_def_cfa_offset \(0xe\)
+#warning: skipping SFrame FDE due to \.cfi_def_cfa_offset without CFA base register in effect
#objdump: --sframe=.sframe
#name: SFrame supports only FP/SP based CFA
#...
diff --git a/gas/testsuite/gas/cfi-sframe/common-empty-3.d b/gas/testsuite/gas/cfi-sframe/common-empty-3.d
index d17521d..5cc37d5 100644
--- a/gas/testsuite/gas/cfi-sframe/common-empty-3.d
+++ b/gas/testsuite/gas/cfi-sframe/common-empty-3.d
@@ -1,5 +1,5 @@
#as: --gsframe
-#warning: skipping SFrame FDE due to non-default DWARF return column
+#warning: skipping SFrame FDE due to non-default return-address register 0
#objdump: --sframe=.sframe
#name: SFrame supports only default return column
#...