diff --git a/Cargo.toml b/Cargo.toml index 9692ecb37a..3d6d388d20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "unicorn-engine" -version = "2.0.0" +version = "2.0.1" authors = ["Ziqiao Kong", "Lukas Seidel"] documentation = "https://github.com/unicorn-engine/unicorn/wiki" edition = "2021" diff --git a/bindings/dotnet/UnicornManaged/Const/Common.fs b/bindings/dotnet/UnicornManaged/Const/Common.fs index af230df473..72b5cb3a2c 100644 --- a/bindings/dotnet/UnicornManaged/Const/Common.fs +++ b/bindings/dotnet/UnicornManaged/Const/Common.fs @@ -9,14 +9,12 @@ module Common = let UC_API_MAJOR = 2 let UC_API_MINOR = 0 - - let UC_API_PATCH = 0 + let UC_API_PATCH = 1 let UC_API_EXTRA = 255 let UC_VERSION_MAJOR = 2 let UC_VERSION_MINOR = 0 - - let UC_VERSION_PATCH = 0 + let UC_VERSION_PATCH = 1 let UC_VERSION_EXTRA = 255 let UC_SECOND_SCALE = 1000000 let UC_MILISECOND_SCALE = 1000 diff --git a/bindings/go/unicorn/unicorn_const.go b/bindings/go/unicorn/unicorn_const.go index 107ef74507..19268ce565 100644 --- a/bindings/go/unicorn/unicorn_const.go +++ b/bindings/go/unicorn/unicorn_const.go @@ -4,14 +4,12 @@ const ( API_MAJOR = 2 API_MINOR = 0 - - API_PATCH = 0 + API_PATCH = 1 API_EXTRA = 255 VERSION_MAJOR = 2 VERSION_MINOR = 0 - - VERSION_PATCH = 0 + VERSION_PATCH = 1 VERSION_EXTRA = 255 SECOND_SCALE = 1000000 MILISECOND_SCALE = 1000 diff --git a/bindings/java/unicorn/UnicornConst.java b/bindings/java/unicorn/UnicornConst.java index 04fb15dd35..62759ba6fc 100644 --- a/bindings/java/unicorn/UnicornConst.java +++ b/bindings/java/unicorn/UnicornConst.java @@ -6,14 +6,12 @@ public interface UnicornConst { public static final int UC_API_MAJOR = 2; public static final int UC_API_MINOR = 0; - - public static final int UC_API_PATCH = 0; + public static final int UC_API_PATCH = 1; public static final int UC_API_EXTRA = 255; public static final int UC_VERSION_MAJOR = 2; public static final int UC_VERSION_MINOR = 0; - - public static final int UC_VERSION_PATCH = 0; + public static final int UC_VERSION_PATCH = 1; public static final int UC_VERSION_EXTRA = 255; public static final int UC_SECOND_SCALE = 1000000; public static final int UC_MILISECOND_SCALE = 1000; diff --git a/bindings/pascal/unicorn/UnicornConst.pas b/bindings/pascal/unicorn/UnicornConst.pas index faff27bf2b..26896d130d 100644 --- a/bindings/pascal/unicorn/UnicornConst.pas +++ b/bindings/pascal/unicorn/UnicornConst.pas @@ -7,14 +7,12 @@ interface const UC_API_MAJOR = 2; UC_API_MINOR = 0; - - UC_API_PATCH = 0; + UC_API_PATCH = 1; UC_API_EXTRA = 255; UC_VERSION_MAJOR = 2; UC_VERSION_MINOR = 0; - - UC_VERSION_PATCH = 0; + UC_VERSION_PATCH = 1; UC_VERSION_EXTRA = 255; UC_SECOND_SCALE = 1000000; UC_MILISECOND_SCALE = 1000; diff --git a/bindings/python/setup.py b/bindings/python/setup.py index f8948d62a2..34c6faf4f9 100755 --- a/bindings/python/setup.py +++ b/bindings/python/setup.py @@ -29,7 +29,7 @@ UC_DIR = SRC_DIR if os.path.exists(SRC_DIR) else os.path.join(ROOT_DIR, '../..') BUILD_DIR = os.path.join(UC_DIR, 'build_python') -VERSION = "2.0.0" +VERSION = "2.0.1" if SYSTEM == 'darwin': LIBRARY_FILE = "libunicorn.2.dylib" diff --git a/bindings/python/unicorn/unicorn_const.py b/bindings/python/unicorn/unicorn_const.py index 5fdb853760..f491dd26eb 100644 --- a/bindings/python/unicorn/unicorn_const.py +++ b/bindings/python/unicorn/unicorn_const.py @@ -2,14 +2,12 @@ UC_API_MAJOR = 2 UC_API_MINOR = 0 - -UC_API_PATCH = 0 +UC_API_PATCH = 1 UC_API_EXTRA = 255 UC_VERSION_MAJOR = 2 UC_VERSION_MINOR = 0 - -UC_VERSION_PATCH = 0 +UC_VERSION_PATCH = 1 UC_VERSION_EXTRA = 255 UC_SECOND_SCALE = 1000000 UC_MILISECOND_SCALE = 1000 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 1fb2196844..e317589e2e 100644 --- a/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb +++ b/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb @@ -4,14 +4,12 @@ module UnicornEngine UC_API_MAJOR = 2 UC_API_MINOR = 0 - - UC_API_PATCH = 0 + UC_API_PATCH = 1 UC_API_EXTRA = 255 UC_VERSION_MAJOR = 2 UC_VERSION_MINOR = 0 - - UC_VERSION_PATCH = 0 + UC_VERSION_PATCH = 1 UC_VERSION_EXTRA = 255 UC_SECOND_SCALE = 1000000 UC_MILISECOND_SCALE = 1000 diff --git a/docs/FAQ.md b/docs/FAQ.md index 5a833139c2..ce29a62a36 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -9,10 +9,10 @@ Optimize your program with less instrumentation, e.g. by using `UC_HOOK_BLOCK` i ## Why do I get a wrong PC after emulation stops? -Updating PC is a very large overhead (10x slower in the worst case, see FAQ above) for emulation so the PC sync guarantee is explained below: +Updating PC is a very large overhead (10x slower in the worst case, see FAQ above) for emulation so the PC sync guarantee is explained below in several cases: -- A `UC_HOOK_CODE` is installed. In this case, the PC is sync-ed _everywhere_ within the effective range of the hook. However, on some architectures, the PC might by sync-ed all the time if the hook is installed. -- A `UC_HOOK_MEM_READ` or `UC_HOOK_MEM_WRITE` is installed. In this case, the PC is sync-ed exactly before any read/write events within the effective range of the hook. +- A `UC_HOOK_CODE` hook is installed. In this case, the PC is sync-ed _everywhere_ within the effective range of the hook. However, on some architectures, the PC might by sync-ed all the time if the hook is installed in any range. Note using `count` in `uc_emu_start` implies installing a `UC_HOOK_CODE` hook. +- A `UC_HOOK_MEM_READ` or `UC_HOOK_MEM_WRITE` hook is installed. In this case, the PC is sync-ed exactly before any read/write events within the effective range of the hook. - Emulation (`uc_emu_start`) terminates without any exception. In this case, the PC will point to the next instruction. - No hook mentioned above is installed and emulation terminates with exceptions. In this case, the PC is sync-ed at the basic block boundary, in other words, the first instruction of the basic block where the exception happens. @@ -44,12 +44,13 @@ Currently, only a small subset of the instructions can be instrumented. On x86, all available instructions are: `in` `out` `syscall` `sysenter` `cpuid`. -## Emulating some instructions gives an error, what should I do? +## Emulating some instructions gives an error like "Invalid Instruction", what should I do? 1. Some instructions are not enabled by default on some architectures. For example, you have to setup CSR on RISC-V or VFP on ARM before emulating floating-point instructions. Refer to the corresponding manual to check if you leave out possible switches in special registers. -2. If you are on ARM, please check whether you are emulating a THUMB instruction. If so, please use `UC_MODE_THUMB` and make sure the starting address is odd. -3. If either is not the case, it might be some newer instruction sets that qemu5 doesn’t support. -4. Note some instruction sets are not implemented by QEMU. +2. Different CPU models support different sets of instructions. This is especially observed on ARM CPUs. For example, for `THUMB2` big-endian instructions, consider setting CPU model to `cortex-r5` or `arm_max`. See [#1725](https://github.com/unicorn-engine/unicorn/issues/1725) and [#1724](https://github.com/unicorn-engine/unicorn/issues/1724). +3. If you are on ARM, please check whether you are emulating a THUMB instruction. If so, please use `UC_MODE_THUMB` and make sure the starting address is odd. +4. If it's not the cases above, it might be some newer instruction sets that qemu5 doesn’t support. +5. Note some instruction sets are not implemented by the latest QEMU. If you are still using Unicorn1, please upgrade to Unicorn2 for better support. diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index c8315b8377..4b169d761f 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -72,7 +72,7 @@ typedef size_t uc_hook; // Unicorn API version #define UC_API_MAJOR 2 #define UC_API_MINOR 0 -#define UC_API_PATCH 0 +#define UC_API_PATCH 1 // Release candidate version, 255 means the official release. #define UC_API_EXTRA 255