diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 75d71514..1ef7fd53 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _aarch64 #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_aarch64 #define use_idiv_instructions use_idiv_instructions_aarch64 #define arm_arch arm_arch_aarch64 #define tb_target_set_jmp_target tb_target_set_jmp_target_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index ee750153..25c3c8a2 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _aarch64eb #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_aarch64eb #define use_idiv_instructions use_idiv_instructions_aarch64eb #define arm_arch arm_arch_aarch64eb #define tb_target_set_jmp_target tb_target_set_jmp_target_aarch64eb diff --git a/qemu/accel/tcg/translate-all.h b/qemu/accel/tcg/translate-all.h index 71be1d41..30ce55d1 100644 --- a/qemu/accel/tcg/translate-all.h +++ b/qemu/accel/tcg/translate-all.h @@ -30,6 +30,7 @@ void tb_invalidate_phys_page_fast(struct uc_struct *uc, struct page_collection * tb_page_addr_t start, int len, uintptr_t retaddr); void tb_invalidate_phys_page_range(struct uc_struct *uc, tb_page_addr_t start, tb_page_addr_t end); +void tb_invalidate_phys_range(struct uc_struct *uc, ram_addr_t start, ram_addr_t end); void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr); #endif /* TRANSLATE_ALL_H */ diff --git a/qemu/arm.h b/qemu/arm.h index d3cc372d..545a9ca6 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _arm #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_arm #define use_idiv_instructions use_idiv_instructions_arm #define arm_arch arm_arch_arm #define tb_target_set_jmp_target tb_target_set_jmp_target_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 0a51a80d..988dab96 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _armeb #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_armeb #define use_idiv_instructions use_idiv_instructions_armeb #define arm_arch arm_arch_armeb #define tb_target_set_jmp_target tb_target_set_jmp_target_armeb diff --git a/qemu/m68k.h b/qemu/m68k.h index cb3d430b..81472490 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _m68k #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_m68k #define use_idiv_instructions use_idiv_instructions_m68k #define arm_arch arm_arch_m68k #define tb_target_set_jmp_target tb_target_set_jmp_target_m68k diff --git a/qemu/mips.h b/qemu/mips.h index a2b78379..cd1cccb4 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _mips #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_mips #define use_idiv_instructions use_idiv_instructions_mips #define arm_arch arm_arch_mips #define tb_target_set_jmp_target tb_target_set_jmp_target_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 9faef36b..e56c5f1f 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _mips64 #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_mips64 #define use_idiv_instructions use_idiv_instructions_mips64 #define arm_arch arm_arch_mips64 #define tb_target_set_jmp_target tb_target_set_jmp_target_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 6f748b36..8e3bdbfe 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _mips64el #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_mips64el #define use_idiv_instructions use_idiv_instructions_mips64el #define arm_arch arm_arch_mips64el #define tb_target_set_jmp_target tb_target_set_jmp_target_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index a4831183..1c1660f3 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _mipsel #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_mipsel #define use_idiv_instructions use_idiv_instructions_mipsel #define arm_arch arm_arch_mipsel #define tb_target_set_jmp_target tb_target_set_jmp_target_mipsel diff --git a/qemu/ppc.h b/qemu/ppc.h index 8cb9ea3e..87a216a3 100644 --- a/qemu/ppc.h +++ b/qemu/ppc.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _ppc #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_ppc #define use_idiv_instructions use_idiv_instructions_ppc #define arm_arch arm_arch_ppc #define tb_target_set_jmp_target tb_target_set_jmp_target_ppc diff --git a/qemu/ppc64.h b/qemu/ppc64.h index 1d055072..d4f27146 100644 --- a/qemu/ppc64.h +++ b/qemu/ppc64.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _ppc64 #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_ppc64 #define use_idiv_instructions use_idiv_instructions_ppc64 #define arm_arch arm_arch_ppc64 #define tb_target_set_jmp_target tb_target_set_jmp_target_ppc64 diff --git a/qemu/riscv32.h b/qemu/riscv32.h index df9eed70..57795e38 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _riscv32 #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_riscv32 #define use_idiv_instructions use_idiv_instructions_riscv32 #define arm_arch arm_arch_riscv32 #define tb_target_set_jmp_target tb_target_set_jmp_target_riscv32 diff --git a/qemu/riscv64.h b/qemu/riscv64.h index c41e7178..4b19f2c9 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _riscv64 #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_riscv64 #define use_idiv_instructions use_idiv_instructions_riscv64 #define arm_arch arm_arch_riscv64 #define tb_target_set_jmp_target tb_target_set_jmp_target_riscv64 diff --git a/qemu/softmmu/cpus.c b/qemu/softmmu/cpus.c index f983f634..173a2e1e 100644 --- a/qemu/softmmu/cpus.c +++ b/qemu/softmmu/cpus.c @@ -27,6 +27,7 @@ #include "qemu/bitmap.h" #include "tcg/tcg.h" #include "exec/tb-hash.h" +#include "accel/tcg/translate-all.h" #include "uc_priv.h" @@ -173,6 +174,7 @@ void cpu_stop_current(struct uc_struct *uc) void resume_all_vcpus(struct uc_struct* uc) { CPUState *cpu = uc->cpu; + tb_page_addr_t addr; cpu->halted = 0; cpu->exit_request = 0; cpu->exception_index = -1; @@ -188,12 +190,15 @@ void resume_all_vcpus(struct uc_struct* uc) // clear the cache of the addr_end address, since the generated code // at that address is to exit emulation, but not for the instruction there. // if we dont do this, next time we cannot emulate at that address - TranslationBlock *tb = cpu->tb_jmp_cache[tb_jmp_cache_hash_func(uc, uc->addr_end)]; - if (tb) { - qht_remove(&uc->tcg_ctx->tb_ctx.htable, tb, tb->hash); - tb_flush_jmp_cache(cpu, uc->addr_end); - } + // GVA to GPA (GPA -> HVA via page_find, HVA->HPA via host mmu) + addr = get_page_addr_code(uc->cpu->env_ptr, uc->addr_end); + // Unicorn: Why addr - 1? + // 0: INC ecx + // 1: DEC edx <--- We put exit here, then the range of TB is [0, 1) + // + // While tb_invalidate_phys_range invalides [start, end) + tb_invalidate_phys_range(uc, addr - 1, addr - 1 + 8); cpu->created = false; } diff --git a/qemu/sparc.h b/qemu/sparc.h index 741e7565..ecb8c6c2 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _sparc #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_sparc #define use_idiv_instructions use_idiv_instructions_sparc #define arm_arch arm_arch_sparc #define tb_target_set_jmp_target tb_target_set_jmp_target_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 5262a11b..22d1ea35 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _sparc64 #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_sparc64 #define use_idiv_instructions use_idiv_instructions_sparc64 #define arm_arch arm_arch_sparc64 #define tb_target_set_jmp_target tb_target_set_jmp_target_sparc64 diff --git a/qemu/x86_64.h b/qemu/x86_64.h index a1896af7..d0d3fba0 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -4,6 +4,7 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _x86_64 #endif +#define tb_invalidate_phys_range tb_invalidate_phys_range_x86_64 #define use_idiv_instructions use_idiv_instructions_x86_64 #define arm_arch arm_arch_x86_64 #define tb_target_set_jmp_target tb_target_set_jmp_target_x86_64 diff --git a/symbols.sh b/symbols.sh index 19997fb4..a30c0f90 100755 --- a/symbols.sh +++ b/symbols.sh @@ -4,6 +4,7 @@ CMD_PATH=$(realpath $0) SOURCE_DIR=$(dirname ${CMD_PATH}) COMMON_SYMBOLS=" +tb_invalidate_phys_range \ use_idiv_instructions \ arm_arch \ tb_target_set_jmp_target \ diff --git a/tests/unit/test_x86.c b/tests/unit/test_x86.c index abb37b19..2d73bd96 100644 --- a/tests/unit/test_x86.c +++ b/tests/unit/test_x86.c @@ -630,23 +630,23 @@ static void test_x86_hook_cpuid() } // This is a regression bug. -static void test_x86_clear_tb_cache() { +static void test_x86_clear_tb_cache() +{ uc_engine *uc; - char code[] = - "\x41\x4a"; // INC ecx; DEC edx; + char code[] = "\x83\xc1\x01\x4a"; // INC ecx; DEC edx; int r_ecx = 0x1234; int r_edx = 0x7890; uint64_t code_start = 0x1240; // Choose this address by design uint64_t code_len = 0x1000; OK(uc_open(UC_ARCH_X86, UC_MODE_32, &uc)); - OK(uc_mem_map(uc, code_start & (1<<12), code_len, UC_PROT_ALL)); + OK(uc_mem_map(uc, code_start & (1 << 12), code_len, UC_PROT_ALL)); OK(uc_mem_write(uc, code_start, code, sizeof(code))); OK(uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx)); OK(uc_reg_write(uc, UC_X86_REG_EDX, &r_edx)); - OK(uc_emu_start(uc, code_start, code_start + 1, 0, 0)); - + OK(uc_emu_start(uc, code_start, code_start + 3, 0, 0)); + // If tb cache is not cleared, edx would be still 0x7890 OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));