mips: only patch instruction size when there is a callback on the instruction. this fixes issue #282
This commit is contained in:
parent
f21fa3d966
commit
bc63102e50
@ -11322,7 +11322,7 @@ static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
|
|||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, bool is_bc_slot)
|
static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, bool is_bc_slot, bool *insn_need_patch)
|
||||||
{
|
{
|
||||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
|
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
|
||||||
@ -11345,8 +11345,10 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, bool is_bc_s
|
|||||||
// Unicorn: trace this instruction on request
|
// Unicorn: trace this instruction on request
|
||||||
if (!is_bc_slot && env->uc->hook_insn) {
|
if (!is_bc_slot && env->uc->hook_insn) {
|
||||||
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
|
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
|
||||||
if (trace)
|
if (trace) {
|
||||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
|
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
|
||||||
|
*insn_need_patch = true;
|
||||||
|
}
|
||||||
// if requested to emulate only some instructions, check if
|
// if requested to emulate only some instructions, check if
|
||||||
// we need to exit immediately
|
// we need to exit immediately
|
||||||
if (env->uc->emu_count > 0) {
|
if (env->uc->emu_count > 0) {
|
||||||
@ -13928,7 +13930,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, bool is_bc_slot)
|
static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, bool is_bc_slot, bool *insn_need_patch)
|
||||||
{
|
{
|
||||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||||
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
|
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
|
||||||
@ -13945,8 +13947,10 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, bool is_b
|
|||||||
// Unicorn: trace this instruction on request
|
// Unicorn: trace this instruction on request
|
||||||
if (!is_bc_slot && env->uc->hook_insn) {
|
if (!is_bc_slot && env->uc->hook_insn) {
|
||||||
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
|
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
|
||||||
if (trace)
|
if (trace) {
|
||||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
|
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
|
||||||
|
*insn_need_patch = true;
|
||||||
|
}
|
||||||
// if requested to emulate only some instructions, check if
|
// if requested to emulate only some instructions, check if
|
||||||
// we need to exit immediately
|
// we need to exit immediately
|
||||||
if (env->uc->emu_count > 0) {
|
if (env->uc->emu_count > 0) {
|
||||||
@ -18503,7 +18507,7 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_opc (CPUMIPSState *env, DisasContext *ctx, bool is_bc_slot)
|
static void decode_opc (CPUMIPSState *env, DisasContext *ctx, bool is_bc_slot, bool *insn_need_patch)
|
||||||
{
|
{
|
||||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
#if defined(TARGET_MIPS64)
|
#if defined(TARGET_MIPS64)
|
||||||
@ -18514,7 +18518,6 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, bool is_bc_slot)
|
|||||||
uint32_t op, op1;
|
uint32_t op, op1;
|
||||||
int16_t imm;
|
int16_t imm;
|
||||||
|
|
||||||
|
|
||||||
/* make sure instructions are on a word boundary */
|
/* make sure instructions are on a word boundary */
|
||||||
if (ctx->pc & 0x3) {
|
if (ctx->pc & 0x3) {
|
||||||
env->CP0_BadVAddr = ctx->pc;
|
env->CP0_BadVAddr = ctx->pc;
|
||||||
@ -18525,8 +18528,10 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, bool is_bc_slot)
|
|||||||
// Unicorn: trace this instruction on request
|
// Unicorn: trace this instruction on request
|
||||||
if (!is_bc_slot && env->uc->hook_insn) {
|
if (!is_bc_slot && env->uc->hook_insn) {
|
||||||
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
|
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
|
||||||
if (trace)
|
if (trace) {
|
||||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
|
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
|
||||||
|
*insn_need_patch = true;
|
||||||
|
}
|
||||||
// if requested to emulate only some instructions, check if
|
// if requested to emulate only some instructions, check if
|
||||||
// we need to exit immediately
|
// we need to exit immediately
|
||||||
if (env->uc->emu_count > 0) {
|
if (env->uc->emu_count > 0) {
|
||||||
@ -19268,6 +19273,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
|||||||
ctx.bstate = BS_EXCP;
|
ctx.bstate = BS_EXCP;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
bool insn_need_patch = false;
|
||||||
// Unicorn: save param buffer
|
// Unicorn: save param buffer
|
||||||
if (env->uc->hook_insn)
|
if (env->uc->hook_insn)
|
||||||
save_opparam_ptr = tcg_ctx->gen_opparam_ptr;
|
save_opparam_ptr = tcg_ctx->gen_opparam_ptr;
|
||||||
@ -19278,13 +19284,13 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
|||||||
if (!(ctx.hflags & MIPS_HFLAG_M16)) {
|
if (!(ctx.hflags & MIPS_HFLAG_M16)) {
|
||||||
ctx.opcode = cpu_ldl_code(env, ctx.pc);
|
ctx.opcode = cpu_ldl_code(env, ctx.pc);
|
||||||
insn_bytes = 4;
|
insn_bytes = 4;
|
||||||
decode_opc(env, &ctx, is_bc_slot);
|
decode_opc(env, &ctx, is_bc_slot, &insn_need_patch);
|
||||||
} else if (ctx.insn_flags & ASE_MICROMIPS) {
|
} else if (ctx.insn_flags & ASE_MICROMIPS) {
|
||||||
ctx.opcode = cpu_lduw_code(env, ctx.pc);
|
ctx.opcode = cpu_lduw_code(env, ctx.pc);
|
||||||
insn_bytes = decode_micromips_opc(env, &ctx, is_bc_slot);
|
insn_bytes = decode_micromips_opc(env, &ctx, is_bc_slot, &insn_need_patch);
|
||||||
} else if (ctx.insn_flags & ASE_MIPS16) {
|
} else if (ctx.insn_flags & ASE_MIPS16) {
|
||||||
ctx.opcode = cpu_lduw_code(env, ctx.pc);
|
ctx.opcode = cpu_lduw_code(env, ctx.pc);
|
||||||
insn_bytes = decode_mips16_opc(env, &ctx, is_bc_slot);
|
insn_bytes = decode_mips16_opc(env, &ctx, is_bc_slot, &insn_need_patch);
|
||||||
} else {
|
} else {
|
||||||
generate_exception(&ctx, EXCP_RI);
|
generate_exception(&ctx, EXCP_RI);
|
||||||
ctx.bstate = BS_STOP;
|
ctx.bstate = BS_STOP;
|
||||||
@ -19292,7 +19298,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unicorn: patch the callback for the instruction size
|
// Unicorn: patch the callback for the instruction size
|
||||||
if (!is_bc_slot && env->uc->hook_insn)
|
if (insn_need_patch)
|
||||||
*(save_opparam_ptr + 1) = insn_bytes;
|
*(save_opparam_ptr + 1) = insn_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user