mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 04:24:43 +00:00
gas: sframe: fix PR gas/33277
In SFrame stack trace format, the representation of stack offsets allows for either 1-byte, 2-byte or 4-byte integers. Add new internal function sframe_fre_stack_offset_bound_p () which checks if the given offset is within bounds (at most as a 4-byte integer). Use this to check if CFA offset is within bounds, if not skip emitting the FDE, and warn the user. Reviewed-by: Jens Remus <jremus@linux.ibm.com> gas/ PR gas/33277 * gen-sframe.c (sframe_fre_stack_offset_bound_p): New definition. (sframe_xlate_do_def_cfa): Check bounds of offset. (sframe_xlate_do_def_cfa_offset): Likewise. gas/testsuite/ PR gas/33277 * gas/cfi-sframe/cfi-sframe.exp: Add new test. * gas/cfi-sframe/cfi-sframe-x86_64-empty-pr33277.d: Likewise. * gas/cfi-sframe/cfi-sframe-x86_64-empty-pr33277.s: Likewise.
This commit is contained in:
@@ -147,6 +147,24 @@ sframe_fre_get_cfa_offset (const struct sframe_row_entry * fre)
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* All stack offsets in SFrame stack trace format must be representable as a
|
||||
1-byte (SFRAME_FRE_OFFSET_1B), 2-byte (SFRAME_FRE_OFFSET_2B) or 4-byte
|
||||
(SFRAME_FRE_OFFSET_4B) value.
|
||||
|
||||
At the moment, sanity check on CFA offset (only) is performed to address PR
|
||||
gas/33277. Arguably, such updates to ra_offset or fp_offset will only
|
||||
follow after updates to cfa_offset in a real-world, useful program. */
|
||||
|
||||
static bool
|
||||
sframe_fre_stack_offset_bound_p (offsetT offset, bool cfa_reg_p)
|
||||
{
|
||||
/* For s390x, CFA offset is adjusted to enable 8-bit offsets. */
|
||||
if (cfa_reg_p && sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG)
|
||||
offset = SFRAME_V2_S390X_CFA_OFFSET_ENCODE (offset);
|
||||
|
||||
return (offset >= INT32_MIN && offset <= INT32_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
sframe_fre_set_cfa_offset (struct sframe_row_entry *fre,
|
||||
offsetT cfa_offset)
|
||||
@@ -1059,9 +1077,18 @@ sframe_xlate_do_def_cfa (struct sframe_xlate_ctx *xlate_ctx,
|
||||
cfi_insn->u.ri.reg);
|
||||
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;
|
||||
else if (sframe_fre_stack_offset_bound_p (cfi_insn->u.ri.offset, true))
|
||||
{
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
as_warn (_("no SFrame FDE emitted; "
|
||||
".cfi_def_cfa with unsupported offset value"));
|
||||
return SFRAME_XLATE_ERR_NOTREPRESENTED;
|
||||
}
|
||||
|
||||
return SFRAME_XLATE_OK;
|
||||
}
|
||||
@@ -1117,8 +1144,17 @@ sframe_xlate_do_def_cfa_offset (struct sframe_xlate_ctx *xlate_ctx,
|
||||
if ((cur_fre->cfa_base_reg == SFRAME_CFA_FP_REG)
|
||||
|| (cur_fre->cfa_base_reg == SFRAME_CFA_SP_REG))
|
||||
{
|
||||
sframe_fre_set_cfa_offset (cur_fre, cfi_insn->u.i);
|
||||
cur_fre->merge_candidate = false;
|
||||
if (sframe_fre_stack_offset_bound_p (cfi_insn->u.i, true))
|
||||
{
|
||||
sframe_fre_set_cfa_offset (cur_fre, cfi_insn->u.i);
|
||||
cur_fre->merge_candidate = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
as_warn (_("no SFrame FDE emitted; "
|
||||
".cfi_def_cfa_offset with unsupported offset value"));
|
||||
return SFRAME_XLATE_ERR_NOTREPRESENTED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#as: --gsframe
|
||||
#warning: cfi_def_cfa_offset with unsupported offset value
|
||||
#objdump: --sframe=.sframe
|
||||
#name: DW_CFA_def_cfa_offset with unsupported offset value
|
||||
#...
|
||||
Contents of the SFrame section .sframe:
|
||||
|
||||
Header :
|
||||
|
||||
Version: SFRAME_VERSION_2
|
||||
Flags: SFRAME_F_FDE_FUNC_START_PCREL
|
||||
#? CFA fixed FP offset: \-?\d+
|
||||
#? CFA fixed RA offset: \-?\d+
|
||||
Num FDEs: 0
|
||||
Num FREs: 0
|
||||
|
||||
#pass
|
||||
@@ -0,0 +1,5 @@
|
||||
## CFA stack offset must be representable as a max 4-byte int.
|
||||
## No SFrame stack trace info for this function will be generated.
|
||||
.cfi_startproc
|
||||
.cfi_def_cfa_offset 1099511627808
|
||||
.cfi_endproc
|
||||
@@ -66,6 +66,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-pr33277"
|
||||
run_dump_test "cfi-sframe-x86_64-ra-undefined-1"
|
||||
set ASFLAGS "$old_ASFLAGS"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user