diff --git a/bindings/dotnet/UnicornManaged/Const/Common.fs b/bindings/dotnet/UnicornManaged/Const/Common.fs index 4a13b793..c80ded89 100644 --- a/bindings/dotnet/UnicornManaged/Const/Common.fs +++ b/bindings/dotnet/UnicornManaged/Const/Common.fs @@ -71,7 +71,6 @@ module Common = let UC_ERR_HOOK_EXIST = 19 let UC_ERR_RESOURCE = 20 let UC_ERR_EXCEPTION = 21 - let UC_ERR_TIMEOUT = 22 let UC_MEM_READ = 16 let UC_MEM_WRITE = 17 let UC_MEM_FETCH = 18 @@ -107,6 +106,7 @@ module Common = let UC_QUERY_MODE = 1 let UC_QUERY_PAGE_SIZE = 2 let UC_QUERY_ARCH = 3 + let UC_QUERY_TIMEOUT = 4 let UC_PROT_NONE = 0 let UC_PROT_READ = 1 diff --git a/bindings/go/unicorn/unicorn_const.go b/bindings/go/unicorn/unicorn_const.go index 645ef8da..ebc2af2a 100644 --- a/bindings/go/unicorn/unicorn_const.go +++ b/bindings/go/unicorn/unicorn_const.go @@ -66,7 +66,6 @@ const ( ERR_HOOK_EXIST = 19 ERR_RESOURCE = 20 ERR_EXCEPTION = 21 - ERR_TIMEOUT = 22 MEM_READ = 16 MEM_WRITE = 17 MEM_FETCH = 18 @@ -102,6 +101,7 @@ const ( QUERY_MODE = 1 QUERY_PAGE_SIZE = 2 QUERY_ARCH = 3 + QUERY_TIMEOUT = 4 PROT_NONE = 0 PROT_READ = 1 diff --git a/bindings/java/unicorn/UnicornConst.java b/bindings/java/unicorn/UnicornConst.java index 4cba0f73..ee5c9844 100644 --- a/bindings/java/unicorn/UnicornConst.java +++ b/bindings/java/unicorn/UnicornConst.java @@ -68,7 +68,6 @@ public interface UnicornConst { public static final int UC_ERR_HOOK_EXIST = 19; public static final int UC_ERR_RESOURCE = 20; public static final int UC_ERR_EXCEPTION = 21; - public static final int UC_ERR_TIMEOUT = 22; public static final int UC_MEM_READ = 16; public static final int UC_MEM_WRITE = 17; public static final int UC_MEM_FETCH = 18; @@ -104,6 +103,7 @@ public interface UnicornConst { public static final int UC_QUERY_MODE = 1; public static final int UC_QUERY_PAGE_SIZE = 2; public static final int UC_QUERY_ARCH = 3; + public static final int UC_QUERY_TIMEOUT = 4; public static final int UC_PROT_NONE = 0; public static final int UC_PROT_READ = 1; diff --git a/bindings/pascal/unicorn/UnicornConst.pas b/bindings/pascal/unicorn/UnicornConst.pas index 6c5a7c53..7337543d 100644 --- a/bindings/pascal/unicorn/UnicornConst.pas +++ b/bindings/pascal/unicorn/UnicornConst.pas @@ -69,7 +69,6 @@ const UC_API_MAJOR = 1; UC_ERR_HOOK_EXIST = 19; UC_ERR_RESOURCE = 20; UC_ERR_EXCEPTION = 21; - UC_ERR_TIMEOUT = 22; UC_MEM_READ = 16; UC_MEM_WRITE = 17; UC_MEM_FETCH = 18; @@ -105,6 +104,7 @@ const UC_API_MAJOR = 1; UC_QUERY_MODE = 1; UC_QUERY_PAGE_SIZE = 2; UC_QUERY_ARCH = 3; + UC_QUERY_TIMEOUT = 4; UC_PROT_NONE = 0; UC_PROT_READ = 1; diff --git a/bindings/python/unicorn/unicorn_const.py b/bindings/python/unicorn/unicorn_const.py index d78e6fa0..54e2c951 100644 --- a/bindings/python/unicorn/unicorn_const.py +++ b/bindings/python/unicorn/unicorn_const.py @@ -64,7 +64,6 @@ UC_ERR_FETCH_UNALIGNED = 18 UC_ERR_HOOK_EXIST = 19 UC_ERR_RESOURCE = 20 UC_ERR_EXCEPTION = 21 -UC_ERR_TIMEOUT = 22 UC_MEM_READ = 16 UC_MEM_WRITE = 17 UC_MEM_FETCH = 18 @@ -100,6 +99,7 @@ UC_HOOK_MEM_VALID = 7168 UC_QUERY_MODE = 1 UC_QUERY_PAGE_SIZE = 2 UC_QUERY_ARCH = 3 +UC_QUERY_TIMEOUT = 4 UC_PROT_NONE = 0 UC_PROT_READ = 1 diff --git a/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb b/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb index c014d3f7..178fac66 100644 --- a/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb +++ b/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb @@ -66,7 +66,6 @@ module UnicornEngine UC_ERR_HOOK_EXIST = 19 UC_ERR_RESOURCE = 20 UC_ERR_EXCEPTION = 21 - UC_ERR_TIMEOUT = 22 UC_MEM_READ = 16 UC_MEM_WRITE = 17 UC_MEM_FETCH = 18 @@ -102,6 +101,7 @@ module UnicornEngine UC_QUERY_MODE = 1 UC_QUERY_PAGE_SIZE = 2 UC_QUERY_ARCH = 3 + UC_QUERY_TIMEOUT = 4 UC_PROT_NONE = 0 UC_PROT_READ = 1 diff --git a/include/uc_priv.h b/include/uc_priv.h index a3023e33..1a894815 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -227,7 +227,7 @@ struct uc_struct { 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() - bool timed_out; // emulation timed out, uc_emu_start() will result in EC_ERR_TIMEOUT + bool timed_out; // emulation timed out, that can retrieve via uc_query(UC_QUERY_TIMEOUT) QemuThread timer; // timer for emulation timeout uint64_t timeout; // timeout for uc_emu_start() diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index fb5a5657..12937a68 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -164,7 +164,6 @@ typedef enum uc_err { UC_ERR_HOOK_EXIST, // hook for this event already existed UC_ERR_RESOURCE, // Insufficient resource: uc_emu_start() UC_ERR_EXCEPTION, // Unhandled CPU exception - UC_ERR_TIMEOUT // Emulation timed out } uc_err; @@ -330,8 +329,9 @@ typedef struct uc_mem_region { typedef enum uc_query_type { // Dynamically query current hardware mode. UC_QUERY_MODE = 1, - UC_QUERY_PAGE_SIZE, - UC_QUERY_ARCH, + UC_QUERY_PAGE_SIZE, // query pagesize of engine + UC_QUERY_ARCH, // query architecture of engine + UC_QUERY_TIMEOUT, // query if emulation stops because of timeout } uc_query_type; // Opaque storage for CPU context, used with uc_context_*() diff --git a/samples/sample_x86.c b/samples/sample_x86.c index 99d63b02..1028504f 100644 --- a/samples/sample_x86.c +++ b/samples/sample_x86.c @@ -383,8 +383,8 @@ static void test_i386_loop(void) // emulate machine code in 2 seconds, so we can quit even // if the code loops err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_LOOP) - 1, 2 * UC_SECOND_SCALE, 0); - if (err != UC_ERR_TIMEOUT) { - printf("Failed on uc_emu_start() with error returned %u: %s, expected UC_ERR_TIMEOUT\n", + if (err) { + printf("Failed on uc_emu_start() with error returned %u: %s\n", err, uc_strerror(err)); } diff --git a/tests/unit/test_x86.c b/tests/unit/test_x86.c index 280d4b07..dc07433d 100644 --- a/tests/unit/test_x86.c +++ b/tests/unit/test_x86.c @@ -379,7 +379,7 @@ static void test_i386_loop(void **state) // emulate machine code in 2 seconds, so we can quit even // if the code loops err = uc_emu_start(uc, address, address+sizeof(code), 2*UC_SECOND_SCALE, 0); - uc_assert_err(err, UC_ERR_TIMEOUT); + uc_assert_err(err); // verify register values uc_assert_success(uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx)); diff --git a/uc.c b/uc.c index a342da52..e9e0bd4d 100644 --- a/uc.c +++ b/uc.c @@ -101,8 +101,6 @@ const char *uc_strerror(uc_err code) return "Insufficient resource (UC_ERR_RESOURCE)"; case UC_ERR_EXCEPTION: return "Unhandled CPU exception (UC_ERR_EXCEPTION)"; - case UC_ERR_TIMEOUT: - return "Emulation timed out (UC_ERR_TIMEOUT)"; } } @@ -662,9 +660,6 @@ uc_err uc_emu_start(uc_engine* uc, uint64_t begin, uint64_t until, uint64_t time qemu_thread_join(&uc->timer); } - if(uc->timed_out) - return UC_ERR_TIMEOUT; - return uc->invalid_error; } @@ -1252,23 +1247,29 @@ uint32_t uc_mem_regions(uc_engine *uc, uc_mem_region **regions, uint32_t *count) UNICORN_EXPORT uc_err uc_query(uc_engine *uc, uc_query_type type, size_t *result) { - if (type == UC_QUERY_PAGE_SIZE) { - *result = uc->target_page_size; - return UC_ERR_OK; - } - - if (type == UC_QUERY_ARCH) { - *result = uc->arch; - return UC_ERR_OK; - } - - switch(uc->arch) { -#ifdef UNICORN_HAS_ARM - case UC_ARCH_ARM: - return uc->query(uc, type, result); -#endif + switch(type) { default: return UC_ERR_ARG; + + case UC_QUERY_PAGE_SIZE: + *result = uc->target_page_size; + break; + + case UC_QUERY_ARCH: + *result = uc->arch; + break; + + case UC_QUERY_MODE: +#ifdef UNICORN_HAS_ARM + if (uc->arch == UC_ARCH_ARM) { + return uc->query(uc, type, result); + } +#endif + return UC_ERR_ARG; + + case UC_QUERY_TIMEOUT: + *result = uc->timed_out; + break; } return UC_ERR_OK;