Undo the disaster that was the patch to unicorn github issue #266 and fix it correctly. makes normal self-modifying code work.

This commit is contained in:
Andrew Dutcher 2016-07-14 09:40:45 -07:00
parent 236b6e9085
commit 97b10da133
9 changed files with 24 additions and 8 deletions

View File

@ -240,6 +240,7 @@ struct uc_struct {
int thumb; // thumb mode for ARM int thumb; // thumb mode for ARM
// full TCG cache leads to middle-block break in the last translation? // full TCG cache leads to middle-block break in the last translation?
bool block_full; bool block_full;
int size_arg; // what tcg arg slot do we need to update with the size of the block?
MemoryRegion **mapped_blocks; MemoryRegion **mapped_blocks;
uint32_t mapped_block_count; uint32_t mapped_block_count;
uint32_t mapped_block_cache_index; uint32_t mapped_block_cache_index;

View File

@ -11115,7 +11115,10 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { 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 // save block address to see if we need to patch block size later
env->uc->block_addr = pc_start; env->uc->block_addr = pc_start;
env->uc->size_arg = tcg_ctx->gen_opparam_buf - tcg_ctx->gen_opparam_ptr + 1;
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
} else {
env->uc->size_arg = -1;
} }
gen_tb_start(tcg_ctx); gen_tb_start(tcg_ctx);

View File

@ -11233,7 +11233,10 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { 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 // save block address to see if we need to patch block size later
env->uc->block_addr = pc_start; env->uc->block_addr = pc_start;
env->uc->size_arg = tcg_ctx->gen_opparam_buf - tcg_ctx->gen_opparam_ptr + 1;
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
} else {
env->uc->size_arg = -1;
} }
gen_tb_start(tcg_ctx); gen_tb_start(tcg_ctx);

View File

@ -8388,15 +8388,17 @@ static inline void gen_intermediate_code_internal(uint8_t *gen_opc_cc_op,
dc->is_jmp = DISAS_NEXT; dc->is_jmp = DISAS_NEXT;
lj = -1; lj = -1;
max_insns = tb->cflags & CF_COUNT_MASK; max_insns = tb->cflags & CF_COUNT_MASK;
if (max_insns <= 1) if (max_insns == 0)
max_insns = CF_COUNT_MASK; max_insns = CF_COUNT_MASK;
// 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 the previous block was not truncated due to space
// full translation cache
if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
env->uc->block_addr = pc_start; env->uc->block_addr = pc_start;
env->uc->size_arg = tcg_ctx->gen_opparam_buf - tcg_ctx->gen_opparam_ptr + 1;
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
} else {
env->uc->size_arg = -1;
} }
gen_tb_start(tcg_ctx); gen_tb_start(tcg_ctx);

View File

@ -3109,7 +3109,10 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { 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 // save block address to see if we need to patch block size later
env->uc->block_addr = pc_start; env->uc->block_addr = pc_start;
env->uc->size_arg = tcg_ctx->gen_opparam_buf - tcg_ctx->gen_opparam_ptr + 1;
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
} else {
env->uc->size_arg = -1;
} }
gen_tb_start(tcg_ctx); gen_tb_start(tcg_ctx);

View File

@ -19217,7 +19217,10 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { 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 // save block address to see if we need to patch block size later
env->uc->block_addr = pc_start; env->uc->block_addr = pc_start;
env->uc->size_arg = tcg_ctx->gen_opparam_buf - tcg_ctx->gen_opparam_ptr + 1;
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
} else {
env->uc->size_arg = -1;
} }
gen_tb_start(tcg_ctx); gen_tb_start(tcg_ctx);

View File

@ -5421,6 +5421,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { 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 // save block address to see if we need to patch block size later
env->uc->block_addr = pc_start; env->uc->block_addr = pc_start;
env->uc->size_arg = tcg_ctx->gen_opparam_buf - tcg_ctx->gen_opparam_ptr + 1;
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
} }

View File

@ -179,12 +179,12 @@ 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 block size operand for callback
if (env->uc->block_addr == tb->pc && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, tb->pc)) { if (env->uc->size_arg != -1 && 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 + env->uc->size_arg) = 0;
else else
*(s->gen_opparam_buf + 1) = tb->size; *(s->gen_opparam_buf + env->uc->size_arg) = tb->size;
} }
/* generate machine code */ /* generate machine code */

View File

@ -1,7 +1,7 @@
#include <unicorn/unicorn.h> #include <unicorn/unicorn.h>
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) {
printf("hook_block(…)\n"); printf("hook_block(%p, %lx, %d, %p)\n", uc, address, size, user_data);
} }
/* /*