mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 06:45:35 +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);
|
free(cur);
|
||||||
cur = next;
|
cur = next;
|
||||||
}
|
}
|
||||||
|
list->head = NULL;
|
||||||
|
list->tail = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns generated linked list node, or NULL on failure
|
// 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)
|
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)
|
static void disas_a64_insn(CPUARMState *env, DisasContext *s)
|
||||||
{
|
{
|
||||||
uint32_t insn;
|
uint32_t insn;
|
||||||
struct hook *hook;
|
|
||||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||||
|
|
||||||
// Unicorn: end address tells us to stop emulation
|
// Unicorn: end address tells us to stop emulation
|
||||||
|
@ -10985,10 +10984,8 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
|
||||||
s->pc += 4;
|
s->pc += 4;
|
||||||
|
|
||||||
// Unicorn: trace this instruction on request
|
// Unicorn: trace this instruction on request
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) {
|
if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, s->pc - 4)) {
|
||||||
if (! HOOK_BOUND_CHECK(hook, s->pc - 4))
|
gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, env->uc, s->pc - 4);
|
||||||
continue;
|
|
||||||
gen_uc_tracecode(tcg_ctx, 4, hook->callback, env->uc, s->pc - 4, hook->user_data);
|
|
||||||
// the callback might want to stop emulation immediately
|
// the callback might want to stop emulation immediately
|
||||||
check_exit_request(tcg_ctx);
|
check_exit_request(tcg_ctx);
|
||||||
}
|
}
|
||||||
|
@ -11044,7 +11041,6 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
|
||||||
int max_insns;
|
int max_insns;
|
||||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||||
bool block_full = false;
|
bool block_full = false;
|
||||||
struct hook *hook;
|
|
||||||
|
|
||||||
pc_start = tb->pc;
|
pc_start = tb->pc;
|
||||||
|
|
||||||
|
@ -11116,14 +11112,10 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
|
||||||
// Unicorn: trace this block on request
|
// Unicorn: trace this block on request
|
||||||
// Only hook this block if it is not broken from previous translation due to
|
// Only hook this block if it is not broken from previous translation due to
|
||||||
// full translation cache
|
// full translation cache
|
||||||
if (! env->uc->block_full) {
|
if (! env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) {
|
// save block address to see if we need to patch block size later
|
||||||
if (! HOOK_BOUND_CHECK(hook, pc_start))
|
env->uc->block_addr = pc_start;
|
||||||
continue;
|
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, 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, hook->callback, env->uc, pc_start, hook->user_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_tb_start(tcg_ctx);
|
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 tmp3;
|
||||||
TCGv_i32 addr;
|
TCGv_i32 addr;
|
||||||
TCGv_i64 tmp64;
|
TCGv_i64 tmp64;
|
||||||
struct hook *hook;
|
|
||||||
|
|
||||||
/* M variants do not implement ARM mode. */
|
/* M variants do not implement ARM mode. */
|
||||||
if (arm_dc_feature(s, ARM_FEATURE_M)) {
|
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
|
// Unicorn: trace this instruction on request
|
||||||
HOOK_FOREACH(s->uc, hook, UC_HOOK_CODE) {
|
if (HOOK_EXISTS_BOUNDED(s->uc, UC_HOOK_CODE, s->pc - 4)) {
|
||||||
if (! HOOK_BOUND_CHECK(hook, s->pc - 4))
|
gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, s->uc, s->pc - 4);
|
||||||
continue;
|
|
||||||
gen_uc_tracecode(tcg_ctx, 4, hook->callback, s->uc, s->pc - 4, hook->user_data);
|
|
||||||
// the callback might want to stop emulation immediately
|
// the callback might want to stop emulation immediately
|
||||||
check_exit_request(tcg_ctx);
|
check_exit_request(tcg_ctx);
|
||||||
}
|
}
|
||||||
|
@ -10391,7 +10388,6 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
|
||||||
TCGv_i32 tmp;
|
TCGv_i32 tmp;
|
||||||
TCGv_i32 tmp2;
|
TCGv_i32 tmp2;
|
||||||
TCGv_i32 addr;
|
TCGv_i32 addr;
|
||||||
struct hook *hook;
|
|
||||||
|
|
||||||
// Unicorn: end address tells us to stop emulation
|
// Unicorn: end address tells us to stop emulation
|
||||||
if (s->pc == s->uc->addr_end) {
|
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
|
// Unicorn: trace this instruction on request
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) {
|
if (HOOK_EXISTS_BOUNDED(s->uc, UC_HOOK_CODE, s->pc)) {
|
||||||
if (! HOOK_BOUND_CHECK(hook, s->pc))
|
gen_uc_tracecode(tcg_ctx, 2, UC_HOOK_CODE_IDX, s->uc, s->pc);
|
||||||
continue;
|
// the callback might want to stop emulation immediately
|
||||||
gen_uc_tracecode(tcg_ctx, 2, hook->callback, env->uc, s->pc, hook->user_data);
|
|
||||||
// check to see if we need to exit immediately
|
|
||||||
check_exit_request(tcg_ctx);
|
check_exit_request(tcg_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11147,7 +11141,6 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
|
||||||
int max_insns;
|
int max_insns;
|
||||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||||
bool block_full = false;
|
bool block_full = false;
|
||||||
struct hook *hook;
|
|
||||||
|
|
||||||
/* generate intermediate code */
|
/* generate intermediate code */
|
||||||
|
|
||||||
|
@ -11237,14 +11230,10 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
|
||||||
// Unicorn: trace this block on request
|
// Unicorn: trace this block on request
|
||||||
// Only hook this block if it is not broken from previous translation due to
|
// Only hook this block if it is not broken from previous translation due to
|
||||||
// full translation cache
|
// full translation cache
|
||||||
if (!env->uc->block_full) {
|
if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) {
|
// save block address to see if we need to patch block size later
|
||||||
if (! HOOK_BOUND_CHECK(hook, pc_start))
|
env->uc->block_addr = pc_start;
|
||||||
continue;
|
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, 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, hook->callback, env->uc, pc_start, hook->user_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_tb_start(tcg_ctx);
|
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_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)
|
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_tmp4 = *(TCGv *)tcg_ctx->cpu_tmp4;
|
||||||
TCGv **cpu_T = (TCGv **)tcg_ctx->cpu_T;
|
TCGv **cpu_T = (TCGv **)tcg_ctx->cpu_T;
|
||||||
TCGv **cpu_regs = (TCGv **)tcg_ctx->cpu_regs;
|
TCGv **cpu_regs = (TCGv **)tcg_ctx->cpu_regs;
|
||||||
struct hook *hook = NULL;
|
|
||||||
TCGArg *save_opparam_ptr = tcg_ctx->gen_opparam_ptr;
|
TCGArg *save_opparam_ptr = tcg_ctx->gen_opparam_ptr;
|
||||||
bool cc_op_dirty = s->cc_op_dirty;
|
bool cc_op_dirty = s->cc_op_dirty;
|
||||||
bool changed_cc_op = false;
|
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;
|
s->last_cc_op = s->cc_op;
|
||||||
changed_cc_op = true;
|
changed_cc_op = true;
|
||||||
}
|
}
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) {
|
gen_uc_tracecode(tcg_ctx, 0xf1f1f1f1, UC_HOOK_CODE_IDX, env->uc, pc_start);
|
||||||
if (! HOOK_BOUND_CHECK(hook, pc_start))
|
// the callback might want to stop emulation immediately
|
||||||
continue;
|
check_exit_request(tcg_ctx);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prefixes = 0;
|
prefixes = 0;
|
||||||
|
@ -8173,7 +8167,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
|
||||||
gen_helper_unlock(tcg_ctx, cpu_env);
|
gen_helper_unlock(tcg_ctx, cpu_env);
|
||||||
|
|
||||||
// Unicorn: patch the callback for the instruction size
|
// Unicorn: patch the callback for the instruction size
|
||||||
if (hook) {
|
if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, pc_start)) {
|
||||||
// int i;
|
// int i;
|
||||||
// for(i = 0; i < 20; i++)
|
// for(i = 0; i < 20; i++)
|
||||||
// printf("=== [%u] = %x\n", i, *(save_opparam_ptr + 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 num_insns = 0;
|
||||||
int max_insns;
|
int max_insns;
|
||||||
bool block_full = false;
|
bool block_full = false;
|
||||||
struct hook *hook;
|
|
||||||
|
|
||||||
/* generate intermediate code */
|
/* generate intermediate code */
|
||||||
pc_start = tb->pc;
|
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
|
// Unicorn: trace this block on request
|
||||||
// Only hook this block if it is not broken from previous translation due to
|
// Only hook this block if it is not broken from previous translation due to
|
||||||
// full translation cache
|
// full translation cache
|
||||||
if (!env->uc->block_full) {
|
if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) {
|
env->uc->block_addr = pc_start;
|
||||||
if (! HOOK_BOUND_CHECK(hook, pc_start))
|
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
|
||||||
continue;
|
|
||||||
env->uc->block_addr = pc_start;
|
|
||||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, pc_start, hook->user_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_tb_start(tcg_ctx);
|
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(bitrev, i32, i32)
|
||||||
DEF_HELPER_1(ff1, 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;
|
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
||||||
uint16_t insn;
|
uint16_t insn;
|
||||||
struct hook *hook;
|
|
||||||
|
|
||||||
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
|
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
|
||||||
tcg_gen_debug_insn_start(tcg_ctx, s->pc);
|
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
|
// Unicorn: trace this instruction on request
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) {
|
if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, s->pc)) {
|
||||||
if (! HOOK_BOUND_CHECK(hook, s->pc))
|
gen_uc_tracecode(tcg_ctx, 2, UC_HOOK_CODE_IDX, env->uc, s->pc);
|
||||||
continue;
|
|
||||||
gen_uc_tracecode(tcg_ctx, 2, hook->callback, env->uc, s->pc, hook->user_data);
|
|
||||||
// the callback might want to stop emulation immediately
|
// the callback might want to stop emulation immediately
|
||||||
check_exit_request(tcg_ctx);
|
check_exit_request(tcg_ctx);
|
||||||
}
|
}
|
||||||
|
@ -3075,7 +3072,6 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
|
||||||
int max_insns;
|
int max_insns;
|
||||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||||
bool block_full = false;
|
bool block_full = false;
|
||||||
struct hook *hook;
|
|
||||||
|
|
||||||
/* generate intermediate code */
|
/* generate intermediate code */
|
||||||
pc_start = tb->pc;
|
pc_start = tb->pc;
|
||||||
|
@ -3110,14 +3106,10 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
|
||||||
// Unicorn: trace this block on request
|
// Unicorn: trace this block on request
|
||||||
// Only hook this block if it is not broken from previous translation due to
|
// Only hook this block if it is not broken from previous translation due to
|
||||||
// full translation cache
|
// full translation cache
|
||||||
if (!env->uc->block_full) {
|
if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) {
|
// save block address to see if we need to patch block size later
|
||||||
if (! HOOK_BOUND_CHECK(hook, pc_start))
|
env->uc->block_addr = pc_start;
|
||||||
continue;
|
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, 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, hook->callback, env->uc, pc_start, hook->user_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_tb_start(tcg_ctx);
|
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_3(raise_exception_err, noreturn, env, i32, int)
|
||||||
DEF_HELPER_2(raise_exception, noreturn, env, i32)
|
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 op, cnvt_op, op1, offset;
|
||||||
int funct;
|
int funct;
|
||||||
int n_bytes;
|
int n_bytes;
|
||||||
struct hook *hook;
|
|
||||||
|
|
||||||
op = (ctx->opcode >> 11) & 0x1f;
|
op = (ctx->opcode >> 11) & 0x1f;
|
||||||
sa = (ctx->opcode >> 2) & 0x7;
|
sa = (ctx->opcode >> 2) & 0x7;
|
||||||
|
@ -11344,10 +11343,8 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, bool *insn_n
|
||||||
n_bytes = 2;
|
n_bytes = 2;
|
||||||
|
|
||||||
// Unicorn: trace this instruction on request
|
// Unicorn: trace this instruction on request
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) {
|
if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, ctx->pc)) {
|
||||||
if (! HOOK_BOUND_CHECK(hook, ctx->pc))
|
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_CODE_IDX, env->uc, ctx->pc);
|
||||||
continue;
|
|
||||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, ctx->pc, hook->user_data);
|
|
||||||
*insn_need_patch = true;
|
*insn_need_patch = true;
|
||||||
// the callback might want to stop emulation immediately
|
// the callback might want to stop emulation immediately
|
||||||
check_exit_request(tcg_ctx);
|
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;
|
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||||
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
|
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
|
||||||
uint32_t op;
|
uint32_t op;
|
||||||
struct hook *hook;
|
|
||||||
|
|
||||||
/* make sure instructions are on a halfword boundary */
|
/* make sure instructions are on a halfword boundary */
|
||||||
if (ctx->pc & 0x1) {
|
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
|
// Unicorn: trace this instruction on request
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) {
|
if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, ctx->pc)) {
|
||||||
if (! HOOK_BOUND_CHECK(hook, ctx->pc))
|
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_CODE_IDX, env->uc, ctx->pc);
|
||||||
continue;
|
|
||||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, ctx->pc, hook->user_data);
|
|
||||||
*insn_need_patch = true;
|
*insn_need_patch = true;
|
||||||
// the callback might want to stop emulation immediately
|
// the callback might want to stop emulation immediately
|
||||||
check_exit_request(tcg_ctx);
|
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)
|
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;
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
struct hook *hook;
|
if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, ctx->pc)) {
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) {
|
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_CODE_IDX, env->uc, ctx->pc);
|
||||||
if (! HOOK_BOUND_CHECK(hook, ctx->pc))
|
|
||||||
continue;
|
|
||||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, ctx->pc, hook->user_data);
|
|
||||||
*insn_need_patch = true;
|
*insn_need_patch = true;
|
||||||
// the callback might want to stop emulation immediately
|
// the callback might want to stop emulation immediately
|
||||||
check_exit_request(tcg_ctx);
|
check_exit_request(tcg_ctx);
|
||||||
|
@ -19178,7 +19169,6 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
||||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||||
TCGArg *save_opparam_ptr = NULL;
|
TCGArg *save_opparam_ptr = NULL;
|
||||||
bool block_full = false;
|
bool block_full = false;
|
||||||
struct hook *hook;
|
|
||||||
|
|
||||||
if (search_pc)
|
if (search_pc)
|
||||||
qemu_log("search pc %d\n", 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
|
// Unicorn: trace this block on request
|
||||||
// Only hook this block if it is not broken from previous translation due to
|
// Only hook this block if it is not broken from previous translation due to
|
||||||
// full translation cache
|
// full translation cache
|
||||||
if (! env->uc->block_full) {
|
if (! env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) {
|
// save block address to see if we need to patch block size later
|
||||||
if (! HOOK_BOUND_CHECK(hook, pc_start))
|
env->uc->block_addr = pc_start;
|
||||||
continue;
|
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, 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, hook->callback, env->uc, pc_start, hook->user_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_tb_start(tcg_ctx);
|
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)
|
DEF_HELPER_1(power_down, void, env)
|
||||||
|
|
||||||
#ifndef TARGET_SPARC64
|
#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_i32 cpu_src1_32, cpu_src2_32, cpu_dst_32;
|
||||||
TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64;
|
TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64;
|
||||||
target_long simm;
|
target_long simm;
|
||||||
struct hook *hook;
|
|
||||||
|
|
||||||
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
|
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
|
||||||
tcg_gen_debug_insn_start(tcg_ctx, dc->pc);
|
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
|
// Unicorn: trace this instruction on request
|
||||||
if (hook_insn) {
|
if (hook_insn && HOOK_EXISTS_BOUNDED(dc->uc, UC_HOOK_CODE, dc->pc)) {
|
||||||
HOOK_FOREACH(dc->uc, hook, UC_HOOK_CODE) {
|
gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, dc->uc, dc->pc);
|
||||||
if (! HOOK_BOUND_CHECK(hook, dc->pc))
|
// the callback might want to stop emulation immediately
|
||||||
continue;
|
check_exit_request(tcg_ctx);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
opc = GET_FIELD(insn, 0, 1);
|
opc = GET_FIELD(insn, 0, 1);
|
||||||
|
@ -5390,7 +5385,6 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
|
||||||
unsigned int insn;
|
unsigned int insn;
|
||||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||||
bool block_full = false;
|
bool block_full = false;
|
||||||
struct hook *hook;
|
|
||||||
|
|
||||||
memset(dc, 0, sizeof(DisasContext));
|
memset(dc, 0, sizeof(DisasContext));
|
||||||
dc->uc = env->uc;
|
dc->uc = env->uc;
|
||||||
|
@ -5431,14 +5425,10 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
|
||||||
// Unicorn: trace this block on request
|
// Unicorn: trace this block on request
|
||||||
// Only hook this block if it is not broken from previous translation due to
|
// Only hook this block if it is not broken from previous translation due to
|
||||||
// full translation cache
|
// full translation cache
|
||||||
if (!env->uc->block_full) {
|
if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) {
|
// save block address to see if we need to patch block size later
|
||||||
if (! HOOK_BOUND_CHECK(hook, pc_start))
|
env->uc->block_addr = pc_start;
|
||||||
continue;
|
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, 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, hook->callback, env->uc, pc_start, hook->user_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_tb_start(tcg_ctx);
|
gen_tb_start(tcg_ctx);
|
||||||
|
|
|
@ -27,14 +27,13 @@
|
||||||
|
|
||||||
int gen_new_label(TCGContext *);
|
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_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_ptr tuc = tcg_const_ptr(tcg_ctx, uc);
|
||||||
TCGv_i64 tpc = tcg_const_i64(tcg_ctx, pc);
|
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, ttype, tuc, tpc);
|
||||||
gen_helper_uc_tracecode(tcg_ctx, tsize, tcallback, tuc, tpc, tdata);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void tcg_gen_op0(TCGContext *s, TCGOpcode opc)
|
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);
|
gen_intermediate_code(env, tb);
|
||||||
|
|
||||||
// Unicorn: when tracing block, patch 1st operand for block size
|
// 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
|
if (env->uc->block_full) // block size is unknown
|
||||||
*(s->gen_opparam_buf + 1) = 0;
|
*(s->gen_opparam_buf + 1) = 0;
|
||||||
else
|
else
|
||||||
|
|
12
uc.c
12
uc.c
|
@ -1009,17 +1009,23 @@ uc_err uc_hook_del(uc_engine *uc, uc_hook hh)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TCG helper
|
// 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, uc_hook_type type, void *handle, int64_t address);
|
||||||
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)
|
||||||
{
|
{
|
||||||
struct uc_struct *uc = handle;
|
struct uc_struct *uc = handle;
|
||||||
|
struct list_item *cur = uc->hook[type].head;
|
||||||
|
struct hook *hook;
|
||||||
|
|
||||||
// sync PC in CPUArchState with address
|
// sync PC in CPUArchState with address
|
||||||
if (uc->set_pc) {
|
if (uc->set_pc) {
|
||||||
uc->set_pc(uc, address);
|
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
|
UNICORN_EXPORT
|
||||||
|
|
Loading…
Reference in a new issue