mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 01:15:37 +00:00
rework code/block tracing
This commit is contained in:
parent
33180b5afa
commit
2ac1281f82
2
list.c
2
list.c
|
@ -18,6 +18,8 @@ void list_clear(struct list *list)
|
|||
free(cur);
|
||||
cur = next;
|
||||
}
|
||||
list->head = NULL;
|
||||
list->tail = NULL;
|
||||
}
|
||||
|
||||
// returns generated linked list node, or NULL on failure
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
DEF_HELPER_5(uc_tracecode, void, i32, ptr, ptr, i64, ptr)
|
||||
DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64)
|
||||
|
||||
DEF_HELPER_FLAGS_1(clz_arm, TCG_CALL_NO_RWG_SE, i32, i32)
|
||||
|
||||
|
|
|
@ -10970,7 +10970,6 @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
|
|||
static void disas_a64_insn(CPUARMState *env, DisasContext *s)
|
||||
{
|
||||
uint32_t insn;
|
||||
struct hook *hook;
|
||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||
|
||||
// Unicorn: end address tells us to stop emulation
|
||||
|
@ -10985,10 +10984,8 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
|
|||
s->pc += 4;
|
||||
|
||||
// Unicorn: trace this instruction on request
|
||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) {
|
||||
if (! HOOK_BOUND_CHECK(hook, s->pc - 4))
|
||||
continue;
|
||||
gen_uc_tracecode(tcg_ctx, 4, hook->callback, env->uc, s->pc - 4, hook->user_data);
|
||||
if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, s->pc - 4)) {
|
||||
gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, env->uc, s->pc - 4);
|
||||
// the callback might want to stop emulation immediately
|
||||
check_exit_request(tcg_ctx);
|
||||
}
|
||||
|
@ -11044,7 +11041,6 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
|
|||
int max_insns;
|
||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||
bool block_full = false;
|
||||
struct hook *hook;
|
||||
|
||||
pc_start = tb->pc;
|
||||
|
||||
|
@ -11116,14 +11112,10 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
|
|||
// Unicorn: trace this block on request
|
||||
// Only hook this block if it is not broken from previous translation due to
|
||||
// full translation cache
|
||||
if (! env->uc->block_full) {
|
||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) {
|
||||
if (! HOOK_BOUND_CHECK(hook, pc_start))
|
||||
continue;
|
||||
// save block address to see if we need to patch block size later
|
||||
env->uc->block_addr = pc_start;
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, pc_start, hook->user_data);
|
||||
}
|
||||
if (! env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
|
||||
// save block address to see if we need to patch block size later
|
||||
env->uc->block_addr = pc_start;
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
|
||||
}
|
||||
|
||||
gen_tb_start(tcg_ctx);
|
||||
|
|
|
@ -7680,7 +7680,6 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq
|
|||
TCGv_i32 tmp3;
|
||||
TCGv_i32 addr;
|
||||
TCGv_i64 tmp64;
|
||||
struct hook *hook;
|
||||
|
||||
/* M variants do not implement ARM mode. */
|
||||
if (arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
|
@ -7688,10 +7687,8 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq
|
|||
}
|
||||
|
||||
// Unicorn: trace this instruction on request
|
||||
HOOK_FOREACH(s->uc, hook, UC_HOOK_CODE) {
|
||||
if (! HOOK_BOUND_CHECK(hook, s->pc - 4))
|
||||
continue;
|
||||
gen_uc_tracecode(tcg_ctx, 4, hook->callback, s->uc, s->pc - 4, hook->user_data);
|
||||
if (HOOK_EXISTS_BOUNDED(s->uc, UC_HOOK_CODE, s->pc - 4)) {
|
||||
gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, s->uc, s->pc - 4);
|
||||
// the callback might want to stop emulation immediately
|
||||
check_exit_request(tcg_ctx);
|
||||
}
|
||||
|
@ -10391,7 +10388,6 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
|
|||
TCGv_i32 tmp;
|
||||
TCGv_i32 tmp2;
|
||||
TCGv_i32 addr;
|
||||
struct hook *hook;
|
||||
|
||||
// Unicorn: end address tells us to stop emulation
|
||||
if (s->pc == s->uc->addr_end) {
|
||||
|
@ -10410,11 +10406,9 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
|
|||
}
|
||||
|
||||
// Unicorn: trace this instruction on request
|
||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) {
|
||||
if (! HOOK_BOUND_CHECK(hook, s->pc))
|
||||
continue;
|
||||
gen_uc_tracecode(tcg_ctx, 2, hook->callback, env->uc, s->pc, hook->user_data);
|
||||
// check to see if we need to exit immediately
|
||||
if (HOOK_EXISTS_BOUNDED(s->uc, UC_HOOK_CODE, s->pc)) {
|
||||
gen_uc_tracecode(tcg_ctx, 2, UC_HOOK_CODE_IDX, s->uc, s->pc);
|
||||
// the callback might want to stop emulation immediately
|
||||
check_exit_request(tcg_ctx);
|
||||
}
|
||||
|
||||
|
@ -11147,7 +11141,6 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
|
|||
int max_insns;
|
||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||
bool block_full = false;
|
||||
struct hook *hook;
|
||||
|
||||
/* generate intermediate code */
|
||||
|
||||
|
@ -11237,14 +11230,10 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
|
|||
// Unicorn: trace this block on request
|
||||
// Only hook this block if it is not broken from previous translation due to
|
||||
// full translation cache
|
||||
if (!env->uc->block_full) {
|
||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) {
|
||||
if (! HOOK_BOUND_CHECK(hook, pc_start))
|
||||
continue;
|
||||
// save block address to see if we need to patch block size later
|
||||
env->uc->block_addr = pc_start;
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, pc_start, hook->user_data);
|
||||
}
|
||||
if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
|
||||
// save block address to see if we need to patch block size later
|
||||
env->uc->block_addr = pc_start;
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
|
||||
}
|
||||
|
||||
gen_tb_start(tcg_ctx);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
DEF_HELPER_5(uc_tracecode, void, i32, ptr, ptr, i64, ptr)
|
||||
DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64)
|
||||
|
||||
DEF_HELPER_FLAGS_4(cc_compute_all, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, int)
|
||||
DEF_HELPER_FLAGS_4(cc_compute_c, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, int)
|
||||
|
|
|
@ -4745,7 +4745,6 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
|
|||
TCGv cpu_tmp4 = *(TCGv *)tcg_ctx->cpu_tmp4;
|
||||
TCGv **cpu_T = (TCGv **)tcg_ctx->cpu_T;
|
||||
TCGv **cpu_regs = (TCGv **)tcg_ctx->cpu_regs;
|
||||
struct hook *hook = NULL;
|
||||
TCGArg *save_opparam_ptr = tcg_ctx->gen_opparam_ptr;
|
||||
bool cc_op_dirty = s->cc_op_dirty;
|
||||
bool changed_cc_op = false;
|
||||
|
@ -4773,14 +4772,9 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
|
|||
s->last_cc_op = s->cc_op;
|
||||
changed_cc_op = true;
|
||||
}
|
||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) {
|
||||
if (! HOOK_BOUND_CHECK(hook, pc_start))
|
||||
continue;
|
||||
// generate code to call callback
|
||||
gen_uc_tracecode(tcg_ctx, 0xf1f1f1f1, hook->callback, env->uc, pc_start, hook->user_data);
|
||||
// the callback might want to stop emulation immediately
|
||||
check_exit_request(tcg_ctx);
|
||||
}
|
||||
gen_uc_tracecode(tcg_ctx, 0xf1f1f1f1, UC_HOOK_CODE_IDX, env->uc, pc_start);
|
||||
// the callback might want to stop emulation immediately
|
||||
check_exit_request(tcg_ctx);
|
||||
}
|
||||
|
||||
prefixes = 0;
|
||||
|
@ -8173,7 +8167,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
|
|||
gen_helper_unlock(tcg_ctx, cpu_env);
|
||||
|
||||
// Unicorn: patch the callback for the instruction size
|
||||
if (hook) {
|
||||
if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, pc_start)) {
|
||||
// int i;
|
||||
// for(i = 0; i < 20; i++)
|
||||
// printf("=== [%u] = %x\n", i, *(save_opparam_ptr + i));
|
||||
|
@ -8282,7 +8276,6 @@ static inline void gen_intermediate_code_internal(uint8_t *gen_opc_cc_op,
|
|||
int num_insns = 0;
|
||||
int max_insns;
|
||||
bool block_full = false;
|
||||
struct hook *hook;
|
||||
|
||||
/* generate intermediate code */
|
||||
pc_start = tb->pc;
|
||||
|
@ -8388,13 +8381,9 @@ static inline void gen_intermediate_code_internal(uint8_t *gen_opc_cc_op,
|
|||
// Unicorn: trace this block on request
|
||||
// Only hook this block if it is not broken from previous translation due to
|
||||
// full translation cache
|
||||
if (!env->uc->block_full) {
|
||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) {
|
||||
if (! HOOK_BOUND_CHECK(hook, pc_start))
|
||||
continue;
|
||||
env->uc->block_addr = pc_start;
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, pc_start, hook->user_data);
|
||||
}
|
||||
if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
|
||||
env->uc->block_addr = pc_start;
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
|
||||
}
|
||||
|
||||
gen_tb_start(tcg_ctx);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
DEF_HELPER_5(uc_tracecode, void, i32, ptr, ptr, i64, ptr)
|
||||
DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64)
|
||||
|
||||
DEF_HELPER_1(bitrev, i32, i32)
|
||||
DEF_HELPER_1(ff1, i32, i32)
|
||||
|
|
|
@ -3031,7 +3031,6 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
|
|||
{
|
||||
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
||||
uint16_t insn;
|
||||
struct hook *hook;
|
||||
|
||||
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
|
||||
tcg_gen_debug_insn_start(tcg_ctx, s->pc);
|
||||
|
@ -3044,10 +3043,8 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
|
|||
}
|
||||
|
||||
// Unicorn: trace this instruction on request
|
||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) {
|
||||
if (! HOOK_BOUND_CHECK(hook, s->pc))
|
||||
continue;
|
||||
gen_uc_tracecode(tcg_ctx, 2, hook->callback, env->uc, s->pc, hook->user_data);
|
||||
if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, s->pc)) {
|
||||
gen_uc_tracecode(tcg_ctx, 2, UC_HOOK_CODE_IDX, env->uc, s->pc);
|
||||
// the callback might want to stop emulation immediately
|
||||
check_exit_request(tcg_ctx);
|
||||
}
|
||||
|
@ -3075,7 +3072,6 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
|
|||
int max_insns;
|
||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||
bool block_full = false;
|
||||
struct hook *hook;
|
||||
|
||||
/* generate intermediate code */
|
||||
pc_start = tb->pc;
|
||||
|
@ -3110,14 +3106,10 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
|
|||
// Unicorn: trace this block on request
|
||||
// Only hook this block if it is not broken from previous translation due to
|
||||
// full translation cache
|
||||
if (!env->uc->block_full) {
|
||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) {
|
||||
if (! HOOK_BOUND_CHECK(hook, pc_start))
|
||||
continue;
|
||||
// save block address to see if we need to patch block size later
|
||||
env->uc->block_addr = pc_start;
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, pc_start, hook->user_data);
|
||||
}
|
||||
if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
|
||||
// save block address to see if we need to patch block size later
|
||||
env->uc->block_addr = pc_start;
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
|
||||
}
|
||||
|
||||
gen_tb_start(tcg_ctx);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
DEF_HELPER_5(uc_tracecode, void, i32, ptr, ptr, i64, ptr)
|
||||
DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64)
|
||||
|
||||
DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int)
|
||||
DEF_HELPER_2(raise_exception, noreturn, env, i32)
|
||||
|
|
|
@ -11331,7 +11331,6 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, bool *insn_n
|
|||
int op, cnvt_op, op1, offset;
|
||||
int funct;
|
||||
int n_bytes;
|
||||
struct hook *hook;
|
||||
|
||||
op = (ctx->opcode >> 11) & 0x1f;
|
||||
sa = (ctx->opcode >> 2) & 0x7;
|
||||
|
@ -11344,10 +11343,8 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, bool *insn_n
|
|||
n_bytes = 2;
|
||||
|
||||
// Unicorn: trace this instruction on request
|
||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) {
|
||||
if (! HOOK_BOUND_CHECK(hook, ctx->pc))
|
||||
continue;
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, ctx->pc, hook->user_data);
|
||||
if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, ctx->pc)) {
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_CODE_IDX, env->uc, ctx->pc);
|
||||
*insn_need_patch = true;
|
||||
// the callback might want to stop emulation immediately
|
||||
check_exit_request(tcg_ctx);
|
||||
|
@ -13932,7 +13929,6 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, bool *ins
|
|||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
|
||||
uint32_t op;
|
||||
struct hook *hook;
|
||||
|
||||
/* make sure instructions are on a halfword boundary */
|
||||
if (ctx->pc & 0x1) {
|
||||
|
@ -13943,10 +13939,8 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, bool *ins
|
|||
}
|
||||
|
||||
// Unicorn: trace this instruction on request
|
||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) {
|
||||
if (! HOOK_BOUND_CHECK(hook, ctx->pc))
|
||||
continue;
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, ctx->pc, hook->user_data);
|
||||
if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, ctx->pc)) {
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_CODE_IDX, env->uc, ctx->pc);
|
||||
*insn_need_patch = true;
|
||||
// the callback might want to stop emulation immediately
|
||||
check_exit_request(tcg_ctx);
|
||||
|
@ -18505,11 +18499,8 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
|
|||
static void hook_insn(CPUMIPSState *env, DisasContext *ctx, bool *insn_need_patch, int *insn_patch_offset, int offset_value)
|
||||
{
|
||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||
struct hook *hook;
|
||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) {
|
||||
if (! HOOK_BOUND_CHECK(hook, ctx->pc))
|
||||
continue;
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, ctx->pc, hook->user_data);
|
||||
if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, ctx->pc)) {
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_CODE_IDX, env->uc, ctx->pc);
|
||||
*insn_need_patch = true;
|
||||
// the callback might want to stop emulation immediately
|
||||
check_exit_request(tcg_ctx);
|
||||
|
@ -19178,7 +19169,6 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
|||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||
TCGArg *save_opparam_ptr = NULL;
|
||||
bool block_full = false;
|
||||
struct hook *hook;
|
||||
|
||||
if (search_pc)
|
||||
qemu_log("search pc %d\n", search_pc);
|
||||
|
@ -19224,14 +19214,10 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
|||
// Unicorn: trace this block on request
|
||||
// Only hook this block if it is not broken from previous translation due to
|
||||
// full translation cache
|
||||
if (! env->uc->block_full) {
|
||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) {
|
||||
if (! HOOK_BOUND_CHECK(hook, pc_start))
|
||||
continue;
|
||||
// save block address to see if we need to patch block size later
|
||||
env->uc->block_addr = pc_start;
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, pc_start, hook->user_data);
|
||||
}
|
||||
if (! env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
|
||||
// save block address to see if we need to patch block size later
|
||||
env->uc->block_addr = pc_start;
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
|
||||
}
|
||||
|
||||
gen_tb_start(tcg_ctx);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
DEF_HELPER_5(uc_tracecode, void, i32, ptr, ptr, i64, ptr)
|
||||
DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64)
|
||||
DEF_HELPER_1(power_down, void, env)
|
||||
|
||||
#ifndef TARGET_SPARC64
|
||||
|
|
|
@ -2625,7 +2625,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn, bool hook_ins
|
|||
TCGv_i32 cpu_src1_32, cpu_src2_32, cpu_dst_32;
|
||||
TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64;
|
||||
target_long simm;
|
||||
struct hook *hook;
|
||||
|
||||
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
|
||||
tcg_gen_debug_insn_start(tcg_ctx, dc->pc);
|
||||
|
@ -2638,14 +2637,10 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn, bool hook_ins
|
|||
}
|
||||
|
||||
// Unicorn: trace this instruction on request
|
||||
if (hook_insn) {
|
||||
HOOK_FOREACH(dc->uc, hook, UC_HOOK_CODE) {
|
||||
if (! HOOK_BOUND_CHECK(hook, dc->pc))
|
||||
continue;
|
||||
gen_uc_tracecode(tcg_ctx, 4, hook->callback, dc->uc, dc->pc, hook->user_data);
|
||||
// the callback might want to stop emulation immediately
|
||||
check_exit_request(tcg_ctx);
|
||||
}
|
||||
if (hook_insn && HOOK_EXISTS_BOUNDED(dc->uc, UC_HOOK_CODE, dc->pc)) {
|
||||
gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, dc->uc, dc->pc);
|
||||
// the callback might want to stop emulation immediately
|
||||
check_exit_request(tcg_ctx);
|
||||
}
|
||||
|
||||
opc = GET_FIELD(insn, 0, 1);
|
||||
|
@ -5390,7 +5385,6 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
|
|||
unsigned int insn;
|
||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||
bool block_full = false;
|
||||
struct hook *hook;
|
||||
|
||||
memset(dc, 0, sizeof(DisasContext));
|
||||
dc->uc = env->uc;
|
||||
|
@ -5431,14 +5425,10 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
|
|||
// Unicorn: trace this block on request
|
||||
// Only hook this block if it is not broken from previous translation due to
|
||||
// full translation cache
|
||||
if (!env->uc->block_full) {
|
||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) {
|
||||
if (! HOOK_BOUND_CHECK(hook, pc_start))
|
||||
continue;
|
||||
// save block address to see if we need to patch block size later
|
||||
env->uc->block_addr = pc_start;
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, pc_start, hook->user_data);
|
||||
}
|
||||
if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
|
||||
// save block address to see if we need to patch block size later
|
||||
env->uc->block_addr = pc_start;
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
|
||||
}
|
||||
|
||||
gen_tb_start(tcg_ctx);
|
||||
|
|
|
@ -27,14 +27,13 @@
|
|||
|
||||
int gen_new_label(TCGContext *);
|
||||
|
||||
static inline void gen_uc_tracecode(TCGContext *tcg_ctx, int32_t size, void *callback, void *uc, uint64_t pc, void *data)
|
||||
static inline void gen_uc_tracecode(TCGContext *tcg_ctx, int32_t size, int32_t type, void *uc, uint64_t pc)
|
||||
{
|
||||
TCGv_i32 tsize = tcg_const_i32(tcg_ctx, size);
|
||||
TCGv_ptr tcallback = tcg_const_ptr(tcg_ctx, callback);
|
||||
TCGv_i32 ttype = tcg_const_i32(tcg_ctx, type);
|
||||
TCGv_ptr tuc = tcg_const_ptr(tcg_ctx, uc);
|
||||
TCGv_i64 tpc = tcg_const_i64(tcg_ctx, pc);
|
||||
TCGv_ptr tdata = tcg_const_ptr(tcg_ctx, data);
|
||||
gen_helper_uc_tracecode(tcg_ctx, tsize, tcallback, tuc, tpc, tdata);
|
||||
gen_helper_uc_tracecode(tcg_ctx, tsize, ttype, tuc, tpc);
|
||||
}
|
||||
|
||||
static inline void tcg_gen_op0(TCGContext *s, TCGOpcode opc)
|
||||
|
|
|
@ -179,7 +179,7 @@ static int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_s
|
|||
gen_intermediate_code(env, tb);
|
||||
|
||||
// Unicorn: when tracing block, patch 1st operand for block size
|
||||
if (HOOK_EXISTS(env->uc, UC_HOOK_BLOCK) && env->uc->block_addr == tb->pc) {
|
||||
if (env->uc->block_addr == tb->pc && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, tb->pc)) {
|
||||
if (env->uc->block_full) // block size is unknown
|
||||
*(s->gen_opparam_buf + 1) = 0;
|
||||
else
|
||||
|
|
12
uc.c
12
uc.c
|
@ -1009,17 +1009,23 @@ uc_err uc_hook_del(uc_engine *uc, uc_hook hh)
|
|||
}
|
||||
|
||||
// TCG helper
|
||||
void helper_uc_tracecode(int32_t size, void *callback, void *handle, int64_t address, void *user_data);
|
||||
void helper_uc_tracecode(int32_t size, void *callback, void *handle, int64_t address, void *user_data)
|
||||
void helper_uc_tracecode(int32_t size, uc_hook_type type, void *handle, int64_t address);
|
||||
void helper_uc_tracecode(int32_t size, uc_hook_type type, void *handle, int64_t address)
|
||||
{
|
||||
struct uc_struct *uc = handle;
|
||||
struct list_item *cur = uc->hook[type].head;
|
||||
struct hook *hook;
|
||||
|
||||
// sync PC in CPUArchState with address
|
||||
if (uc->set_pc) {
|
||||
uc->set_pc(uc, address);
|
||||
}
|
||||
|
||||
((uc_cb_hookcode_t)callback)(uc, address, size, user_data);
|
||||
while (cur != NULL && !uc->stop_request) {
|
||||
hook = (struct hook *)cur->data;
|
||||
((uc_cb_hookcode_t)hook->callback)(uc, address, size, hook->user_data);
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
|
||||
UNICORN_EXPORT
|
||||
|
|
Loading…
Reference in a new issue