tcg/tci: Move stack bounds check to compile-time
The existing check was incomplete: (1) Only applied to two of the 7 stores, and not to the loads at all. (2) Only checked the upper, but not the lower bound of the stack. Doing this at compile time means that we don't need to do it at runtime as well. Tested-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
90be4dde24
commit
53f405569c
@ -628,7 +628,6 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
|
|||||||
t0 = tci_read_r32(regs, &tb_ptr);
|
t0 = tci_read_r32(regs, &tb_ptr);
|
||||||
t1 = tci_read_r(regs, &tb_ptr);
|
t1 = tci_read_r(regs, &tb_ptr);
|
||||||
t2 = tci_read_s32(&tb_ptr);
|
t2 = tci_read_s32(&tb_ptr);
|
||||||
tci_assert(t1 != sp_value || (int32_t)t2 < 0);
|
|
||||||
*(uint32_t *)(t1 + t2) = t0;
|
*(uint32_t *)(t1 + t2) = t0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -884,7 +883,6 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
|
|||||||
t0 = tci_read_r64(regs, &tb_ptr);
|
t0 = tci_read_r64(regs, &tb_ptr);
|
||||||
t1 = tci_read_r(regs, &tb_ptr);
|
t1 = tci_read_r(regs, &tb_ptr);
|
||||||
t2 = tci_read_s32(&tb_ptr);
|
t2 = tci_read_s32(&tb_ptr);
|
||||||
tci_assert(t1 != sp_value || (int32_t)t2 < 0);
|
|
||||||
*(uint64_t *)(t1 + t2) = t0;
|
*(uint64_t *)(t1 + t2) = t0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -375,10 +375,20 @@ static void tci_out_label(TCGContext *s, TCGLabel *label)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void stack_bounds_check(TCGReg base, target_long offset)
|
||||||
|
{
|
||||||
|
if (base == TCG_REG_CALL_STACK) {
|
||||||
|
tcg_debug_assert(offset < 0);
|
||||||
|
tcg_debug_assert(offset >= -(CPU_TEMP_BUF_NLONGS * sizeof(long)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
|
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
|
||||||
intptr_t arg2)
|
intptr_t arg2)
|
||||||
{
|
{
|
||||||
uint8_t *old_code_ptr = s->code_ptr;
|
uint8_t *old_code_ptr = s->code_ptr;
|
||||||
|
|
||||||
|
stack_bounds_check(arg1, arg2);
|
||||||
if (type == TCG_TYPE_I32) {
|
if (type == TCG_TYPE_I32) {
|
||||||
tcg_out_op_t(s, INDEX_op_ld_i32);
|
tcg_out_op_t(s, INDEX_op_ld_i32);
|
||||||
tcg_out_r(s, ret);
|
tcg_out_r(s, ret);
|
||||||
@ -514,6 +524,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
|||||||
case INDEX_op_st16_i64:
|
case INDEX_op_st16_i64:
|
||||||
case INDEX_op_st32_i64:
|
case INDEX_op_st32_i64:
|
||||||
case INDEX_op_st_i64:
|
case INDEX_op_st_i64:
|
||||||
|
stack_bounds_check(args[1], args[2]);
|
||||||
tcg_out_r(s, args[0]);
|
tcg_out_r(s, args[0]);
|
||||||
tcg_out_r(s, args[1]);
|
tcg_out_r(s, args[1]);
|
||||||
tcg_debug_assert(args[2] == (int32_t)args[2]);
|
tcg_debug_assert(args[2] == (int32_t)args[2]);
|
||||||
@ -716,6 +727,8 @@ static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
|
|||||||
intptr_t arg2)
|
intptr_t arg2)
|
||||||
{
|
{
|
||||||
uint8_t *old_code_ptr = s->code_ptr;
|
uint8_t *old_code_ptr = s->code_ptr;
|
||||||
|
|
||||||
|
stack_bounds_check(arg1, arg2);
|
||||||
if (type == TCG_TYPE_I32) {
|
if (type == TCG_TYPE_I32) {
|
||||||
tcg_out_op_t(s, INDEX_op_st_i32);
|
tcg_out_op_t(s, INDEX_op_st_i32);
|
||||||
tcg_out_r(s, arg);
|
tcg_out_r(s, arg);
|
||||||
|
Loading…
Reference in New Issue
Block a user