From db8f499fe94107a30e352cd2f3655ac36c440135 Mon Sep 17 00:00:00 2001 From: Ryan Hileman Date: Tue, 1 Sep 2015 18:58:02 -0700 Subject: [PATCH 1/8] fix crash on some SSE instructions --- qemu/target-i386/translate.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c index a3b09fd5..137d9159 100644 --- a/qemu/target-i386/translate.c +++ b/qemu/target-i386/translate.c @@ -2944,8 +2944,8 @@ typedef void (*SSEFunc_0_epl)(TCGContext *s, TCGv_ptr env, TCGv_ptr reg, TCGv_i6 typedef void (*SSEFunc_0_epp)(TCGContext *s, TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b); typedef void (*SSEFunc_0_eppi)(TCGContext *s, TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val); -typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val); -typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, +typedef void (*SSEFunc_0_ppi)(TCGContext *s, TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val); +typedef void (*SSEFunc_0_eppt)(TCGContext *s, TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv val); #define SSE_SPECIAL ((void *)1) @@ -4669,7 +4669,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, tcg_gen_addi_ptr(tcg_ctx, cpu_ptr1, cpu_env, op2_offset); /* XXX: introduce a new table? */ sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp; - sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(tcg_ctx, val)); + sse_fn_ppi(tcg_ctx, cpu_ptr0, cpu_ptr1, tcg_const_i32(tcg_ctx, val)); break; case 0xc2: /* compare insns */ @@ -4694,7 +4694,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, tcg_gen_addi_ptr(tcg_ctx, cpu_ptr1, cpu_env, op2_offset); /* XXX: introduce a new table? */ sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp; - sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0); + sse_fn_eppt(tcg_ctx, cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0); break; default: tcg_gen_addi_ptr(tcg_ctx, cpu_ptr0, cpu_env, op1_offset); From 5f7a912f5db975b8e6600874ed348fc8a5fdefa8 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Wed, 2 Sep 2015 10:44:26 +0800 Subject: [PATCH 2/8] better instructions for install Msys2 on Windows --- COMPILE.TXT | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/COMPILE.TXT b/COMPILE.TXT index 5887f094..fa2b1d7c 100644 --- a/COMPILE.TXT +++ b/COMPILE.TXT @@ -178,8 +178,16 @@ Unicorn requires few dependent packages as followings [7] Compile on Windows with MinGW (MSYS2) To compile with MinGW you need to install MSYS2: https://msys2.github.io/ - Follow the install instructions and don't forget to update the system packages as written in 5 & 6 paragraphs + Follow the install instructions and don't forget to update the system packages with: + + $ pacman --needed -Sy bash pacman pacman-mirrors msys2-runtime + + Then close MSYS2, run it again from Start menu and update the rest with: + + $ pacman -Su + Finally, compile Unicorn with the next steps: + - To compile Windows 32-bit binary with MinGW, run: $ pacman -S make $ pacman -S pkg-config From a94e31165d56573e77163aa81d39426f0d464432 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Wed, 2 Sep 2015 12:00:43 +0800 Subject: [PATCH 3/8] x86: fix issue #95 --- qemu/target-i386/translate.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c index 137d9159..07c877f1 100644 --- a/qemu/target-i386/translate.c +++ b/qemu/target-i386/translate.c @@ -8175,9 +8175,15 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, // printf("\n"); if (changed_cc_op) { if (cc_op_dirty) +#if TCG_TARGET_REG_BITS == 32 + *(save_opparam_ptr + 16) = s->pc - pc_start; + else + *(save_opparam_ptr + 14) = s->pc - pc_start; +#else *(save_opparam_ptr + 12) = s->pc - pc_start; else *(save_opparam_ptr + 10) = s->pc - pc_start; +#endif } else { *(save_opparam_ptr + 1) = s->pc - pc_start; } From 8b39ec5b0c4d291a7d01df92a64778355bca8cef Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Wed, 2 Sep 2015 16:13:12 +0800 Subject: [PATCH 4/8] initial support to remove a static variable in qemu-thread-win32.c --- include/uc_priv.h | 2 ++ qemu/cpus.c | 4 ++-- qemu/include/qemu/thread.h | 7 ++++--- qemu/util/qemu-thread-posix.c | 6 +++--- qemu/util/qemu-thread-win32.c | 14 ++++++-------- uc.c | 2 +- 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/include/uc_priv.h b/include/uc_priv.h index 007fecea..7a51767b 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -172,6 +172,8 @@ struct uc_struct { bool block_full; MemoryRegion **mapped_blocks; uint32_t mapped_block_count; + + void *qemu_thread_data; // to support cross compile to Windows (qemu-thread-win32.c) }; #include "qemu_macro.h" diff --git a/qemu/cpus.c b/qemu/cpus.c index ecc66e83..e274fe5a 100644 --- a/qemu/cpus.c +++ b/qemu/cpus.c @@ -124,7 +124,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) struct uc_struct *uc = cpu->uc; //qemu_tcg_init_cpu_signals(); - qemu_thread_get_self(cpu->thread); + qemu_thread_get_self(uc, cpu->thread); qemu_mutex_lock(&uc->qemu_global_mutex); CPU_FOREACH(cpu) { @@ -185,7 +185,7 @@ static void qemu_tcg_init_vcpu(CPUState *cpu) uc->tcg_halt_cond = cpu->halt_cond; snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG", cpu->cpu_index); - qemu_thread_create(cpu->thread, thread_name, qemu_tcg_cpu_thread_fn, + qemu_thread_create(uc, cpu->thread, thread_name, qemu_tcg_cpu_thread_fn, cpu, QEMU_THREAD_JOINABLE); #ifdef _WIN32 cpu->hThread = qemu_thread_get_handle(cpu->thread); diff --git a/qemu/include/qemu/thread.h b/qemu/include/qemu/thread.h index ef2f6962..de5956b2 100644 --- a/qemu/include/qemu/thread.h +++ b/qemu/include/qemu/thread.h @@ -52,12 +52,13 @@ void qemu_event_reset(QemuEvent *ev); void qemu_event_wait(QemuEvent *ev); void qemu_event_destroy(QemuEvent *ev); -void qemu_thread_create(QemuThread *thread, const char *name, +struct uc_struct; +void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name, void *(*start_routine)(void *), void *arg, int mode); void *qemu_thread_join(QemuThread *thread); -void qemu_thread_get_self(QemuThread *thread); +void qemu_thread_get_self(struct uc_struct *uc, QemuThread *thread); bool qemu_thread_is_self(QemuThread *thread); -void qemu_thread_exit(void *retval); +void qemu_thread_exit(struct uc_struct *uc, void *retval); #endif diff --git a/qemu/util/qemu-thread-posix.c b/qemu/util/qemu-thread-posix.c index 1e8f8304..34632bca 100644 --- a/qemu/util/qemu-thread-posix.c +++ b/qemu/util/qemu-thread-posix.c @@ -389,7 +389,7 @@ void qemu_event_wait(QemuEvent *ev) } } -void qemu_thread_create(QemuThread *thread, const char *name, +void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name, void *(*start_routine)(void*), void *arg, int mode) { @@ -426,7 +426,7 @@ void qemu_thread_create(QemuThread *thread, const char *name, pthread_attr_destroy(&attr); } -void qemu_thread_get_self(QemuThread *thread) +void qemu_thread_get_self(struct uc_struct *uc, QemuThread *thread) { thread->thread = pthread_self(); } @@ -436,7 +436,7 @@ bool qemu_thread_is_self(QemuThread *thread) return pthread_equal(pthread_self(), thread->thread); } -void qemu_thread_exit(void *retval) +void qemu_thread_exit(struct uc_struct *uc, void *retval) { pthread_exit(retval); } diff --git a/qemu/util/qemu-thread-win32.c b/qemu/util/qemu-thread-win32.c index 004f17bf..51ca88f8 100644 --- a/qemu/util/qemu-thread-win32.c +++ b/qemu/util/qemu-thread-win32.c @@ -266,8 +266,6 @@ struct QemuThreadData { CRITICAL_SECTION cs; }; -static __thread QemuThreadData *qemu_thread_data; - static unsigned __stdcall win32_start_routine(void *arg) { QemuThreadData *data = (QemuThreadData *) arg; @@ -278,14 +276,13 @@ static unsigned __stdcall win32_start_routine(void *arg) g_free(data); data = NULL; } - qemu_thread_data = data; qemu_thread_exit(start_routine(thread_arg)); abort(); } -void qemu_thread_exit(void *arg) +void qemu_thread_exit(struct uc_struct *uc, void *arg) { - QemuThreadData *data = qemu_thread_data; + QemuThreadData *data = uc->qemu_thread_data; if (data) { assert(data->mode != QEMU_THREAD_DETACHED); @@ -326,7 +323,7 @@ void *qemu_thread_join(QemuThread *thread) return ret; } -void qemu_thread_create(QemuThread *thread, const char *name, +void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name, void *(*start_routine)(void *), void *arg, int mode) { @@ -338,6 +335,7 @@ void qemu_thread_create(QemuThread *thread, const char *name, data->arg = arg; data->mode = mode; data->exited = false; + uc->qemu_thread_data = data; if (data->mode != QEMU_THREAD_DETACHED) { InitializeCriticalSection(&data->cs); @@ -352,9 +350,9 @@ void qemu_thread_create(QemuThread *thread, const char *name, thread->data = (mode == QEMU_THREAD_DETACHED) ? NULL : data; } -void qemu_thread_get_self(QemuThread *thread) +void qemu_thread_get_self(struct uc_struct *uc, QemuThread *thread) { - thread->data = qemu_thread_data; + thread->data = uc->qemu_thread_data; thread->tid = GetCurrentThreadId(); } diff --git a/uc.c b/uc.c index 6d93d0e7..d1584b4f 100644 --- a/uc.c +++ b/uc.c @@ -465,7 +465,7 @@ static void enable_emu_timer(uch handle, uint64_t timeout) struct uc_struct *uc = (struct uc_struct *)handle; uc->timeout = timeout; - qemu_thread_create(&uc->timer, "timeout", _timeout_fn, + qemu_thread_create(uc, &uc->timer, "timeout", _timeout_fn, uc, QEMU_THREAD_JOINABLE); } From 2d9db36a2b79afe995c39d07de4db5378deb0e7b Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Wed, 2 Sep 2015 01:34:23 -0700 Subject: [PATCH 5/8] fix some errors introduced by the last commit on qemu-thread-win32.c --- qemu/util/qemu-thread-win32.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qemu/util/qemu-thread-win32.c b/qemu/util/qemu-thread-win32.c index 51ca88f8..3f7f7015 100644 --- a/qemu/util/qemu-thread-win32.c +++ b/qemu/util/qemu-thread-win32.c @@ -16,6 +16,8 @@ #include #include +#include "uc_priv.h" + static void error_exit(int err, const char *msg) { @@ -264,6 +266,7 @@ struct QemuThreadData { bool exited; void *ret; CRITICAL_SECTION cs; + struct uc_struct *uc; }; static unsigned __stdcall win32_start_routine(void *arg) @@ -276,7 +279,7 @@ static unsigned __stdcall win32_start_routine(void *arg) g_free(data); data = NULL; } - qemu_thread_exit(start_routine(thread_arg)); + qemu_thread_exit(data->uc, start_routine(thread_arg)); abort(); } @@ -335,6 +338,8 @@ void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *na data->arg = arg; data->mode = mode; data->exited = false; + data->uc = uc; + uc->qemu_thread_data = data; if (data->mode != QEMU_THREAD_DETACHED) { From 4a2f23db60c786a846f4797290455a35eb334e3b Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Thu, 3 Sep 2015 01:10:35 +0800 Subject: [PATCH 6/8] regress: fix rep_movsb.c to properly use uc_hook_add() API --- regress/rep_movsb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/regress/rep_movsb.c b/regress/rep_movsb.c index ab49175b..c9fb6f15 100644 --- a/regress/rep_movsb.c +++ b/regress/rep_movsb.c @@ -128,7 +128,7 @@ int main(int argc, char **argv, char **envp) printf("ok %d - Program written to memory\n", log_num++); } - if (uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK) { + if (uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) { printf("not ok %d - Failed to install UC_HOOK_CODE handler\n", log_num++); return 5; } @@ -137,7 +137,7 @@ int main(int argc, char **argv, char **envp) } // intercept memory write events only, NOT read events - if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL) != UC_ERR_OK) { + if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) { printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE handler\n", log_num++); return 6; } From be659d201d0fdcd9509241763af2b56abbd0afd2 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Thu, 3 Sep 2015 01:12:49 +0800 Subject: [PATCH 7/8] fix confusion betweet UC_MEM_xxx & UC_HOOK_MEM_xxx. fix issue #93 --- hook.c | 21 +++++++++++---------- qemu/softmmu_template.h | 8 ++++---- uc.c | 7 ++++--- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/hook.c b/hook.c index 6a26d70d..f4690506 100644 --- a/hook.c +++ b/hook.c @@ -67,17 +67,17 @@ size_t hook_add(uch handle, int type, uint64_t begin, uint64_t end, void *callba if (begin > end) uc->hook_insn_idx = i; break; - case UC_MEM_READ: + case UC_HOOK_MEM_READ: uc->hook_mem_read = true; if (begin > end) uc->hook_read_idx = i; break; - case UC_MEM_WRITE: + case UC_HOOK_MEM_WRITE: uc->hook_mem_write = true; if (begin > end) uc->hook_write_idx = i; break; - case UC_MEM_READ_WRITE: + case UC_HOOK_MEM_READ_WRITE: uc->hook_mem_read = true; uc->hook_mem_write = true; if (begin > end) { @@ -162,12 +162,13 @@ static struct hook_struct *_hook_find(struct uc_struct *uc, int type, uint64_t a if (uc->hook_insn_idx) return &uc->hook_callbacks[uc->hook_insn_idx]; break; - case UC_MEM_READ: + case UC_HOOK_MEM_READ: // already hooked all memory read? - if (uc->hook_read_idx) + if (uc->hook_read_idx) { return &uc->hook_callbacks[uc->hook_read_idx]; + } break; - case UC_MEM_WRITE: + case UC_HOOK_MEM_WRITE: // already hooked all memory write? if (uc->hook_write_idx) return &uc->hook_callbacks[uc->hook_write_idx]; @@ -185,14 +186,14 @@ static struct hook_struct *_hook_find(struct uc_struct *uc, int type, uint64_t a return &uc->hook_callbacks[i]; } break; - case UC_MEM_READ: - if (uc->hook_callbacks[i].hook_type == UC_MEM_READ || uc->hook_callbacks[i].hook_type == UC_MEM_READ_WRITE) { + case UC_HOOK_MEM_READ: + if (uc->hook_callbacks[i].hook_type == UC_HOOK_MEM_READ || uc->hook_callbacks[i].hook_type == UC_HOOK_MEM_READ_WRITE) { if (uc->hook_callbacks[i].begin <= address && address <= uc->hook_callbacks[i].end) return &uc->hook_callbacks[i]; } break; - case UC_MEM_WRITE: - if (uc->hook_callbacks[i].hook_type == UC_MEM_WRITE || uc->hook_callbacks[i].hook_type == UC_MEM_READ_WRITE) { + case UC_HOOK_MEM_WRITE: + if (uc->hook_callbacks[i].hook_type == UC_HOOK_MEM_WRITE || uc->hook_callbacks[i].hook_type == UC_HOOK_MEM_READ_WRITE) { if (uc->hook_callbacks[i].begin <= address && address <= uc->hook_callbacks[i].end) return &uc->hook_callbacks[i]; } diff --git a/qemu/softmmu_template.h b/qemu/softmmu_template.h index 56f657a4..3def3e76 100644 --- a/qemu/softmmu_template.h +++ b/qemu/softmmu_template.h @@ -183,7 +183,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, // Unicorn: callback on memory read if (env->uc->hook_mem_read && READ_ACCESS_TYPE == MMU_DATA_LOAD) { - struct hook_struct *trace = hook_find((uch)env->uc, UC_MEM_READ, addr); + struct hook_struct *trace = hook_find((uch)env->uc, UC_HOOK_MEM_READ, addr); if (trace) { ((uc_cb_hookmem_t)trace->callback)((uch)env->uc, UC_MEM_READ, (uint64_t)addr, (int)DATA_SIZE, (int64_t)0, trace->user_data); @@ -328,7 +328,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, // Unicorn: callback on memory read if (env->uc->hook_mem_read && READ_ACCESS_TYPE == MMU_DATA_LOAD) { - struct hook_struct *trace = hook_find((uch)env->uc, UC_MEM_READ, addr); + struct hook_struct *trace = hook_find((uch)env->uc, UC_HOOK_MEM_READ, addr); if (trace) { ((uc_cb_hookmem_t)trace->callback)((uch)env->uc, UC_MEM_READ, (uint64_t)addr, (int)DATA_SIZE, (int64_t)0, trace->user_data); @@ -511,7 +511,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, // Unicorn: callback on memory write if (uc->hook_mem_write) { - struct hook_struct *trace = hook_find((uch)uc, UC_MEM_WRITE, addr); + struct hook_struct *trace = hook_find((uch)uc, UC_HOOK_MEM_WRITE, addr); if (trace) { ((uc_cb_hookmem_t)trace->callback)((uch)uc, UC_MEM_WRITE, (uint64_t)addr, (int)DATA_SIZE, (int64_t)val, trace->user_data); @@ -649,7 +649,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, // Unicorn: callback on memory write if (uc->hook_mem_write) { - struct hook_struct *trace = hook_find((uch)uc, UC_MEM_WRITE, addr); + struct hook_struct *trace = hook_find((uch)uc, UC_HOOK_MEM_WRITE, addr); if (trace) { ((uc_cb_hookmem_t)trace->callback)((uch)uc, UC_MEM_WRITE, (uint64_t)addr, (int)DATA_SIZE, (int64_t)val, trace->user_data); diff --git a/uc.c b/uc.c index d1584b4f..c42123e0 100644 --- a/uc.c +++ b/uc.c @@ -791,16 +791,17 @@ uc_err uc_hook_add(uch handle, uch *h2, uc_hook_t type, void *callback, void *us case UC_HOOK_MEM_READ: begin = va_arg(valist, uint64_t); end = va_arg(valist, uint64_t); - ret = _hook_mem_access(handle, UC_MEM_READ, begin, end, callback, user_data, h2); + ret = _hook_mem_access(handle, UC_HOOK_MEM_READ, begin, end, callback, user_data, h2); break; case UC_HOOK_MEM_WRITE: begin = va_arg(valist, uint64_t); end = va_arg(valist, uint64_t); - ret = _hook_mem_access(handle, UC_MEM_WRITE, begin, end, callback, user_data, h2); + ret = _hook_mem_access(handle, UC_HOOK_MEM_WRITE, begin, end, callback, user_data, h2); + break; case UC_HOOK_MEM_READ_WRITE: begin = va_arg(valist, uint64_t); end = va_arg(valist, uint64_t); - ret = _hook_mem_access(handle, UC_MEM_READ_WRITE, begin, end, callback, user_data, h2); + ret = _hook_mem_access(handle, UC_HOOK_MEM_READ_WRITE, begin, end, callback, user_data, h2); break; } From 03683a7960314ea26f878519aa0a667b996fc3ec Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Thu, 3 Sep 2015 01:18:41 +0800 Subject: [PATCH 8/8] fix an warning caused by _hook_mem_access() --- uc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uc.c b/uc.c index c42123e0..e0e9c655 100644 --- a/uc.c +++ b/uc.c @@ -593,7 +593,7 @@ static int _hook_code(uch handle, int type, uint64_t begin, uint64_t end, } -static uc_err _hook_mem_access(uch handle, uc_mem_type type, +static uc_err _hook_mem_access(uch handle, uc_hook_t type, uint64_t begin, uint64_t end, void *callback, void *user_data, uch *h2) {