@@ -2988,11 +2988,35 @@ static void translate(DisasContext *ctx)
2988
2988
return ;
2989
2989
}
2990
2990
2991
+ // Unicorn: trace this instruction on request
2992
+ bool insn_hook = false;
2993
+ TCGOp * insn_prev_op = NULL ;
2994
+ if (HOOK_EXISTS_BOUNDED (uc , UC_HOOK_CODE , insn_pc * 2 )) {
2995
+
2996
+ // sync PC in advance
2997
+ tcg_gen_movi_tl (cpu_pc , insn_pc );
2998
+
2999
+ // save the last operand
3000
+ insn_prev_op = tcg_last_op (tcg_ctx );
3001
+ insn_hook = true;
3002
+ gen_uc_tracecode (tcg_ctx , 0xf1 , UC_HOOK_CODE_IDX , uc , insn_pc * 2 );
3003
+
3004
+ // the callback might want to stop emulation immediately
3005
+ check_exit_request (tcg_ctx );
3006
+ }
3007
+
2991
3008
uint32_t opcode = next_word (ctx );
2992
3009
if (!decode_insn (ctx , opcode )) {
2993
3010
gen_helper_unsupported (cpu_env );
2994
3011
ctx -> bstate = DISAS_NORETURN ;
2995
3012
}
3013
+
3014
+ if (insn_hook ) {
3015
+ // Unicorn: patch the callback to have the proper instruction size.
3016
+ TCGOp * const tcg_op = insn_prev_op ?
3017
+ QTAILQ_NEXT (insn_prev_op , link ) : QTAILQ_FIRST (& tcg_ctx -> ops );
3018
+ tcg_op -> args [1 ] = (ctx -> npc - insn_pc )* 2 ;
3019
+ }
2996
3020
}
2997
3021
2998
3022
/* Standardize the cpu_skip condition to NE. */
@@ -3056,7 +3080,9 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
3056
3080
target_ulong pc_start = tb -> pc / 2 ;
3057
3081
int num_insns = 0 ;
3058
3082
3083
+ INIT_UC_CONTEXT_FROM_DISAS (& ctx );
3059
3084
INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS (& ctx );
3085
+
3060
3086
if (tb -> flags & TB_FLAGS_FULL_ACCESS ) {
3061
3087
/*
3062
3088
* This flag is set by ST/LD instruction we will regenerate it ONLY
@@ -3068,6 +3094,17 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
3068
3094
max_insns = 1 ;
3069
3095
}
3070
3096
3097
+ // Unicorn: trace this block on request
3098
+ bool block_hook = false;
3099
+ TCGOp * block_prev_op = NULL ;
3100
+ if (HOOK_EXISTS_BOUNDED (uc , UC_HOOK_BLOCK , tb -> pc )) {
3101
+
3102
+ // save the last operand
3103
+ block_prev_op = tcg_last_op (tcg_ctx );
3104
+ block_hook = true;
3105
+ gen_uc_tracecode (tcg_ctx , 0xf8 , UC_HOOK_BLOCK_IDX , uc , tb -> pc );
3106
+ }
3107
+
3071
3108
gen_tb_start (tb );
3072
3109
3073
3110
ctx .npc = pc_start ;
@@ -3188,6 +3225,15 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
3188
3225
tb -> size = (ctx .npc - pc_start ) * 2 ;
3189
3226
tb -> icount = num_insns ;
3190
3227
3228
+ hooked_regions_check (uc , tb -> pc , tb -> size );
3229
+
3230
+ if (block_hook ) {
3231
+ // Unicorn: patch the callback to have the proper block size.
3232
+ TCGOp * const tcg_op = block_prev_op ?
3233
+ QTAILQ_NEXT (block_prev_op , link ) : QTAILQ_FIRST (& tcg_ctx -> ops );
3234
+ tcg_op -> args [1 ] = (ctx .npc - pc_start )* 2 ;
3235
+ }
3236
+
3191
3237
#ifdef DEBUG_DISAS
3192
3238
#if 0
3193
3239
if (qemu_loglevel_mask (CPU_LOG_TB_IN_ASM )
0 commit comments