diff --git a/include/uc_priv.h b/include/uc_priv.h index 5cdf6557..32616ae0 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -130,10 +130,12 @@ struct uc_struct { QemuMutex flat_view_mutex; QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners; QTAILQ_HEAD(, AddressSpace) address_spaces; + MachineState *machine_state; // qom/object.c GHashTable *type_table; Type type_interface; Object *root; + Object *owner; bool enumerating_types; // util/module.c ModuleTypeList init_type_list[MODULE_INIT_MAX]; diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 2deac84f..e368bee4 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -2414,7 +2414,6 @@ #define qemu_clock_get_us qemu_clock_get_us_aarch64 #define qemu_clock_ptr qemu_clock_ptr_aarch64 #define qemu_clocks qemu_clocks_aarch64 -#define qemu_cond_destroy qemu_cond_destroy_aarch64 #define qemu_cpu_is_self qemu_cpu_is_self_aarch64 #define qemu_cpu_kick_thread qemu_cpu_kick_thread_aarch64 #define qemu_daemon qemu_daemon_aarch64 @@ -2442,7 +2441,6 @@ #define qemu_log_flush qemu_log_flush_aarch64 #define qemu_loglevel_mask qemu_loglevel_mask_aarch64 #define qemu_log_vprintf qemu_log_vprintf_aarch64 -#define qemu_mutex_destroy qemu_mutex_destroy_aarch64 #define qemu_mutex_lock_ramlist qemu_mutex_lock_ramlist_aarch64 #define qemu_mutex_trylock qemu_mutex_trylock_aarch64 #define qemu_mutex_unlock_ramlist qemu_mutex_unlock_ramlist_aarch64 diff --git a/qemu/arm.h b/qemu/arm.h index a5ae3a38..09b8a147 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -2414,7 +2414,6 @@ #define qemu_clock_get_us qemu_clock_get_us_arm #define qemu_clock_ptr qemu_clock_ptr_arm #define qemu_clocks qemu_clocks_arm -#define qemu_cond_destroy qemu_cond_destroy_arm #define qemu_cpu_is_self qemu_cpu_is_self_arm #define qemu_cpu_kick_thread qemu_cpu_kick_thread_arm #define qemu_daemon qemu_daemon_arm @@ -2442,7 +2441,6 @@ #define qemu_log_flush qemu_log_flush_arm #define qemu_loglevel_mask qemu_loglevel_mask_arm #define qemu_log_vprintf qemu_log_vprintf_arm -#define qemu_mutex_destroy qemu_mutex_destroy_arm #define qemu_mutex_lock_ramlist qemu_mutex_lock_ramlist_arm #define qemu_mutex_trylock qemu_mutex_trylock_arm #define qemu_mutex_unlock_ramlist qemu_mutex_unlock_ramlist_arm diff --git a/qemu/cpus.c b/qemu/cpus.c index 98ee07c1..a0e9435f 100644 --- a/qemu/cpus.c +++ b/qemu/cpus.c @@ -28,6 +28,7 @@ #include "config-host.h" #include "sysemu/sysemu.h" #include "sysemu/cpus.h" +#include "qemu/thread.h" #include "exec/address-spaces.h" // debug, can be removed later @@ -76,7 +77,9 @@ void pause_all_vcpus(struct uc_struct *uc) CPUState *cpu; CPU_FOREACH(cpu) { - qemu_thread_join(cpu->thread); // qq: fix qemu_thread_join() to work for instance + qemu_thread_join(uc, cpu->thread); // qq: fix qemu_thread_join() to work for instance + free(cpu->thread); + cpu->thread = NULL; } } @@ -164,6 +167,13 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) CPU_FOREACH(cpu) { cpu->thread_id = 0; cpu->created = false; + qemu_cond_destroy(cpu->halt_cond); + free(cpu->halt_cond); +#ifdef _WIN32 + if(cpu->hThread) + CloseHandle(cpu->hThread); +#endif + cpu->halt_cond = NULL; } qemu_mutex_unlock(&uc->qemu_global_mutex); diff --git a/qemu/header_gen.py b/qemu/header_gen.py index d889247d..0616d1de 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -2420,7 +2420,6 @@ symbols = ( 'qemu_clock_get_us', 'qemu_clock_ptr', 'qemu_clocks', - 'qemu_cond_destroy', 'qemu_cpu_is_self', 'qemu_cpu_kick_thread', 'qemu_daemon', @@ -2448,7 +2447,6 @@ symbols = ( 'qemu_log_flush', 'qemu_loglevel_mask', 'qemu_log_vprintf', - 'qemu_mutex_destroy', 'qemu_mutex_lock_ramlist', 'qemu_mutex_trylock', 'qemu_mutex_unlock_ramlist', diff --git a/qemu/include/qemu/thread.h b/qemu/include/qemu/thread.h index 2a402673..d8f477d7 100644 --- a/qemu/include/qemu/thread.h +++ b/qemu/include/qemu/thread.h @@ -57,7 +57,7 @@ struct uc_struct; int 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_join(struct uc_struct *uc, QemuThread *thread); void qemu_thread_get_self(struct uc_struct *uc, QemuThread *thread); bool qemu_thread_is_self(QemuThread *thread); void qemu_thread_exit(struct uc_struct *uc, void *retval); diff --git a/qemu/m68k.h b/qemu/m68k.h index f1a6712f..7591ff9a 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -2414,7 +2414,6 @@ #define qemu_clock_get_us qemu_clock_get_us_m68k #define qemu_clock_ptr qemu_clock_ptr_m68k #define qemu_clocks qemu_clocks_m68k -#define qemu_cond_destroy qemu_cond_destroy_m68k #define qemu_cpu_is_self qemu_cpu_is_self_m68k #define qemu_cpu_kick_thread qemu_cpu_kick_thread_m68k #define qemu_daemon qemu_daemon_m68k @@ -2442,7 +2441,6 @@ #define qemu_log_flush qemu_log_flush_m68k #define qemu_loglevel_mask qemu_loglevel_mask_m68k #define qemu_log_vprintf qemu_log_vprintf_m68k -#define qemu_mutex_destroy qemu_mutex_destroy_m68k #define qemu_mutex_lock_ramlist qemu_mutex_lock_ramlist_m68k #define qemu_mutex_trylock qemu_mutex_trylock_m68k #define qemu_mutex_unlock_ramlist qemu_mutex_unlock_ramlist_m68k diff --git a/qemu/main-loop.c b/qemu/main-loop.c index bb7c3d02..9d7d6290 100644 --- a/qemu/main-loop.c +++ b/qemu/main-loop.c @@ -90,6 +90,9 @@ static void qemu_cpu_kick_thread(CPUState *cpu) GetLastError()); exit(1); } + + CloseHandle(cpu->hThread); + cpu->hThread = 0; } #endif } diff --git a/qemu/memory.c b/qemu/memory.c index 26683230..c7b709ee 100644 --- a/qemu/memory.c +++ b/qemu/memory.c @@ -70,6 +70,7 @@ void memory_unmap(struct uc_struct *uc, MemoryRegion *mr) { int i; target_ulong addr; + Object *obj; // Make sure all pages associated with the MemoryRegion are flushed // Only need to do this if we are in a running state @@ -87,8 +88,12 @@ void memory_unmap(struct uc_struct *uc, MemoryRegion *mr) //shift remainder of array down over deleted pointer memcpy(&uc->mapped_blocks[i], &uc->mapped_blocks[i + 1], sizeof(MemoryRegion*) * (uc->mapped_block_count - i)); mr->destructor(mr); - g_free((char *)mr->name); + obj = OBJECT(mr); + obj->ref = 1; + obj->free = g_free; g_free(mr->ioeventfds); + g_free((char *)mr->name); + mr->name = NULL; break; } } @@ -97,6 +102,7 @@ void memory_unmap(struct uc_struct *uc, MemoryRegion *mr) int memory_free(struct uc_struct *uc) { MemoryRegion *mr; + Object *obj; int i; get_system_memory(uc)->enabled = false; @@ -105,9 +111,10 @@ int memory_free(struct uc_struct *uc) mr->enabled = false; memory_region_del_subregion(get_system_memory(uc), mr); mr->destructor(mr); - g_free((char *)mr->name); + obj = OBJECT(mr); + obj->ref = 1; + obj->free = g_free; g_free(mr->ioeventfds); - g_free(mr); } return 0; @@ -948,6 +955,7 @@ void memory_region_init(struct uc_struct *uc, MemoryRegion *mr, { if (!owner) { owner = qdev_get_machine(uc); + uc->owner = owner; } object_initialize(uc, mr, sizeof(*mr), TYPE_MEMORY_REGION); diff --git a/qemu/mips.h b/qemu/mips.h index ed7e86d1..d50d7fe1 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -2414,7 +2414,6 @@ #define qemu_clock_get_us qemu_clock_get_us_mips #define qemu_clock_ptr qemu_clock_ptr_mips #define qemu_clocks qemu_clocks_mips -#define qemu_cond_destroy qemu_cond_destroy_mips #define qemu_cpu_is_self qemu_cpu_is_self_mips #define qemu_cpu_kick_thread qemu_cpu_kick_thread_mips #define qemu_daemon qemu_daemon_mips @@ -2442,7 +2441,6 @@ #define qemu_log_flush qemu_log_flush_mips #define qemu_loglevel_mask qemu_loglevel_mask_mips #define qemu_log_vprintf qemu_log_vprintf_mips -#define qemu_mutex_destroy qemu_mutex_destroy_mips #define qemu_mutex_lock_ramlist qemu_mutex_lock_ramlist_mips #define qemu_mutex_trylock qemu_mutex_trylock_mips #define qemu_mutex_unlock_ramlist qemu_mutex_unlock_ramlist_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 96ff3baa..d62f4ee6 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -2414,7 +2414,6 @@ #define qemu_clock_get_us qemu_clock_get_us_mips64 #define qemu_clock_ptr qemu_clock_ptr_mips64 #define qemu_clocks qemu_clocks_mips64 -#define qemu_cond_destroy qemu_cond_destroy_mips64 #define qemu_cpu_is_self qemu_cpu_is_self_mips64 #define qemu_cpu_kick_thread qemu_cpu_kick_thread_mips64 #define qemu_daemon qemu_daemon_mips64 @@ -2442,7 +2441,6 @@ #define qemu_log_flush qemu_log_flush_mips64 #define qemu_loglevel_mask qemu_loglevel_mask_mips64 #define qemu_log_vprintf qemu_log_vprintf_mips64 -#define qemu_mutex_destroy qemu_mutex_destroy_mips64 #define qemu_mutex_lock_ramlist qemu_mutex_lock_ramlist_mips64 #define qemu_mutex_trylock qemu_mutex_trylock_mips64 #define qemu_mutex_unlock_ramlist qemu_mutex_unlock_ramlist_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 60315919..8193f24b 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -2414,7 +2414,6 @@ #define qemu_clock_get_us qemu_clock_get_us_mips64el #define qemu_clock_ptr qemu_clock_ptr_mips64el #define qemu_clocks qemu_clocks_mips64el -#define qemu_cond_destroy qemu_cond_destroy_mips64el #define qemu_cpu_is_self qemu_cpu_is_self_mips64el #define qemu_cpu_kick_thread qemu_cpu_kick_thread_mips64el #define qemu_daemon qemu_daemon_mips64el @@ -2442,7 +2441,6 @@ #define qemu_log_flush qemu_log_flush_mips64el #define qemu_loglevel_mask qemu_loglevel_mask_mips64el #define qemu_log_vprintf qemu_log_vprintf_mips64el -#define qemu_mutex_destroy qemu_mutex_destroy_mips64el #define qemu_mutex_lock_ramlist qemu_mutex_lock_ramlist_mips64el #define qemu_mutex_trylock qemu_mutex_trylock_mips64el #define qemu_mutex_unlock_ramlist qemu_mutex_unlock_ramlist_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 54c454f8..02a39df5 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -2414,7 +2414,6 @@ #define qemu_clock_get_us qemu_clock_get_us_mipsel #define qemu_clock_ptr qemu_clock_ptr_mipsel #define qemu_clocks qemu_clocks_mipsel -#define qemu_cond_destroy qemu_cond_destroy_mipsel #define qemu_cpu_is_self qemu_cpu_is_self_mipsel #define qemu_cpu_kick_thread qemu_cpu_kick_thread_mipsel #define qemu_daemon qemu_daemon_mipsel @@ -2442,7 +2441,6 @@ #define qemu_log_flush qemu_log_flush_mipsel #define qemu_loglevel_mask qemu_loglevel_mask_mipsel #define qemu_log_vprintf qemu_log_vprintf_mipsel -#define qemu_mutex_destroy qemu_mutex_destroy_mipsel #define qemu_mutex_lock_ramlist qemu_mutex_lock_ramlist_mipsel #define qemu_mutex_trylock qemu_mutex_trylock_mipsel #define qemu_mutex_unlock_ramlist qemu_mutex_unlock_ramlist_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 7cd2c00d..cb7a046c 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -2414,7 +2414,6 @@ #define qemu_clock_get_us qemu_clock_get_us_powerpc #define qemu_clock_ptr qemu_clock_ptr_powerpc #define qemu_clocks qemu_clocks_powerpc -#define qemu_cond_destroy qemu_cond_destroy_powerpc #define qemu_cpu_is_self qemu_cpu_is_self_powerpc #define qemu_cpu_kick_thread qemu_cpu_kick_thread_powerpc #define qemu_daemon qemu_daemon_powerpc @@ -2442,7 +2441,6 @@ #define qemu_log_flush qemu_log_flush_powerpc #define qemu_loglevel_mask qemu_loglevel_mask_powerpc #define qemu_log_vprintf qemu_log_vprintf_powerpc -#define qemu_mutex_destroy qemu_mutex_destroy_powerpc #define qemu_mutex_lock_ramlist qemu_mutex_lock_ramlist_powerpc #define qemu_mutex_trylock qemu_mutex_trylock_powerpc #define qemu_mutex_unlock_ramlist qemu_mutex_unlock_ramlist_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index c30dd375..85e042e8 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -2414,7 +2414,6 @@ #define qemu_clock_get_us qemu_clock_get_us_sparc #define qemu_clock_ptr qemu_clock_ptr_sparc #define qemu_clocks qemu_clocks_sparc -#define qemu_cond_destroy qemu_cond_destroy_sparc #define qemu_cpu_is_self qemu_cpu_is_self_sparc #define qemu_cpu_kick_thread qemu_cpu_kick_thread_sparc #define qemu_daemon qemu_daemon_sparc @@ -2442,7 +2441,6 @@ #define qemu_log_flush qemu_log_flush_sparc #define qemu_loglevel_mask qemu_loglevel_mask_sparc #define qemu_log_vprintf qemu_log_vprintf_sparc -#define qemu_mutex_destroy qemu_mutex_destroy_sparc #define qemu_mutex_lock_ramlist qemu_mutex_lock_ramlist_sparc #define qemu_mutex_trylock qemu_mutex_trylock_sparc #define qemu_mutex_unlock_ramlist qemu_mutex_unlock_ramlist_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index c7824ebf..a08c42e1 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -2414,7 +2414,6 @@ #define qemu_clock_get_us qemu_clock_get_us_sparc64 #define qemu_clock_ptr qemu_clock_ptr_sparc64 #define qemu_clocks qemu_clocks_sparc64 -#define qemu_cond_destroy qemu_cond_destroy_sparc64 #define qemu_cpu_is_self qemu_cpu_is_self_sparc64 #define qemu_cpu_kick_thread qemu_cpu_kick_thread_sparc64 #define qemu_daemon qemu_daemon_sparc64 @@ -2442,7 +2441,6 @@ #define qemu_log_flush qemu_log_flush_sparc64 #define qemu_loglevel_mask qemu_loglevel_mask_sparc64 #define qemu_log_vprintf qemu_log_vprintf_sparc64 -#define qemu_mutex_destroy qemu_mutex_destroy_sparc64 #define qemu_mutex_lock_ramlist qemu_mutex_lock_ramlist_sparc64 #define qemu_mutex_trylock qemu_mutex_trylock_sparc64 #define qemu_mutex_unlock_ramlist qemu_mutex_unlock_ramlist_sparc64 diff --git a/qemu/unicorn_common.h b/qemu/unicorn_common.h index 2df9ccef..a09253d3 100644 --- a/qemu/unicorn_common.h +++ b/qemu/unicorn_common.h @@ -35,6 +35,7 @@ static void release_common(void *t) { TCGContext *s = (TCGContext *)t; struct uc_struct* uc = s->uc; + CPUState *cpu; // Clean TCG. TCGOpDef* def = &s->tcg_op_defs[0]; @@ -55,9 +56,48 @@ static void release_common(void *t) memory_free(uc); // Clean CPU. + CPU_FOREACH(cpu) { + g_free(cpu->tcg_as_listener); + g_free(cpu->thread); + g_free(cpu->halt_cond); + } + + OBJECT(uc->machine_state->accelerator)->ref = 1; + OBJECT(uc->machine_state)->ref = 1; + OBJECT(uc->owner)->ref = 1; + OBJECT(uc->root)->ref = 1; + + object_unref(uc, OBJECT(uc->machine_state->accelerator)); + object_unref(uc, OBJECT(uc->machine_state)); object_unref(uc, uc->cpu); + object_unref(uc, OBJECT(&uc->io_mem_notdirty)); + object_unref(uc, OBJECT(&uc->io_mem_unassigned)); + object_unref(uc, OBJECT(&uc->io_mem_rom)); + object_unref(uc, OBJECT(uc->root)); g_hash_table_foreach(uc->type_table, free_table, uc); + g_free(uc->system_memory); + + if(uc->qemu_thread_data) + free(uc->qemu_thread_data); + +#if TCG_TARGET_REG_BITS == 32 + for(int i = 0; i < s->nb_globals; i++) + { + TCGTemp *ts = &s->temps[i]; + if(ts->base_type == TCG_TYPE_I64) + { + if(ts->name && ((strcmp(ts->name+(strlen(ts->name)-2), "_0") == 0) || (strcmp(ts->name+(strlen(ts->name)-2), "_1") == 0))) + { + free((void *)ts->name); + } + } + } +#endif + + qemu_mutex_destroy(&uc->qemu_global_mutex); + qemu_cond_destroy(&uc->qemu_cpu_cond); + // Clean cache. tb_cleanup(uc); } diff --git a/qemu/util/qemu-thread-posix.c b/qemu/util/qemu-thread-posix.c index 26cba2da..a250044f 100644 --- a/qemu/util/qemu-thread-posix.c +++ b/qemu/util/qemu-thread-posix.c @@ -441,7 +441,7 @@ void qemu_thread_exit(struct uc_struct *uc, void *retval) pthread_exit(retval); } -void *qemu_thread_join(QemuThread *thread) +void *qemu_thread_join(struct uc_struct *uc, QemuThread *thread) { int err; void *ret; diff --git a/qemu/util/qemu-thread-win32.c b/qemu/util/qemu-thread-win32.c index 2c2cf4ad..4732731d 100644 --- a/qemu/util/qemu-thread-win32.c +++ b/qemu/util/qemu-thread-win32.c @@ -276,6 +276,7 @@ static unsigned __stdcall win32_start_routine(void *arg) void *thread_arg = data->arg; if (data->mode == QEMU_THREAD_DETACHED) { + data->uc->qemu_thread_data = NULL; g_free(data); data = NULL; } @@ -297,7 +298,7 @@ void qemu_thread_exit(struct uc_struct *uc, void *arg) _endthreadex(0); } -void *qemu_thread_join(QemuThread *thread) +void *qemu_thread_join(struct uc_struct *uc, QemuThread *thread) { QemuThreadData *data; void *ret; @@ -322,6 +323,7 @@ void *qemu_thread_join(QemuThread *thread) ret = data->ret; assert(data->mode != QEMU_THREAD_DETACHED); DeleteCriticalSection(&data->cs); + uc->qemu_thread_data = NULL; g_free(data); return ret; } diff --git a/qemu/vl.c b/qemu/vl.c index caf6686f..34b0f40a 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -107,15 +107,18 @@ int machine_initialize(struct uc_struct *uc) module_call_init(uc, MODULE_INIT_MACHINE); // this will auto initialize all register objects above. machine_class = find_default_machine(uc, uc->arch); - if (machine_class == NULL) { - //fprintf(stderr, "No machine specified, and there is no default.\n" - // "Use -machine help to list supported machines!\n"); - return -2; + if(!uc->machine_state) + { + if (machine_class == NULL) { + //fprintf(stderr, "No machine specified, and there is no default.\n" + // "Use -machine help to list supported machines!\n"); + return -2; + } + + current_machine = MACHINE(uc, object_new(uc, object_class_get_name( + OBJECT_CLASS(machine_class)))); + uc->machine_state = current_machine; } - - current_machine = MACHINE(uc, object_new(uc, object_class_get_name( - OBJECT_CLASS(machine_class)))); - current_machine->uc = uc; uc->cpu_exec_init_all(uc); diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 340e4e08..882a7b0d 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -2414,7 +2414,6 @@ #define qemu_clock_get_us qemu_clock_get_us_x86_64 #define qemu_clock_ptr qemu_clock_ptr_x86_64 #define qemu_clocks qemu_clocks_x86_64 -#define qemu_cond_destroy qemu_cond_destroy_x86_64 #define qemu_cpu_is_self qemu_cpu_is_self_x86_64 #define qemu_cpu_kick_thread qemu_cpu_kick_thread_x86_64 #define qemu_daemon qemu_daemon_x86_64 @@ -2442,7 +2441,6 @@ #define qemu_log_flush qemu_log_flush_x86_64 #define qemu_loglevel_mask qemu_loglevel_mask_x86_64 #define qemu_log_vprintf qemu_log_vprintf_x86_64 -#define qemu_mutex_destroy qemu_mutex_destroy_x86_64 #define qemu_mutex_lock_ramlist qemu_mutex_lock_ramlist_x86_64 #define qemu_mutex_trylock qemu_mutex_trylock_x86_64 #define qemu_mutex_unlock_ramlist qemu_mutex_unlock_ramlist_x86_64 diff --git a/uc.c b/uc.c index 5d6f5f2c..14290e8e 100644 --- a/uc.c +++ b/uc.c @@ -263,9 +263,7 @@ uc_err uc_close(uc_engine *uc) if (uc->release) uc->release(uc->tcg_ctx); -#ifndef _WIN32 free(uc->l1_map); -#endif if (uc->bounce.buffer) { free(uc->bounce.buffer); @@ -273,8 +271,6 @@ uc_err uc_close(uc_engine *uc) g_free(uc->tcg_ctx); - free((void*) uc->system_memory->name); - g_free(uc->system_memory); g_hash_table_destroy(uc->type_table); for (i = 0; i < DIRTY_MEMORY_NUM; i++) { @@ -282,7 +278,7 @@ uc_err uc_close(uc_engine *uc) } // TODO: remove uc->root (created with object_new()) - uc->root->free(uc->root); + //uc->root->free(uc->root); free(uc->hook_callbacks); @@ -524,7 +520,7 @@ uc_err uc_emu_start(uc_engine* uc, uint64_t begin, uint64_t until, uint64_t time if (timeout) { // wait for the timer to finish - qemu_thread_join(&uc->timer); + qemu_thread_join(uc, &uc->timer); } return uc->invalid_error;