From 84abf1d3a4f70c6597612d6c325caa80a70762b2 Mon Sep 17 00:00:00 2001 From: lazymio Date: Sun, 31 Oct 2021 21:01:55 +0100 Subject: [PATCH] A stronger test and handle addr_end = 0 --- qemu/accel/tcg/translate-all.c | 3 ++- qemu/softmmu/cpus.c | 23 ++++++++++++++--------- tests/unit/test_x86.c | 6 +++++- uc.c | 6 ++++++ 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/qemu/accel/tcg/translate-all.c b/qemu/accel/tcg/translate-all.c index 79434101..d59b9604 100644 --- a/qemu/accel/tcg/translate-all.c +++ b/qemu/accel/tcg/translate-all.c @@ -1753,7 +1753,8 @@ void tb_invalidate_phys_range(struct uc_struct *uc, ram_addr_t start, ram_addr_t pages = page_collection_lock(uc, start, end); for (next = (start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; - start < end; + //start < end; Unicorn: Fix possible wrap around + (intptr_t)(end - start) > 0; start = next, next += TARGET_PAGE_SIZE) { PageDesc *pd = page_find(uc, start >> TARGET_PAGE_BITS); tb_page_addr_t bound = MIN(next, end); diff --git a/qemu/softmmu/cpus.c b/qemu/softmmu/cpus.c index 173a2e1e..12cb84e4 100644 --- a/qemu/softmmu/cpus.c +++ b/qemu/softmmu/cpus.c @@ -174,7 +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; + tb_page_addr_t start, end; cpu->halted = 0; cpu->exit_request = 0; cpu->exception_index = -1; @@ -190,15 +190,20 @@ 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 + if (uc->addr_end != 0) { + // GVA to GPA (GPA -> HVA via page_find, HVA->HPA via host mmu) + end = get_page_addr_code(uc->cpu->env_ptr, 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); + // For 32bit target. + start = (end - 1) & (target_ulong)(-1); + end = end & (target_ulong)(-1); + // Unicorn: Why start - 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, start, end); + } cpu->created = false; } diff --git a/tests/unit/test_x86.c b/tests/unit/test_x86.c index 2d73bd96..bbf35697 100644 --- a/tests/unit/test_x86.c +++ b/tests/unit/test_x86.c @@ -633,7 +633,7 @@ static void test_x86_hook_cpuid() static void test_x86_clear_tb_cache() { uc_engine *uc; - char code[] = "\x83\xc1\x01\x4a"; // INC ecx; DEC edx; + char code[] = "\x83\xc1\x01\x4a"; // ADD ecx, 1; DEC edx; int r_ecx = 0x1234; int r_edx = 0x7890; uint64_t code_start = 0x1240; // Choose this address by design @@ -645,6 +645,10 @@ static void test_x86_clear_tb_cache() OK(uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx)); OK(uc_reg_write(uc, UC_X86_REG_EDX, &r_edx)); + // This emulation should take no effect at all. + OK(uc_emu_start(uc, code_start, code_start, 0, 0)); + + // Emulate ADD ecx, 1. OK(uc_emu_start(uc, code_start, code_start + 3, 0, 0)); // If tb cache is not cleared, edx would be still 0x7890 diff --git a/uc.c b/uc.c index ec0b7d5f..67be4960 100644 --- a/uc.c +++ b/uc.c @@ -639,6 +639,12 @@ uc_err uc_emu_start(uc_engine *uc, uint64_t begin, uint64_t until, uc->timed_out = false; uc->first_tb = true; + // In this case, we don't do any emulation because it will generate + // an empty translation block which we can't invalidate. + if (begin == until) { + return UC_ERR_OK; + } + switch (uc->arch) { default: break;