From e750a4e97c4db33aa00866eb4875098b871ce4a8 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Thu, 28 Jan 2016 00:56:55 +0800 Subject: [PATCH] when uc_mem_exec() remove EXE permission, quit current TB & continue emulating with TB flushed. this fixes issue in PR #378 --- include/uc_priv.h | 1 + qemu/cpus.c | 8 +++++++- uc.c | 11 +++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/include/uc_priv.h b/include/uc_priv.h index 44c116ea..0ef5a3dd 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -215,6 +215,7 @@ struct uc_struct { bool init_tcg; // already initialized local TCGv variables? bool stop_request; // request to immediately stop emulation - for uc_emu_stop() + bool quit_request; // request to quit the current TB, but continue to emulate - for uc_mem_protect() bool emulation_done; // emulation is done by uc_emu_start() QemuThread timer; // timer for emulation timeout uint64_t timeout; // timeout for uc_emu_start() diff --git a/qemu/cpus.c b/qemu/cpus.c index 98ee07c1..64c73b0b 100644 --- a/qemu/cpus.c +++ b/qemu/cpus.c @@ -231,8 +231,14 @@ static bool tcg_exec_all(struct uc_struct* uc) //qemu_clock_enable(QEMU_CLOCK_VIRTUAL, // (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0); if (cpu_can_run(cpu)) { + uc->quit_request = false; r = tcg_cpu_exec(uc, env); - if (uc->stop_request) { + + // quit current TB but continue emulating? + if (uc->quit_request) { + // reset stop_request + uc->stop_request = false; + } else if (uc->stop_request) { //printf(">>> got STOP request!!!\n"); finish = true; break; diff --git a/uc.c b/uc.c index e66b9f82..06b08fca 100644 --- a/uc.c +++ b/uc.c @@ -826,6 +826,7 @@ uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size, uint3 MemoryRegion *mr; uint64_t addr = address; size_t count, len; + bool remove_exec = false; if (size == 0) // trivial case, no change @@ -862,12 +863,22 @@ uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size, uint3 return UC_ERR_NOMEM; mr = memory_mapping(uc, addr); + // will this remove EXEC permission? + if (((mr->perms & UC_PROT_EXEC) != 0) && ((perms & UC_PROT_EXEC) == 0)) + remove_exec = true; mr->perms = perms; uc->readonly_mem(mr, (perms & UC_PROT_WRITE) == 0); count += len; addr += len; } + + // if EXEC permission is removed, then quit TB and continue at the same place + if (remove_exec) { + uc->quit_request = true; + uc_emu_stop(uc); + } + return UC_ERR_OK; }