From 20a22fd65e524873397a2f421f3510c58ce0075f Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Wed, 27 May 2020 15:02:17 +0800 Subject: [PATCH 01/44] .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 5973b4b4..18fd949f 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,8 @@ qemu/sparc64-softmmu/ qemu/sparc-softmmu/ qemu/i386-softmmu/ qemu/x86_64-softmmu/ +qemu/ppc-softmmu/ +qemu/ppc64-softmmu/ tags qemu/config-host.ld From 2d75bc0aab6fd8b66be9102671e4f3e9a853cdbe Mon Sep 17 00:00:00 2001 From: chfl4gs <55137784+chfl4gs@users.noreply.github.com> Date: Wed, 27 May 2020 16:20:39 +0800 Subject: [PATCH 02/44] make header for make related builds (#1268) * Travis-CI Migration (#1230) * Travis-CI Migration * Travis-CI addition cmake Linux * Travis-CI cmake fix * Travis-CI Arm64 build * make header for make related build --- .travis.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2b021068..75da008b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,9 +7,9 @@ script: choco install cygwin cyg-get && \ cyg-get.bat default autoconf automake make gcc-core clang pkg-config libpcre-devel cmake python27-setuptools ruby wget && \ export SHELLOPTS && set -o igncr \ - cmd.exe //C "C:\\tools\\cygwin\\bin\\bash.exe -lc 'cd /cygdrive/$TRAVIS_BUILD_DIR; make; ./install-cmocka-linux.sh; export PATH="$PATH":/cygdrive/$TRAVIS_BUILD_DIR:/cygdrive/$TRAVIS_BUILD_DIR/cmocka/src; make test'" + cmd.exe //C "C:\\tools\\cygwin\\bin\\bash.exe -lc 'cd /cygdrive/$TRAVIS_BUILD_DIR; make header; make; ./install-cmocka-linux.sh; export PATH="$PATH":/cygdrive/$TRAVIS_BUILD_DIR:/cygdrive/$TRAVIS_BUILD_DIR/cmocka/src; make test'" else - make && make -C bindings/go && make -C bindings/go test && make test + make header && make && make -C bindings/go && make -C bindings/go test && make test fi compiler: - clang @@ -28,7 +28,7 @@ matrix: language: c env: - PATH=$PATH:/usr/local/opt/binutils/bin - script: make && make -C tests/unit test && make -C tests/regress test + script: make header && make && make -C tests/unit test && make -C tests/regress test - name: "Linux arm64 gcc C" arch: arm64 @@ -37,7 +37,7 @@ matrix: language: c env: - PATH=$PATH:/usr/local/opt/binutils/bin - script: make && make -C tests/unit test && make -C tests/regress test + script: make header && make && make -C tests/unit test && make -C tests/regress test - name: "Linux clang ASAN" os: linux @@ -48,7 +48,7 @@ matrix: - CXXFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -fsanitize=fuzzer-no-link" - CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -fsanitize=fuzzer-no-link" - LDFLAGS="-fsanitize=address" - script: make && make -C tests/fuzz && sh tests/fuzz/dlcorpus.sh + script: make header && make && make -C tests/fuzz && sh tests/fuzz/dlcorpus.sh - name: "Linux clang MSAN" os: linux @@ -59,7 +59,7 @@ matrix: - CXXFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=memory -fsanitize=fuzzer-no-link" - CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=memory -fsanitize=fuzzer-no-link" - LDFLAGS="-fsanitize=memory" - script: make && make -C tests/fuzz && sh tests/fuzz/dlcorpus.sh + script: make header && make && make -C tests/fuzz && sh tests/fuzz/dlcorpus.sh - name: "Linux clang USAN" os: linux @@ -70,7 +70,7 @@ matrix: - CXXFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=undefined -fsanitize=fuzzer-no-link" - CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=undefined -fsanitize=fuzzer-no-link" - LDFLAGS="-fsanitize=undefined" - script: make && make -C tests/fuzz && sh tests/fuzz/dlcorpus.sh + script: make header && make && make -C tests/fuzz && sh tests/fuzz/dlcorpus.sh - name: "Linux 32bit" os: linux @@ -78,7 +78,7 @@ matrix: env: - CFLAGS="-m32" LDFLAGS="-m32" LDFLAGS_STATIC="-m32" UNICORN_QEMU_FLAGS="--cpu=i386" - PATH=$PATH:/usr/local/opt/binutils/bin - script: make && make -C tests/unit test && make -C tests/regress test + script: make header && make && make -C tests/unit test && make -C tests/regress test addons: apt: packages: @@ -221,7 +221,7 @@ matrix: - $HOME/AppData/Local/Temp/chocolatey - /C/tools/msys64 script: - - $shell make; cp unicorn.dll /C/Windows/SysWOW64/; $shell make test + - $shell make header; $shell make; cp unicorn.dll /C/Windows/SysWOW64/; $shell make test - name: "Windows MSYS2/MinGW64" os: windows @@ -263,7 +263,7 @@ matrix: - $HOME/AppData/Local/Temp/chocolatey - /C/tools/msys64 script: - - $shell make; cp unicorn.dll /C/Windows/System32/; $shell make test + - $shell make header; $shell make; cp unicorn.dll /C/Windows/System32/; $shell make test addons: apt: packages: From e55909cec44140fed5432ad763475ba511e68495 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 29 May 2020 01:02:46 +0800 Subject: [PATCH 03/44] ChangeLog for 1.0.2-rc4 --- ChangeLog | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ChangeLog b/ChangeLog index 8ff87b51..bb2e6a07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,22 @@ This file details the changelog of Unicorn Engine. +---------------------------------- +[Version 1.0.2-rc4]: May 29th, 2020 + +- No longer require Python to build +- Fix recursive UC_HOOK_MEM callbacks for cross pages access +- Remove UC_ERR_TIMEOUT, so timeout on uc_emu_start() is not considered error +- Added UC_QUERY_TIMEOUT to query exit reason +- Fix UAF when deleting hook while in hook callback +- Ensure that hooks are unaffected by a request to stop emulation. +- Fix block hooks being called twice after an early exit from execution. +- Fix binding install on python2 +- X86: + - Support read/write STn registers + - Support read/write X64 base regs +- ARM64: + - Support some new registers + ---------------------------------- [Version 1.0.1]: April 20th, 2017 From 934b04884e2ebeca5d954e353cc261b06baf5855 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 29 May 2020 01:20:12 +0800 Subject: [PATCH 04/44] ChangeLog --- ChangeLog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bb2e6a07..7e81b347 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ This file details the changelog of Unicorn Engine. ----------------------------------- +----------------------------------- [Version 1.0.2-rc4]: May 29th, 2020 - No longer require Python to build @@ -10,7 +10,7 @@ This file details the changelog of Unicorn Engine. - Fix UAF when deleting hook while in hook callback - Ensure that hooks are unaffected by a request to stop emulation. - Fix block hooks being called twice after an early exit from execution. -- Fix binding install on python2 +- Fix binding install on python2 (MacOS) - X86: - Support read/write STn registers - Support read/write X64 base regs From 99be837364ac62c45f610b6f76c623a2794758a0 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 29 May 2020 11:56:24 +0800 Subject: [PATCH 05/44] python: add long description to setup.py --- bindings/python/setup.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/bindings/python/setup.py b/bindings/python/setup.py index 25b42883..98b94ad2 100755 --- a/bindings/python/setup.py +++ b/bindings/python/setup.py @@ -254,6 +254,24 @@ except ImportError: def join_all(src, files): return tuple(os.path.join(src, f) for f in files) +long_desc = ''' +Unicorn is a lightweight, multi-platform, multi-architecture CPU emulator framework +based on [QEMU](http://qemu.org). + +Unicorn offers some unparalleled features: + +- Multi-architecture: ARM, ARM64 (ARMv8), M68K, MIPS, SPARC, and X86 (16, 32, 64-bit) +- Clean/simple/lightweight/intuitive architecture-neutral API +- Implemented in pure C language, with bindings for Crystal, Clojure, Visual Basic, Perl, Rust, Ruby, Python, Java, .NET, Go, Delphi/Free Pascal, Haskell, Pharo, and Lua. +- Native support for Windows & *nix (with Mac OSX, Linux, *BSD & Solaris confirmed) +- High performance via Just-In-Time compilation +- Support for fine-grained instrumentation at various levels +- Thread-safety by design +- Distributed under free software license GPLv2 + +Further information is available at http://www.unicorn-engine.org +''' + setup( provides=['unicorn'], packages=['unicorn'], @@ -262,6 +280,8 @@ setup( author='Nguyen Anh Quynh', author_email='aquynh@gmail.com', description='Unicorn CPU emulator engine', + long_description=long_desc, + long_description_content_type="text/markdown", url='http://www.unicorn-engine.org', classifiers=[ 'License :: OSI Approved :: BSD License', From 582e6968fdd37507ce0e063d3fb61bd150c1b7bd Mon Sep 17 00:00:00 2001 From: scribam Date: Sun, 31 May 2020 18:00:07 +0200 Subject: [PATCH 06/44] cmake: add option to build unicorn as a static library (#1275) --- CMakeLists.txt | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e7b05b3..d6c39bd3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,8 @@ set(UNICORN_VERSION_MAJOR 1) set(UNICORN_VERSION_MINOR 0) set(UNICORN_VERSION_PATCH 2) +option(UNICORN_BUILD_SHARED "Build shared instead of static library" ON) + if(NOT UNICORN_ARCH) # build all architectures set(UNICORN_ARCH "x86 arm aarch64 m68k mips sparc") @@ -830,9 +832,15 @@ else() ) endif() -add_library(unicorn SHARED - ${UNICORN_SRCS} -) +if (UNICORN_BUILD_SHARED) + add_library(unicorn SHARED + ${UNICORN_SRCS} + ) +else() + add_library(unicorn STATIC + ${UNICORN_SRCS} + ) +endif() if (UNICORN_HAS_X86) set(UNICRON_COMPILE_OPTIONS ${UNICRON_COMPILE_OPTIONS} -DUNICORN_HAS_X86) @@ -865,19 +873,21 @@ if (UNICORN_HAS_SPARC) set(UNICRON_SAMPLE_FILE ${UNICRON_SAMPLE_FILE} sample_sparc) endif() +target_compile_options(unicorn PRIVATE + ${UNICRON_COMPILE_OPTIONS} +) if(MSVC) - target_compile_options(unicorn PRIVATE - ${UNICRON_COMPILE_OPTIONS} - -DUNICORN_SHARED - ) + if (UNICORN_BUILD_SHARED) + target_compile_options(unicorn PRIVATE + -DUNICORN_SHARED + ) + endif() + target_link_libraries(unicorn ${UNICRON_LINK_LIBRARIES} ) else() - target_compile_options(unicorn PRIVATE - ${UNICRON_COMPILE_OPTIONS} - ) target_link_libraries(unicorn ${UNICRON_LINK_LIBRARIES} m From db3235a65b0c5cf3c74d2a0c753e76fabff24ca6 Mon Sep 17 00:00:00 2001 From: scribam Date: Tue, 2 Jun 2020 10:04:33 +0200 Subject: [PATCH 07/44] cmake: fix Visual Studio build (#1276) --- CMakeLists.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d6c39bd3..049c537b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -297,7 +297,7 @@ add_library(x86_64-softmmu if(MSVC) target_compile_options(x86_64-softmmu PRIVATE -DNEED_CPU_H - /FI x86_64.h + /FIx86_64.h /I${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/x86_64-softmmu /I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target-i386 ) @@ -340,7 +340,7 @@ add_library(arm-softmmu if(MSVC) target_compile_options(arm-softmmu PRIVATE -DNEED_CPU_H - /FI arm.h + /FIarm.h /I${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/arm-softmmu /I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target-arm ) @@ -381,7 +381,7 @@ add_library(armeb-softmmu if(MSVC) target_compile_options(armeb-softmmu PRIVATE -DNEED_CPU_H - /FI armeb.h + /FIarmeb.h /I${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/armeb-softmmu /I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target-arm ) @@ -427,7 +427,7 @@ add_library(aarch64-softmmu if(MSVC) target_compile_options(aarch64-softmmu PRIVATE -DNEED_CPU_H - /FI aarch64.h + /FIaarch64.h /I${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/aarch64-softmmu /I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target-arm ) @@ -471,7 +471,7 @@ add_library(aarch64eb-softmmu if(MSVC) target_compile_options(aarch64eb-softmmu PRIVATE -DNEED_CPU_H - /FI aarch64eb.h + /FIaarch64eb.h /I${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/aarch64eb-softmmu /I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target-arm ) @@ -509,7 +509,7 @@ add_library(m68k-softmmu if(MSVC) target_compile_options(m68k-softmmu PRIVATE -DNEED_CPU_H - /FI m68k.h + /FIm68k.h /I${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/m68k-softmmu /I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target-m68k ) @@ -552,7 +552,7 @@ add_library(mips-softmmu if(MSVC) target_compile_options(mips-softmmu PRIVATE -DNEED_CPU_H - /FI mips.h + /FImips.h /I${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/mips-softmmu /I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target-mips ) @@ -593,7 +593,7 @@ add_library(mipsel-softmmu if(MSVC) target_compile_options(mipsel-softmmu PRIVATE -DNEED_CPU_H - /FI mipsel.h + /FImipsel.h /I${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/mipsel-softmmu /I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target-mips ) @@ -634,7 +634,7 @@ add_library(mips64-softmmu if(MSVC) target_compile_options(mips64-softmmu PRIVATE -DNEED_CPU_H - /FI mips64.h + /FImips64.h /I${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/mips64-softmmu /I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target-mips ) @@ -675,7 +675,7 @@ add_library(mips64el-softmmu if(MSVC) target_compile_options(mips64el-softmmu PRIVATE -DNEED_CPU_H - /FI mips64el.h + /FImips64el.h /I${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/mips64el-softmmu /I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target-mips ) @@ -718,7 +718,7 @@ add_library(sparc-softmmu if(MSVC) target_compile_options(sparc-softmmu PRIVATE -DNEED_CPU_H - /FI sparc.h + /FIsparc.h /I${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/sparc-softmmu /I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target-sparc ) @@ -760,7 +760,7 @@ add_library(sparc64-softmmu if(MSVC) target_compile_options(sparc64-softmmu PRIVATE -DNEED_CPU_H - /FI sparc64.h + /FIsparc64.h /I${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/sparc64-softmmu /I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target-sparc ) From 5508d3aa32a44f29c79a09b2ba5d5b13b45ae02b Mon Sep 17 00:00:00 2001 From: scribam Date: Wed, 3 Jun 2020 04:13:32 +0200 Subject: [PATCH 08/44] cmake: fix typo "UNICRON" => "UNICORN" (#1277) --- CMakeLists.txt | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 049c537b..c09a3044 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -843,38 +843,38 @@ else() endif() if (UNICORN_HAS_X86) - set(UNICRON_COMPILE_OPTIONS ${UNICRON_COMPILE_OPTIONS} -DUNICORN_HAS_X86) - set(UNICRON_LINK_LIBRARIES ${UNICRON_LINK_LIBRARIES} x86_64-softmmu) - set(UNICRON_SAMPLE_FILE ${UNICRON_SAMPLE_FILE} sample_x86 sample_x86_32_gdt_and_seg_regs sample_batch_reg mem_apis shellcode) + set(UNICORN_COMPILE_OPTIONS ${UNICORN_COMPILE_OPTIONS} -DUNICORN_HAS_X86) + set(UNICORN_LINK_LIBRARIES ${UNICORN_LINK_LIBRARIES} x86_64-softmmu) + set(UNICORN_SAMPLE_FILE ${UNICORN_SAMPLE_FILE} sample_x86 sample_x86_32_gdt_and_seg_regs sample_batch_reg mem_apis shellcode) endif() if (UNICORN_HAS_ARM) - set(UNICRON_COMPILE_OPTIONS ${UNICRON_COMPILE_OPTIONS} -DUNICORN_HAS_ARM) - set(UNICRON_LINK_LIBRARIES ${UNICRON_LINK_LIBRARIES} arm-softmmu armeb-softmmu) - set(UNICRON_SAMPLE_FILE ${UNICRON_SAMPLE_FILE} sample_arm sample_armeb) + set(UNICORN_COMPILE_OPTIONS ${UNICORN_COMPILE_OPTIONS} -DUNICORN_HAS_ARM) + set(UNICORN_LINK_LIBRARIES ${UNICORN_LINK_LIBRARIES} arm-softmmu armeb-softmmu) + set(UNICORN_SAMPLE_FILE ${UNICORN_SAMPLE_FILE} sample_arm sample_armeb) endif() if (UNICORN_HAS_AARCH64) - set(UNICRON_COMPILE_OPTIONS ${UNICRON_COMPILE_OPTIONS} -DUNICORN_HAS_ARM64) - set(UNICRON_LINK_LIBRARIES ${UNICRON_LINK_LIBRARIES} aarch64-softmmu aarch64eb-softmmu) - set(UNICRON_SAMPLE_FILE ${UNICRON_SAMPLE_FILE} sample_arm64 sample_arm64eb) + set(UNICORN_COMPILE_OPTIONS ${UNICORN_COMPILE_OPTIONS} -DUNICORN_HAS_ARM64) + set(UNICORN_LINK_LIBRARIES ${UNICORN_LINK_LIBRARIES} aarch64-softmmu aarch64eb-softmmu) + set(UNICORN_SAMPLE_FILE ${UNICORN_SAMPLE_FILE} sample_arm64 sample_arm64eb) endif() if (UNICORN_HAS_M68K) - set(UNICRON_COMPILE_OPTIONS ${UNICRON_COMPILE_OPTIONS} -DUNICORN_HAS_M68K) - set(UNICRON_LINK_LIBRARIES ${UNICRON_LINK_LIBRARIES} m68k-softmmu) - set(UNICRON_SAMPLE_FILE ${UNICRON_SAMPLE_FILE} sample_m68k) + set(UNICORN_COMPILE_OPTIONS ${UNICORN_COMPILE_OPTIONS} -DUNICORN_HAS_M68K) + set(UNICORN_LINK_LIBRARIES ${UNICORN_LINK_LIBRARIES} m68k-softmmu) + set(UNICORN_SAMPLE_FILE ${UNICORN_SAMPLE_FILE} sample_m68k) endif() if (UNICORN_HAS_MIPS) - set(UNICRON_COMPILE_OPTIONS ${UNICRON_COMPILE_OPTIONS} -DUNICORN_HAS_MIPS -DUNICORN_HAS_MIPSEL -DUNICORN_HAS_MIPS64 -DUNICORN_HAS_MIPS64EL) - set(UNICRON_LINK_LIBRARIES ${UNICRON_LINK_LIBRARIES} mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu) - set(UNICRON_SAMPLE_FILE ${UNICRON_SAMPLE_FILE} sample_mips) + set(UNICORN_COMPILE_OPTIONS ${UNICORN_COMPILE_OPTIONS} -DUNICORN_HAS_MIPS -DUNICORN_HAS_MIPSEL -DUNICORN_HAS_MIPS64 -DUNICORN_HAS_MIPS64EL) + set(UNICORN_LINK_LIBRARIES ${UNICORN_LINK_LIBRARIES} mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu) + set(UNICORN_SAMPLE_FILE ${UNICORN_SAMPLE_FILE} sample_mips) endif() if (UNICORN_HAS_SPARC) - set(UNICRON_COMPILE_OPTIONS ${UNICRON_COMPILE_OPTIONS} -DUNICORN_HAS_SPARC) - set(UNICRON_LINK_LIBRARIES ${UNICRON_LINK_LIBRARIES} sparc-softmmu sparc64-softmmu) - set(UNICRON_SAMPLE_FILE ${UNICRON_SAMPLE_FILE} sample_sparc) + set(UNICORN_COMPILE_OPTIONS ${UNICORN_COMPILE_OPTIONS} -DUNICORN_HAS_SPARC) + set(UNICORN_LINK_LIBRARIES ${UNICORN_LINK_LIBRARIES} sparc-softmmu sparc64-softmmu) + set(UNICORN_SAMPLE_FILE ${UNICORN_SAMPLE_FILE} sample_sparc) endif() target_compile_options(unicorn PRIVATE - ${UNICRON_COMPILE_OPTIONS} + ${UNICORN_COMPILE_OPTIONS} ) if(MSVC) @@ -885,11 +885,11 @@ if(MSVC) endif() target_link_libraries(unicorn - ${UNICRON_LINK_LIBRARIES} + ${UNICORN_LINK_LIBRARIES} ) else() target_link_libraries(unicorn - ${UNICRON_LINK_LIBRARIES} + ${UNICORN_LINK_LIBRARIES} m ) set_target_properties(unicorn PROPERTIES @@ -909,7 +909,7 @@ else() ) endif() -foreach(SAMPLE_FILE ${UNICRON_SAMPLE_FILE}) +foreach(SAMPLE_FILE ${UNICORN_SAMPLE_FILE}) add_executable(${SAMPLE_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/samples/${SAMPLE_FILE}.c ) From 605cfe8e02b55a3ce76f119ccd395528bb371480 Mon Sep 17 00:00:00 2001 From: John Zimmermann Date: Thu, 4 Jun 2020 00:38:40 -0700 Subject: [PATCH 09/44] cmake: fix static linking due to cyclic deps (#1278) linking of samples like sample_arm do fail due to cyclic references in the archives --- CMakeLists.txt | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c09a3044..2ec62e5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ set(UNICORN_VERSION_PATCH 2) option(UNICORN_BUILD_SHARED "Build shared instead of static library" ON) -if(NOT UNICORN_ARCH) +if (NOT UNICORN_ARCH) # build all architectures set(UNICORN_ARCH "x86 arm aarch64 m68k mips sparc") endif() @@ -293,6 +293,9 @@ add_library(x86_64-softmmu qemu/tcg/tcg.c qemu/translate-all.c ) +if (NOT UNICORN_BUILD_SHARED) + target_link_libraries(x86_64-softmmu unicorn) +endif() if(MSVC) target_compile_options(x86_64-softmmu PRIVATE @@ -336,6 +339,9 @@ add_library(arm-softmmu qemu/tcg/tcg.c qemu/translate-all.c ) +if (NOT UNICORN_BUILD_SHARED) + target_link_libraries(arm-softmmu unicorn) +endif() if(MSVC) target_compile_options(arm-softmmu PRIVATE @@ -377,6 +383,9 @@ add_library(armeb-softmmu qemu/tcg/tcg.c qemu/translate-all.c ) +if (NOT UNICORN_BUILD_SHARED) + target_link_libraries(armeb-softmmu unicorn) +endif() if(MSVC) target_compile_options(armeb-softmmu PRIVATE @@ -423,6 +432,9 @@ add_library(aarch64-softmmu qemu/tcg/tcg.c qemu/translate-all.c ) +if (NOT UNICORN_BUILD_SHARED) + target_link_libraries(aarch64-softmmu unicorn) +endif() if(MSVC) target_compile_options(aarch64-softmmu PRIVATE @@ -467,6 +479,9 @@ add_library(aarch64eb-softmmu qemu/tcg/tcg.c qemu/translate-all.c ) +if (NOT UNICORN_BUILD_SHARED) + target_link_libraries(aarch64eb-softmmu unicorn) +endif() if(MSVC) target_compile_options(aarch64eb-softmmu PRIVATE @@ -505,6 +520,9 @@ add_library(m68k-softmmu qemu/tcg/tcg.c qemu/translate-all.c ) +if (NOT UNICORN_BUILD_SHARED) + target_link_libraries(m68k-softmmu unicorn) +endif() if(MSVC) target_compile_options(m68k-softmmu PRIVATE @@ -548,6 +566,9 @@ add_library(mips-softmmu qemu/tcg/tcg.c qemu/translate-all.c ) +if (NOT UNICORN_BUILD_SHARED) + target_link_libraries(mips-softmmu unicorn) +endif() if(MSVC) target_compile_options(mips-softmmu PRIVATE @@ -589,6 +610,9 @@ add_library(mipsel-softmmu qemu/tcg/tcg.c qemu/translate-all.c ) +if (NOT UNICORN_BUILD_SHARED) + target_link_libraries(mipsel-softmmu unicorn) +endif() if(MSVC) target_compile_options(mipsel-softmmu PRIVATE @@ -630,6 +654,9 @@ add_library(mips64-softmmu qemu/tcg/tcg.c qemu/translate-all.c ) +if (NOT UNICORN_BUILD_SHARED) + target_link_libraries(mips64-softmmu unicorn) +endif() if(MSVC) target_compile_options(mips64-softmmu PRIVATE @@ -671,6 +698,9 @@ add_library(mips64el-softmmu qemu/tcg/tcg.c qemu/translate-all.c ) +if (NOT UNICORN_BUILD_SHARED) + target_link_libraries(mips64el-softmmu unicorn) +endif() if(MSVC) target_compile_options(mips64el-softmmu PRIVATE @@ -714,6 +744,9 @@ add_library(sparc-softmmu qemu/tcg/tcg.c qemu/translate-all.c ) +if (NOT UNICORN_BUILD_SHARED) + target_link_libraries(sparc-softmmu unicorn) +endif() if(MSVC) target_compile_options(sparc-softmmu PRIVATE @@ -756,6 +789,9 @@ add_library(sparc64-softmmu qemu/tcg/tcg.c qemu/translate-all.c ) +if (NOT UNICORN_BUILD_SHARED) + target_link_libraries(sparc64-softmmu unicorn) +endif() if(MSVC) target_compile_options(sparc64-softmmu PRIVATE From 10f0562796869a0df03ad7efed7a948d3c0f77f3 Mon Sep 17 00:00:00 2001 From: chfl4gs <55137784+chfl4gs@users.noreply.github.com> Date: Thu, 4 Jun 2020 15:40:11 +0800 Subject: [PATCH 10/44] Adding Travis-CI cmake static (#1279) --- .travis.yml | 63 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 75da008b..79cb6576 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,8 @@ script: cyg-get.bat default autoconf automake make gcc-core clang pkg-config libpcre-devel cmake python27-setuptools ruby wget && \ export SHELLOPTS && set -o igncr \ cmd.exe //C "C:\\tools\\cygwin\\bin\\bash.exe -lc 'cd /cygdrive/$TRAVIS_BUILD_DIR; make header; make; ./install-cmocka-linux.sh; export PATH="$PATH":/cygdrive/$TRAVIS_BUILD_DIR:/cygdrive/$TRAVIS_BUILD_DIR/cmocka/src; make test'" + elif [[ "$TRAVIS_CPU_ARCH" == "arm64" ]]; then + make header && make && make -C tests/unit test && make -C tests/regress test else make header && make && make -C bindings/go && make -C bindings/go test && make test fi @@ -18,27 +20,17 @@ os: - linux - osx - windows +arch: + - amd64 + - arm64 matrix: fast_finish: true + exclude: + - os: windows + arch: arm64 + - os: osx + arch: arm64 include: - - name: "Linux arm64 clang C" - arch: arm64 - os: linux - compiler: clang - language: c - env: - - PATH=$PATH:/usr/local/opt/binutils/bin - script: make header && make && make -C tests/unit test && make -C tests/regress test - - - name: "Linux arm64 gcc C" - arch: arm64 - os: linux - compiler: gcc - language: c - env: - - PATH=$PATH:/usr/local/opt/binutils/bin - script: make header && make && make -C tests/unit test && make -C tests/regress test - - name: "Linux clang ASAN" os: linux compiler: clang @@ -125,6 +117,41 @@ matrix: - cp libunicorn.* ../ - make -C ../tests/unit test && make -C ../tests/regress test + - name: "Linux Cmake Static 32bit" + os: linux + compiler: gcc + env: + - CFLAGS="-m32" LDFLAGS="-m32" LDFLAGS_STATIC="-m32" UNICORN_QEMU_FLAGS="--cpu=i386" + - PATH=$PATH:/usr/local/opt/binutils/bin + script: + - mkdir build + - cd build + - cmake -DCMAKE_BUILD_TYPE=Release -DUNICORN_ARCH=x86 -DUNICORN_BUILD_SHARED=OFF .. && make -j8 + - cp libunicorn.* ../ + - make -C ../tests/unit test && make -C ../tests/regress test + addons: + apt: + packages: + - lib32ncurses5-dev + - lib32z1-dev + - libpthread-stubs0-dev + - lib32gcc-4.8-dev + - libc6-dev-i386 + - gcc-multilib + - libcmocka-dev:i386 + + - name: "Linux Cmake Static 64bit" + os: linux + compiler: gcc + env: + - PATH=$PATH:/usr/local/opt/binutils/bin + script: + - mkdir build + - cd build + - cmake -DCMAKE_BUILD_TYPE=Release -DUNICORN_BUILD_SHARED=OFF .. && make -j8 + - cp libunicorn.* ../ + - make -C ../tests/unit test && make -C ../tests/regress test + - name: "MacOSX brew" os: osx osx_image: xcode10.1 From ad80f042c4f9635f704b0244216137abfaea0b1f Mon Sep 17 00:00:00 2001 From: scribam Date: Fri, 5 Jun 2020 04:27:41 +0200 Subject: [PATCH 11/44] cmake: add ARCHIVE rule to the install command (#1282) --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ec62e5b..e1cb27ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -959,6 +959,7 @@ if(NOT MSVC) file(GLOB UNICORN_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/unicorn/*.h) install(TARGETS unicorn RUNTIME DESTINATION bin + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install(FILES ${UNICORN_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/unicorn) From a4784cc96c71e51235044d42c860a840083ad1c8 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 5 Jun 2020 04:30:23 +0200 Subject: [PATCH 12/44] fix error handling of mmap() calls (#1283) --- qemu/exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu/exec.c b/qemu/exec.c index e6923862..9e4fa5d1 100644 --- a/qemu/exec.c +++ b/qemu/exec.c @@ -1154,7 +1154,7 @@ void qemu_ram_remap(struct uc_struct *uc, ram_addr_t addr, ram_addr_t length) area = mmap(vaddr, length, PROT_READ | PROT_WRITE, flags, -1, 0); } - if (area != vaddr) { + if (area == MAP_FAILED || area != vaddr) { fprintf(stderr, "Could not remap addr: " RAM_ADDR_FMT "@" RAM_ADDR_FMT "\n", length, addr); From 2e0f753e6f9411901dce1e6779b0bcdd57d13c09 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 5 Jun 2020 20:12:44 +0800 Subject: [PATCH 13/44] save cpu->jmp_env in saving context, so uc_emu_start() can be reentrant. also improved Python binding on handling context --- bindings/python/unicorn/unicorn.py | 31 +++++++++++++++--------------- include/uc_priv.h | 6 ++++-- qemu/cpu-exec.c | 8 ++------ qemu/cpus.c | 2 ++ uc.c | 18 ++++++++++------- 5 files changed, 34 insertions(+), 31 deletions(-) diff --git a/bindings/python/unicorn/unicorn.py b/bindings/python/unicorn/unicorn.py index 40fccce0..7b8f49be 100644 --- a/bindings/python/unicorn/unicorn.py +++ b/bindings/python/unicorn/unicorn.py @@ -596,15 +596,12 @@ class Uc(object): h = 0 def context_save(self): - size = _uc.uc_context_size(self._uch) - - context = context_factory(size) - - status = _uc.uc_context_save(self._uch, ctypes.byref(context)) + context = UcContext(self._uch) + status = _uc.uc_context_save(self._uch, context.context) if status != uc.UC_ERR_OK: raise UcError(status) - return ctypes.string_at(ctypes.byref(context), ctypes.sizeof(context)) + return context def context_update(self, context): status = _uc.uc_context_save(self._uch, context) @@ -612,7 +609,7 @@ class Uc(object): raise UcError(status) def context_restore(self, context): - status = _uc.uc_context_restore(self._uch, context) + status = _uc.uc_context_restore(self._uch, context.context) if status != uc.UC_ERR_OK: raise UcError(status) @@ -631,15 +628,17 @@ class Uc(object): _uc.uc_free(regions) -def context_factory(size): - class SavedContext(ctypes.Structure): - _fields_ = [ - ('size', ctypes.c_size_t), - ('data', ctypes.c_char*size) - ] - ctxt = SavedContext() - ctxt.size = size - return ctxt +class UcContext(ctypes.Structure): + def __init__(self, h): + self.context = uc_context() + + status = _uc.uc_context_alloc(h, ctypes.byref(self.context)) + if status != uc.UC_ERR_OK: + raise UcError(status) + + def __del__(self): + _uc.uc_free(self.context) + # print out debugging info def debug(): diff --git a/include/uc_priv.h b/include/uc_priv.h index ef8be62c..80288187 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -253,9 +253,11 @@ struct uc_struct { }; // Metadata stub for the variable-size cpu context used with uc_context_*() +// We also save cpu->jmp_env, so emulation can be reentrant struct uc_context { - size_t size; - char data[0]; + size_t context_size; // size of the real internal context structure + unsigned int jmp_env_size; // size of cpu->jmp_env + char data[0]; // context + cpu->jmp_env }; // check if this address is mapped in (via uc_mem_map()) diff --git a/qemu/cpu-exec.c b/qemu/cpu-exec.c index 7da6e3f4..b4aa4bf0 100644 --- a/qemu/cpu-exec.c +++ b/qemu/cpu-exec.c @@ -39,13 +39,9 @@ void cpu_loop_exit(CPUState *cpu) /* exit the current TB from a signal handler. The host registers are restored in a state compatible with the CPU emulator */ -#if defined(CONFIG_SOFTMMU) - void cpu_resume_from_signal(CPUState *cpu, void *puc) { -#endif /* XXX: restore cpu registers saved in host registers */ - cpu->exception_index = -1; siglongjmp(cpu->jmp_env, 1); } @@ -66,7 +62,6 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq uintptr_t next_tb; struct hook *hook; - if (cpu->halted) { if (!cpu_has_work(cpu)) { return EXCP_HALTED; @@ -306,7 +301,8 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq tb_flush(env); /* fail safe : never use current_cpu outside cpu_exec() */ - uc->current_cpu = NULL; + // uc->current_cpu = NULL; + return ret; } diff --git a/qemu/cpus.c b/qemu/cpus.c index 0035e222..28509d54 100644 --- a/qemu/cpus.c +++ b/qemu/cpus.c @@ -71,6 +71,8 @@ int resume_all_vcpus(struct uc_struct *uc) return -1; } + cpu->exit_request = 0; + //qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true); cpu_resume(cpu); qemu_tcg_cpu_loop(uc); diff --git a/uc.c b/uc.c index 038c7803..3e2f7dc9 100644 --- a/uc.c +++ b/uc.c @@ -1323,9 +1323,10 @@ uc_err uc_context_alloc(uc_engine *uc, uc_context **context) struct uc_context **_context = context; size_t size = cpu_context_size(uc->arch, uc->mode); - *_context = malloc(size + sizeof(uc_context)); + *_context = malloc(size); if (*_context) { - (*_context)->size = size; + (*_context)->jmp_env_size = sizeof(*uc->cpu->jmp_env); + (*_context)->context_size = size - sizeof(uc_context) - (*_context)->jmp_env_size; return UC_ERR_OK; } else { return UC_ERR_NOMEM; @@ -1342,21 +1343,24 @@ uc_err uc_free(void *mem) UNICORN_EXPORT size_t uc_context_size(uc_engine *uc) { - return cpu_context_size(uc->arch, uc->mode); + // return the total size of struct uc_context + return sizeof(uc_context) + cpu_context_size(uc->arch, uc->mode) + sizeof(*uc->cpu->jmp_env); } UNICORN_EXPORT uc_err uc_context_save(uc_engine *uc, uc_context *context) { - struct uc_context *_context = context; - memcpy(_context->data, uc->cpu->env_ptr, _context->size); + memcpy(context->data, uc->cpu->env_ptr, context->context_size); + memcpy(context->data + context->context_size, uc->cpu->jmp_env, context->jmp_env_size); + return UC_ERR_OK; } UNICORN_EXPORT uc_err uc_context_restore(uc_engine *uc, uc_context *context) { - struct uc_context *_context = context; - memcpy(uc->cpu->env_ptr, _context->data, _context->size); + memcpy(uc->cpu->env_ptr, context->data, context->context_size); + memcpy(uc->cpu->jmp_env, context->data + context->context_size, context->jmp_env_size); + return UC_ERR_OK; } From 9288b4a845a1ce08cc086ad399608bc311d9aeac Mon Sep 17 00:00:00 2001 From: chfl4gs <55137784+chfl4gs@users.noreply.github.com> Date: Sat, 6 Jun 2020 12:53:31 +0800 Subject: [PATCH 14/44] adding pypi workflow (#1280) * adding pypi workflow * PyPI distribution packages workflow --- .github/workflows/python-publish.yml | 60 ++++++++++++++++++++++++++++ bindings/python/build_wheel.sh | 14 +++++++ bindings/python/setup.py | 50 ++++++++++------------- 3 files changed, 96 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/python-publish.yml create mode 100755 bindings/python/build_wheel.sh diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml new file mode 100644 index 00000000..028c193e --- /dev/null +++ b/.github/workflows/python-publish.yml @@ -0,0 +1,60 @@ +name: PyPI 📦 Distribution + +on: [push] + +jobs: + deploy: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [windows-latest, macos-latest, ubuntu-latest] + platform: [x32, x64] + steps: + - uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Set up MSVC + if: matrix.os == 'windows-latest' + uses: microsoft/setup-msbuild@v1 + + - name: Install dependencies + run: | + pip install setuptools wheel + + - name: Build distribution 📦 + shell: bash + run: | + if [ ${{ matrix.platform }} == 'x32' ] && [ ${{ matrix.os }} == 'windows-latest' ]; then + cd bindings/python && python setup.py build -p win32 sdist bdist_wheel -p win32 + rm dist/*.tar.gz + elif [ ${{ matrix.platform }} == 'x32' ] && [ ${{ matrix.os }} == 'ubuntu-latest' ]; then + docker run --rm -v `pwd`/:/work dockcross/manylinux1-x86 > ./dockcross + chmod +x ./dockcross + ./dockcross bindings/python/build_wheel.sh + elif [ ${{ matrix.platform }} == 'x64' ] && [ ${{ matrix.os }} == 'ubuntu-latest' ]; then + docker run --rm -v `pwd`/:/work dockcross/manylinux1-x64 > ./dockcross + chmod +x ./dockcross + ./dockcross bindings/python/build_wheel.sh + elif [ ${{ matrix.platform }} == 'x32' ] && [ ${{ matrix.os }} == 'macos-latest' ]; then + cd bindings/python && python setup.py sdist + else + cd bindings/python && python setup.py bdist_wheel + fi + + - uses: actions/upload-artifact@v2 + with: + name: unicorn-packages-${{ matrix.os }}-${{ matrix.platform }} + path: ${{ github.workspace }}/bindings/python/dist/* + + - name: Publish distribution 📦 to PyPI + if: startsWith(github.event.ref, 'refs/tags') + uses: pypa/gh-action-pypi-publish@master + with: + username: __token__ + password: ${{ secrets.pypi_pass }} + packages_dir: ${{ github.workspace }}/bindings/python/dist/ diff --git a/bindings/python/build_wheel.sh b/bindings/python/build_wheel.sh new file mode 100755 index 00000000..e3c9d444 --- /dev/null +++ b/bindings/python/build_wheel.sh @@ -0,0 +1,14 @@ +#!/bin/bash +set -e -x + +cd bindings/python + +# Compile wheels +if [ -f /opt/python/cp36-cp36m/bin/python ];then + /opt/python/cp36-cp36m/bin/python setup.py bdist_wheel +else + python3 setup.py bdist_wheel +fi +cd dist +auditwheel repair *.whl +mv -f wheelhouse/*.whl . diff --git a/bindings/python/setup.py b/bindings/python/setup.py index 98b94ad2..d261c7c7 100755 --- a/bindings/python/setup.py +++ b/bindings/python/setup.py @@ -15,6 +15,7 @@ from distutils.util import get_platform from distutils.command.build import build from distutils.command.sdist import sdist from setuptools.command.bdist_egg import bdist_egg +from setuptools.command.develop import develop SYSTEM = sys.platform @@ -22,7 +23,7 @@ SYSTEM = sys.platform IS_64BITS = platform.architecture()[0] == '64bit' # are we building from the repository or from a source distribution? -ROOT_DIR = os.path.dirname(os.path.realpath(__file__)) +ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) LIBS_DIR = os.path.join(ROOT_DIR, 'unicorn', 'lib') HEADERS_DIR = os.path.join(ROOT_DIR, 'unicorn', 'include') SRC_DIR = os.path.join(ROOT_DIR, 'src') @@ -140,16 +141,22 @@ def build_libraries(): os.chdir(BUILD_DIR) try: - subprocess.check_call(['msbuild', '/help']) + subprocess.check_call(['msbuild', '-ver']) except: has_msbuild = False else: has_msbuild = True if has_msbuild and SYSTEM == 'win32': - plat = 'Win32' if platform.architecture()[0] == '32bit' else 'x64' + if platform.architecture()[0] == '32bit': + plat = 'Win32' + elif 'win32' in sys.argv: + plat = 'Win32' + else: + plat = 'x64' + conf = 'Debug' if os.getenv('DEBUG', '') else 'Release' - subprocess.call(['msbuild', '-m', '-p:Platform=' + plat, '-p:Configuration=' + conf], cwd=os.path.join(BUILD_DIR, 'msvc')) + subprocess.call(['msbuild', 'unicorn.sln', '-m', '-p:Platform=' + plat, '-p:Configuration=' + conf], cwd=os.path.join(BUILD_DIR, 'msvc')) obj_dir = os.path.join(BUILD_DIR, 'msvc', plat, conf) shutil.copy(os.path.join(obj_dir, LIBRARY_FILE), LIBS_DIR) @@ -191,7 +198,6 @@ def build_libraries(): sys.exit(1) os.chdir(cwd) - class custom_sdist(sdist): def run(self): clean_bins() @@ -207,6 +213,12 @@ class custom_build(build): build_libraries() return build.run(self) +class custom_develop(develop): + def run(self): + log.info("Building C extensions") + build_libraries() + return develop.run(self) + class custom_bdist_egg(bdist_egg): def run(self): self.run_command('build') @@ -215,10 +227,6 @@ class custom_bdist_egg(bdist_egg): def dummy_src(): return [] -cmdclass = {} -cmdclass['build'] = custom_build -cmdclass['sdist'] = custom_sdist -cmdclass['bdist_egg'] = custom_bdist_egg if 'bdist_wheel' in sys.argv and '--plat-name' not in sys.argv: idx = sys.argv.index('bdist_wheel') + 1 @@ -239,24 +247,10 @@ if 'bdist_wheel' in sys.argv and '--plat-name' not in sys.argv: # https://www.python.org/dev/peps/pep-0425/ sys.argv.insert(idx + 1, name.replace('.', '_').replace('-', '_')) -try: - from setuptools.command.develop import develop - class custom_develop(develop): - def run(self): - log.info("Building C extensions") - build_libraries() - return develop.run(self) - - cmdclass['develop'] = custom_develop -except ImportError: - print("Proper 'develop' support unavailable.") - -def join_all(src, files): - return tuple(os.path.join(src, f) for f in files) long_desc = ''' Unicorn is a lightweight, multi-platform, multi-architecture CPU emulator framework -based on [QEMU](http://qemu.org). +based on [QEMU](https://qemu.org). Unicorn offers some unparalleled features: @@ -269,7 +263,7 @@ Unicorn offers some unparalleled features: - Thread-safety by design - Distributed under free software license GPLv2 -Further information is available at http://www.unicorn-engine.org +Further information is available at https://www.unicorn-engine.org ''' setup( @@ -282,17 +276,17 @@ setup( description='Unicorn CPU emulator engine', long_description=long_desc, long_description_content_type="text/markdown", - url='http://www.unicorn-engine.org', + url='https://www.unicorn-engine.org', classifiers=[ 'License :: OSI Approved :: BSD License', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 3', ], requires=['ctypes'], - cmdclass=cmdclass, + cmdclass={'build': custom_build, 'develop': custom_develop, 'sdist': custom_sdist, 'bdist_egg': custom_bdist_egg}, zip_safe=True, include_package_data=True, - is_pure=True, + is_pure=False, package_data={ 'unicorn': ['lib/*', 'include/unicorn/*'] } From 590bab8f1aeb7838238ec76fa709f9fde74a926c Mon Sep 17 00:00:00 2001 From: John Zimmermann Date: Fri, 5 Jun 2020 21:54:06 -0700 Subject: [PATCH 15/44] cmake: fix build if workdir is outside of CMAKE_BINARY_DIR (#1284) this e.g. happens if you would try to compile this like this: cmake -B build cmake --build build --config Release --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e1cb27ab..59a1e695 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -186,6 +186,7 @@ else() execute_process(COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/qemu/configure ${EXTRA_CFLAGS} ${TARGET_LIST} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) execute_process(COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/qemu/scripts/create_config INPUT_FILE ${CMAKE_BINARY_DIR}/config-host.mak From 535143ae5abdeb69151173559bb3eb79924413d9 Mon Sep 17 00:00:00 2001 From: chfl4gs <55137784+chfl4gs@users.noreply.github.com> Date: Sun, 7 Jun 2020 01:09:30 +0800 Subject: [PATCH 16/44] Fixing minor typo on PyPI distribution workflow (#1286) * Adding Travis-CI cmake static * Fix minor typo on PyPI workflow config --- .github/workflows/python-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index 028c193e..35ce5fb1 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -55,6 +55,6 @@ jobs: if: startsWith(github.event.ref, 'refs/tags') uses: pypa/gh-action-pypi-publish@master with: - username: __token__ + user: __token__ password: ${{ secrets.pypi_pass }} packages_dir: ${{ github.workspace }}/bindings/python/dist/ From 7ea04acbdcc51423c42488aba67efcd7f8960706 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Sun, 7 Jun 2020 11:22:18 +0800 Subject: [PATCH 17/44] fix some uninitialized vars in fpu --- qemu/fpu/softfloat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qemu/fpu/softfloat.c b/qemu/fpu/softfloat.c index 3bc69662..d1031ba8 100644 --- a/qemu/fpu/softfloat.c +++ b/qemu/fpu/softfloat.c @@ -368,7 +368,7 @@ static float32 roundAndPackFloat32(flag zSign, int_fast16_t zExp, uint32_t zSig { int8 roundingMode; flag roundNearestEven; - int8 roundIncrement, roundBits; + int8 roundIncrement = 0, roundBits; flag isTiny; roundingMode = STATUS(float_rounding_mode); @@ -553,7 +553,7 @@ static float64 roundAndPackFloat64(flag zSign, int_fast16_t zExp, uint64_t zSig { int8 roundingMode; flag roundNearestEven; - int_fast16_t roundIncrement, roundBits; + int_fast16_t roundIncrement = 0, roundBits; flag isTiny; roundingMode = STATUS(float_rounding_mode); @@ -726,7 +726,7 @@ static floatx80 STATUS_PARAM) { int8 roundingMode; - flag roundNearestEven, increment, isTiny; + flag roundNearestEven, increment = 0, isTiny; int64 roundIncrement, roundMask, roundBits; roundingMode = STATUS(float_rounding_mode); @@ -1064,7 +1064,7 @@ static float128 flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1, uint64_t zSig2 STATUS_PARAM) { int8 roundingMode; - flag roundNearestEven, increment, isTiny; + flag roundNearestEven, increment = 0, isTiny; roundingMode = STATUS(float_rounding_mode); roundNearestEven = ( roundingMode == float_round_nearest_even ); From 564ae2b14aa12c08ed0d5155a662126fa6c92e9b Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Wed, 10 Jun 2020 17:56:01 +0800 Subject: [PATCH 18/44] python: correct a comment on hooking on sample_arm64.py. fix #1292 --- bindings/python/sample_arm64.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/sample_arm64.py b/bindings/python/sample_arm64.py index 4b92f098..0f9550b5 100755 --- a/bindings/python/sample_arm64.py +++ b/bindings/python/sample_arm64.py @@ -45,7 +45,7 @@ def test_arm64(): # tracing all basic blocks with customized callback mu.hook_add(UC_HOOK_BLOCK, hook_block) - # tracing all instructions with customized callback + # tracing one instruction at ADDRESS with customized callback mu.hook_add(UC_HOOK_CODE, hook_code, begin=ADDRESS, end=ADDRESS) # emulate machine code in infinite time From a8a6a3fa9a6a2bf2da223668b10f0662dc5014ae Mon Sep 17 00:00:00 2001 From: chfl4gs <55137784+chfl4gs@users.noreply.github.com> Date: Sun, 14 Jun 2020 01:46:10 +0800 Subject: [PATCH 19/44] PyPI test check (#1296) * Adding Travis-CI cmake static * adding pypi test --- .github/workflows/python-publish.yml | 33 ++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index 35ce5fb1..11d9e68b 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -3,7 +3,7 @@ name: PyPI 📦 Distribution on: [push] jobs: - deploy: + build: runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -48,13 +48,28 @@ jobs: - uses: actions/upload-artifact@v2 with: - name: unicorn-packages-${{ matrix.os }}-${{ matrix.platform }} path: ${{ github.workspace }}/bindings/python/dist/* - - name: Publish distribution 📦 to PyPI - if: startsWith(github.event.ref, 'refs/tags') - uses: pypa/gh-action-pypi-publish@master - with: - user: __token__ - password: ${{ secrets.pypi_pass }} - packages_dir: ${{ github.workspace }}/bindings/python/dist/ + publish: + needs: [build] + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags') + steps: + - uses: actions/download-artifact@v2 + with: + name: artifact + path: dist + + - name: Publish distribution 📦 to test PyPI + uses: pypa/gh-action-pypi-publish@master + with: + user: __token__ + password: ${{ secrets.testpypi_pass }} + repository_url: https://test.pypi.org/legacy/ + + - name: Publish distribution 📦 to PyPI + if: ${{ success() }} + uses: pypa/gh-action-pypi-publish@master + with: + user: __token__ + password: ${{ secrets.pypi_pass }} From 3134f3302981298e8c53ef6b000959c31c6818af Mon Sep 17 00:00:00 2001 From: liangjs <761232680@qq.com> Date: Sun, 28 Jun 2020 01:43:14 +0800 Subject: [PATCH 20/44] fix 64-bit fstenv (#1300) * fix 64-bit fstenv * fix fstenv --- qemu/target-i386/fpu_helper.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/qemu/target-i386/fpu_helper.c b/qemu/target-i386/fpu_helper.c index 5de7e2ef..f121175c 100644 --- a/qemu/target-i386/fpu_helper.c +++ b/qemu/target-i386/fpu_helper.c @@ -1008,16 +1008,7 @@ void helper_fstenv(CPUX86State *env, target_ulong ptr, int data32) } } - // DFLAG enum: tcg.h, case here to int - if (env->hflags & HF_CS64_MASK) { - cpu_stl_data(env, ptr, env->fpuc); - cpu_stl_data(env, ptr + 4, fpus); - cpu_stl_data(env, ptr + 8, fptag); - cpu_stl_data(env, ptr + 12, (uint32_t)env->fpip); /* fpip */ - cpu_stl_data(env, ptr + 20, 0); /* fpcs */ - cpu_stl_data(env, ptr + 24, 0); /* fpoo */ - cpu_stl_data(env, ptr + 28, 0); /* fpos */ - } else if (data32) { + if (data32) { /* 32 bit */ cpu_stl_data(env, ptr, env->fpuc); cpu_stl_data(env, ptr + 4, fpus); From a9025c58a47d985dd0cec10344b5f33ded1ac51c Mon Sep 17 00:00:00 2001 From: h01G3r <63418746+h01G3r@users.noreply.github.com> Date: Thu, 20 Aug 2020 17:24:04 +0200 Subject: [PATCH 21/44] fixes an issue with ARM APSR register handling: (#1317) - Q flag / GE flag were not included in APSR register (read/write) - UC_ARM_REG_APSR_NZCV register constant was ignored completely. - regression test added --- qemu/target-arm/unicorn_arm.c | 6 ++++++ tests/regress/arm_apsr_access.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tests/regress/arm_apsr_access.py diff --git a/qemu/target-arm/unicorn_arm.c b/qemu/target-arm/unicorn_arm.c index 0e1b1828..d5b9a7d9 100644 --- a/qemu/target-arm/unicorn_arm.c +++ b/qemu/target-arm/unicorn_arm.c @@ -69,6 +69,9 @@ int arm_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun else { switch(regid) { case UC_ARM_REG_APSR: + *(int32_t *)value = cpsr_read(&ARM_CPU(uc, mycpu)->env) & (CPSR_NZCV | CPSR_Q | CPSR_GE); + break; + case UC_ARM_REG_APSR_NZCV: *(int32_t *)value = cpsr_read(&ARM_CPU(uc, mycpu)->env) & CPSR_NZCV; break; case UC_ARM_REG_CPSR: @@ -132,6 +135,9 @@ int arm_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, i else { switch(regid) { case UC_ARM_REG_APSR: + cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, (CPSR_NZCV | CPSR_Q | CPSR_GE)); + break; + case UC_ARM_REG_APSR_NZCV: cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, CPSR_NZCV); break; case UC_ARM_REG_CPSR: diff --git a/tests/regress/arm_apsr_access.py b/tests/regress/arm_apsr_access.py new file mode 100644 index 00000000..33c10fd9 --- /dev/null +++ b/tests/regress/arm_apsr_access.py @@ -0,0 +1,30 @@ +#!/usr/bin/python + +from unicorn import * +from unicorn.arm_const import * + +import regress + +class APSRAccess(regress.RegressTest): + + def runTest(self): + code = ( + b'\x00\x00\xa0\xe1' + # 0: mov r0, r0 + b'\x08\x10\x9f\xe5' + # 4: ldr r1, [pc, #8] + b'\x01\xf0\x28\xe1' + # 8: 01 f0 28 e1 msr apsr_nzcvq, r1 + b'\x00\x00\xa0\xe1' + # c: mov r0, r0 + b'\x00\x00\xa0\xe1' + # 10: mov r0, r0 + b'\x00\x00\x00\xff') # 14: data for inst @4 + + uc = Uc(UC_ARCH_ARM, UC_MODE_ARM) + uc.mem_map(0x1000, 0x1000) + uc.mem_write(0x1000, code) # bxeq lr; mov r0, r0 + + uc.reg_write(UC_ARM_REG_APSR, 0) + uc.emu_start(0x1000, 0x100c) + + self.assertEqual(uc.reg_read(UC_ARM_REG_APSR), 0xf8000000) + self.assertEqual(uc.reg_read(UC_ARM_REG_APSR_NZCV), 0xf0000000) + +if __name__ == '__main__': + regress.main() From c03f50f76a683488afc633cb31be6b9253d37ebf Mon Sep 17 00:00:00 2001 From: chfl4gs <55137784+chfl4gs@users.noreply.github.com> Date: Thu, 10 Sep 2020 10:01:13 +0800 Subject: [PATCH 22/44] Fixing installation on cygwin, Travis-ci cache adjustment (#1322) * Adding Travis-CI cmake static * fix 64-bit fstenv (#1300) * fix 64-bit fstenv * fix fstenv * safe_zip to false and travis adjustment * Fixed zip_safe and cygwin setup Co-authored-by: liangjs <761232680@qq.com> --- .travis.yml | 104 +++++++++++++++++++++++++++++---------- bindings/python/setup.py | 14 +++--- 2 files changed, 84 insertions(+), 34 deletions(-) diff --git a/.travis.yml b/.travis.yml index 79cb6576..c08466b8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,10 +4,17 @@ env: script: - | if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then - choco install cygwin cyg-get && \ - cyg-get.bat default autoconf automake make gcc-core clang pkg-config libpcre-devel cmake python27-setuptools ruby wget && \ - export SHELLOPTS && set -o igncr \ - cmd.exe //C "C:\\tools\\cygwin\\bin\\bash.exe -lc 'cd /cygdrive/$TRAVIS_BUILD_DIR; make header; make; ./install-cmocka-linux.sh; export PATH="$PATH":/cygdrive/$TRAVIS_BUILD_DIR:/cygdrive/$TRAVIS_BUILD_DIR/cmocka/src; make test'" + if [[ "$TRAVIS_COMPILER" == "clang" ]]; then + choco install cygwin cyg-get && \ + cyg-get.bat default autoconf automake make gcc-core clang pkg-config libpcre-devel cmake python27-setuptools ruby wget && \ + export SHELLOPTS && set -o igncr && \ + cmd.exe //C "C:\\tools\\cygwin\\bin\\bash.exe -lc 'cd /cygdrive/$TRAVIS_BUILD_DIR; make header; make'" + else + choco install cygwin cyg-get && \ + cyg-get.bat default autoconf automake make gcc-core clang pkg-config libpcre-devel cmake python27-setuptools ruby wget && \ + export SHELLOPTS && set -o igncr && \ + cmd.exe //C "C:\\tools\\cygwin\\bin\\bash.exe -lc 'cd /cygdrive/$TRAVIS_BUILD_DIR; make header; make; ./install-cmocka-linux.sh; export PATH="$PATH":/cygdrive/$TRAVIS_BUILD_DIR:/cygdrive/$TRAVIS_BUILD_DIR/cmocka/src; make test'" + fi elif [[ "$TRAVIS_CPU_ARCH" == "arm64" ]]; then make header && make && make -C tests/unit test && make -C tests/regress test else @@ -18,7 +25,6 @@ compiler: - gcc os: - linux - - osx - windows arch: - amd64 @@ -28,9 +34,44 @@ matrix: exclude: - os: windows arch: arm64 - - os: osx - arch: arm64 include: + + - name: "Compiler: clang C" + os: osx + osx_image: xcode10.1 + python: 3.7 + compiler: clang + before_cache: + - brew cleanup + - find /usr/local/Homebrew \! -regex ".+\.git.+" -delete; + cache: + directories: + - $HOME/Library/Caches/Homebrew + - /usr/local/Homebrew + before_install: + - cd /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core && git stash && git clean -d -f + script: + - cd $TRAVIS_BUILD_DIR + - make header && make && make -C bindings/go && make -C bindings/go test && make test + + - name: "Compiler: gcc C" + os: osx + osx_image: xcode10.1 + python: 3.7 + compiler: gcc + before_cache: + - brew cleanup + - find /usr/local/Homebrew \! -regex ".+\.git.+" -delete; + cache: + directories: + - $HOME/Library/Caches/Homebrew + - /usr/local/Homebrew + before_install: + - cd /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core && git stash && git clean -d -f + script: + - cd $TRAVIS_BUILD_DIR + - make header && make && make -C bindings/go && make -C bindings/go test && make test + - name: "Linux clang ASAN" os: linux compiler: clang @@ -40,7 +81,9 @@ matrix: - CXXFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -fsanitize=fuzzer-no-link" - CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -fsanitize=fuzzer-no-link" - LDFLAGS="-fsanitize=address" - script: make header && make && make -C tests/fuzz && sh tests/fuzz/dlcorpus.sh + script: + - make header && make + - make -C tests/fuzz && sh tests/fuzz/dlcorpus.sh - name: "Linux clang MSAN" os: linux @@ -51,7 +94,9 @@ matrix: - CXXFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=memory -fsanitize=fuzzer-no-link" - CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=memory -fsanitize=fuzzer-no-link" - LDFLAGS="-fsanitize=memory" - script: make header && make && make -C tests/fuzz && sh tests/fuzz/dlcorpus.sh + script: + - make header && make + - make -C tests/fuzz && sh tests/fuzz/dlcorpus.sh - name: "Linux clang USAN" os: linux @@ -62,7 +107,9 @@ matrix: - CXXFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=undefined -fsanitize=fuzzer-no-link" - CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=undefined -fsanitize=fuzzer-no-link" - LDFLAGS="-fsanitize=undefined" - script: make header && make && make -C tests/fuzz && sh tests/fuzz/dlcorpus.sh + script: + - make header && make + - make -C tests/fuzz && sh tests/fuzz/dlcorpus.sh - name: "Linux 32bit" os: linux @@ -127,8 +174,9 @@ matrix: - mkdir build - cd build - cmake -DCMAKE_BUILD_TYPE=Release -DUNICORN_ARCH=x86 -DUNICORN_BUILD_SHARED=OFF .. && make -j8 - - cp libunicorn.* ../ - - make -C ../tests/unit test && make -C ../tests/regress test +# temporarily disable test for static build +# - cp libunicorn.* ../ +# - make -C ../tests/unit test && make -C ../tests/regress test addons: apt: packages: @@ -149,8 +197,8 @@ matrix: - mkdir build - cd build - cmake -DCMAKE_BUILD_TYPE=Release -DUNICORN_BUILD_SHARED=OFF .. && make -j8 - - cp libunicorn.* ../ - - make -C ../tests/unit test && make -C ../tests/regress test +# - cp libunicorn.* ../ +# - make -C ../tests/unit test && make -C ../tests/regress test - name: "MacOSX brew" os: osx @@ -241,12 +289,14 @@ matrix: - export LDFLAGS="-m32" - export LDFLAGS_STATIC="-m32" - export UNICORN_QEMU_FLAGS="--cpu=i386" - before_cache: - - $msys2 pacman --sync --clean --noconfirm - cache: - directories: - - $HOME/AppData/Local/Temp/chocolatey - - /C/tools/msys64 +# before_cache: +# - $msys2 pacman --sync --clean --noconfirm +# cache: +# timeout: +# 1000 +# directories: +# - $HOME/AppData/Local/Temp/chocolatey +# - /C/tools/msys64 script: - $shell make header; $shell make; cp unicorn.dll /C/Windows/SysWOW64/; $shell make test @@ -283,12 +333,14 @@ matrix: - export CC=x86_64-w64-mingw32-gcc - export AR=gcc-ar - export RANLIB=gcc-ranlib - before_cache: - - $msys2 pacman --sync --clean --noconfirm - cache: - directories: - - $HOME/AppData/Local/Temp/chocolatey - - /C/tools/msys64 +# before_cache: +# - $msys2 pacman --sync --clean --noconfirm +# cache: +# timeout: +# 1000 +# directories: +# - $HOME/AppData/Local/Temp/chocolatey +# - /C/tools/msys64 script: - $shell make header; $shell make; cp unicorn.dll /C/Windows/System32/; $shell make test addons: diff --git a/bindings/python/setup.py b/bindings/python/setup.py index d261c7c7..836dab80 100755 --- a/bindings/python/setup.py +++ b/bindings/python/setup.py @@ -63,9 +63,12 @@ if SYSTEM == 'darwin': LIBRARY_FILE = "libunicorn.dylib" MAC_LIBRARY_FILE = "libunicorn*.dylib" STATIC_LIBRARY_FILE = None -elif SYSTEM in ('win32', 'cygwin'): +elif SYSTEM == 'win32': LIBRARY_FILE = "unicorn.dll" STATIC_LIBRARY_FILE = "unicorn.lib" +elif SYSTEM == 'cygwin': + LIBRARY_FILE = "cygunicorn.dll" + STATIC_LIBRARY_FILE = None else: LIBRARY_FILE = "libunicorn.so" STATIC_LIBRARY_FILE = None @@ -166,12 +169,7 @@ def build_libraries(): new_env = dict(os.environ) new_env['UNICORN_BUILD_CORE_ONLY'] = 'yes' cmd = ['sh', './make.sh'] - if SYSTEM == "cygwin": - if IS_64BITS: - cmd.append('cygwin-mingw64') - else: - cmd.append('cygwin-mingw32') - elif SYSTEM == "win32": + if SYSTEM == "win32": if IS_64BITS: cmd.append('cross-win64') else: @@ -284,7 +282,7 @@ setup( ], requires=['ctypes'], cmdclass={'build': custom_build, 'develop': custom_develop, 'sdist': custom_sdist, 'bdist_egg': custom_bdist_egg}, - zip_safe=True, + zip_safe=False, include_package_data=True, is_pure=False, package_data={ From c1c0baec7d85ed34064ca361846bcb46e3ef34a3 Mon Sep 17 00:00:00 2001 From: lazymio Date: Thu, 10 Sep 2020 10:02:22 +0800 Subject: [PATCH 23/44] Fix IP value for UC_MODE_16 (#1321) --- qemu/target-i386/unicorn.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qemu/target-i386/unicorn.c b/qemu/target-i386/unicorn.c index 7c4ca998..9ab5dd22 100644 --- a/qemu/target-i386/unicorn.c +++ b/qemu/target-i386/unicorn.c @@ -27,7 +27,12 @@ const int X86_REGS_STORAGE_SIZE = offsetof(CPUX86State, tlb_table); static void x86_set_pc(struct uc_struct *uc, uint64_t address) { - ((CPUX86State *)uc->current_cpu->env_ptr)->eip = address; + CPUState* cpu = uc->cpu; + int16_t cs = (uint16_t)X86_CPU(uc, cpu)->env.segs[R_CS].selector; + if(uc->mode == UC_MODE_16) + ((CPUX86State *)uc->current_cpu->env_ptr)->eip = address - cs*16; + else + ((CPUX86State *)uc->current_cpu->env_ptr)->eip = address; } void x86_release(void *ctx); From abe452babc13299f598a47f7c87873a4ae34bf09 Mon Sep 17 00:00:00 2001 From: Sunho Kim Date: Thu, 10 Sep 2020 11:03:36 +0900 Subject: [PATCH 24/44] Fix enabled hooks even after deleting them (#1315) --- include/uc_priv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uc_priv.h b/include/uc_priv.h index 80288187..833a4238 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -127,7 +127,7 @@ enum uc_hook_idx { // if statement to check hook bounds #define HOOK_BOUND_CHECK(hh, addr) \ ((((addr) >= (hh)->begin && (addr) <= (hh)->end) \ - || (hh)->begin > (hh)->end)) + || (hh)->begin > (hh)->end) && !((hh)->to_delete)) #define HOOK_EXISTS(uc, idx) ((uc)->hook[idx##_IDX].head != NULL) #define HOOK_EXISTS_BOUNDED(uc, idx, addr) _hook_exists_bounded((uc)->hook[idx##_IDX].head, addr) From 748aceb7601d1de24e922afa3a80b68ab62802d2 Mon Sep 17 00:00:00 2001 From: mogoreanu Date: Wed, 16 Sep 2020 02:09:10 -0700 Subject: [PATCH 25/44] Add qemu_ prefix to bitmap_set and bitmap_clear to avoid conflicts. (#1326) When unicorn and systemd are combined into a single binary the 2 libraries conflict on bitmap_set and bitmap_clear functions which breaks unicorn. Co-authored-by: Nicolae Mogoreanu --- qemu/include/exec/ram_addr.h | 4 ++-- qemu/include/qemu/bitmap.h | 10 +++++----- qemu/util/bitmap.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/qemu/include/exec/ram_addr.h b/qemu/include/exec/ram_addr.h index a4c9007c..5e614e59 100644 --- a/qemu/include/exec/ram_addr.h +++ b/qemu/include/exec/ram_addr.h @@ -93,7 +93,7 @@ static inline void cpu_physical_memory_set_dirty_range(struct uc_struct *uc, ram end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS; page = start >> TARGET_PAGE_BITS; - bitmap_set(uc->ram_list.dirty_memory[DIRTY_MEMORY_CODE], page, end - page); + qemu_bitmap_set(uc->ram_list.dirty_memory[DIRTY_MEMORY_CODE], page, end - page); } #if !defined(_WIN32) @@ -153,7 +153,7 @@ static inline void cpu_physical_memory_clear_dirty_range(struct uc_struct *uc, r assert(client < DIRTY_MEMORY_NUM); end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS; page = start >> TARGET_PAGE_BITS; - bitmap_clear(uc->ram_list.dirty_memory[client], page, end - page); + qemu_bitmap_clear(uc->ram_list.dirty_memory[client], page, end - page); } void cpu_physical_memory_reset_dirty(struct uc_struct *uc, diff --git a/qemu/include/qemu/bitmap.h b/qemu/include/qemu/bitmap.h index 89b6b34d..b8faee8d 100644 --- a/qemu/include/qemu/bitmap.h +++ b/qemu/include/qemu/bitmap.h @@ -26,8 +26,8 @@ * Note that nbits should be always a compile time evaluable constant. * Otherwise many inlines will generate horrible code. * - * bitmap_set(dst, pos, nbits) Set specified bit area - * bitmap_clear(dst, pos, nbits) Clear specified bit area + * qemu_bitmap_set(dst, pos, nbits) Set specified bit area + * qemu_bitmap_clear(dst, pos, nbits) Clear specified bit area */ /* @@ -46,15 +46,15 @@ #define DECLARE_BITMAP(name,bits) \ unsigned long name[BITS_TO_LONGS(bits)] -void bitmap_set(unsigned long *map, long i, long len); -void bitmap_clear(unsigned long *map, long start, long nr); +void qemu_bitmap_set(unsigned long *map, long i, long len); +void qemu_bitmap_clear(unsigned long *map, long start, long nr); static inline unsigned long *bitmap_zero_extend(unsigned long *old, long old_nbits, long new_nbits) { long new_len = BITS_TO_LONGS(new_nbits) * sizeof(unsigned long); unsigned long *new = g_realloc(old, new_len); - bitmap_clear(new, old_nbits, new_nbits - old_nbits); + qemu_bitmap_clear(new, old_nbits, new_nbits - old_nbits); return new; } diff --git a/qemu/util/bitmap.c b/qemu/util/bitmap.c index 96bbabc8..f6b9cdc1 100644 --- a/qemu/util/bitmap.c +++ b/qemu/util/bitmap.c @@ -14,7 +14,7 @@ #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG)) -void bitmap_set(unsigned long *map, long start, long nr) +void qemu_bitmap_set(unsigned long *map, long start, long nr) { unsigned long *p = map + BIT_WORD(start); const long size = start + nr; @@ -34,7 +34,7 @@ void bitmap_set(unsigned long *map, long start, long nr) } } -void bitmap_clear(unsigned long *map, long start, long nr) +void qemu_bitmap_clear(unsigned long *map, long start, long nr) { unsigned long *p = map + BIT_WORD(start); const long size = start + nr; From b1459f7554fd029a4a40b3136e226d4cb87463d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=98=83=20Stephen=20Shkardoon=20=E2=98=83?= Date: Mon, 21 Sep 2020 14:37:38 +1200 Subject: [PATCH 26/44] Fix failing test caused by removal of UC_ERR_TIMEOUT (#1305) Caused by fbef45b18f2f59d9699af54c6ad6ac73eaba3b29. Now the code assumes if it completes without an error, it was successful. --- bindings/python/sample_x86.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/bindings/python/sample_x86.py b/bindings/python/sample_x86.py index eeb64dd9..5c9c0d69 100755 --- a/bindings/python/sample_x86.py +++ b/bindings/python/sample_x86.py @@ -384,15 +384,8 @@ def test_i386_loop(): print(">>> EDX = 0x%x" %r_edx) except UcError as e: - # timeout is acceptable in this case - if e.errno == UC_ERR_TIMEOUT: - print(">>> Emulation done. Below is the CPU context") - r_ecx = mu.reg_read(UC_X86_REG_ECX) - r_edx = mu.reg_read(UC_X86_REG_EDX) - print(">>> ECX = 0x%x" %r_ecx) - print(">>> EDX = 0x%x" %r_edx) - else: - print("ERROR: %s" % e) + print("ERROR: %s" % e) + # Test X86 32 bit with IN/OUT instruction def test_i386_inout(): From 225f6f288929b24b3989ad6e033c7ba8a5364661 Mon Sep 17 00:00:00 2001 From: liangjs <761232680@qq.com> Date: Mon, 21 Sep 2020 10:39:00 +0800 Subject: [PATCH 27/44] Return 'indefinite integer value' for invalid SSE fp->int conversions (#1306) Merge from qemu commit 1e8a98b53867f61da9ca09f411288e2085d323c4. https://github.com/qemu/qemu/commit/1e8a98b53867f61da9ca09f411288e2085d323c4 --- qemu/target-i386/ops_sse.h | 88 ++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 28 deletions(-) diff --git a/qemu/target-i386/ops_sse.h b/qemu/target-i386/ops_sse.h index 45e5ce65..8a8cda91 100644 --- a/qemu/target-i386/ops_sse.h +++ b/qemu/target-i386/ops_sse.h @@ -710,102 +710,134 @@ void helper_cvtsq2sd(CPUX86State *env, XMMReg *d, uint64_t val) #endif /* float to integer */ + +/* + * x86 mandates that we return the indefinite integer value for the result + * of any float-to-integer conversion that raises the 'invalid' exception. + * Wrap the softfloat functions to get this behaviour. + */ +#define WRAP_FLOATCONV(RETTYPE, FN, FLOATTYPE, INDEFVALUE) \ + static inline RETTYPE x86_##FN(FLOATTYPE a, float_status *s) \ + { \ + int oldflags, newflags; \ + RETTYPE r; \ + \ + oldflags = get_float_exception_flags(s); \ + set_float_exception_flags(0, s); \ + r = FN(a, s); \ + newflags = get_float_exception_flags(s); \ + if (newflags & float_flag_invalid) { \ + r = INDEFVALUE; \ + } \ + set_float_exception_flags(newflags | oldflags, s); \ + return r; \ + } + +WRAP_FLOATCONV(int32_t, float32_to_int32, float32, INT32_MIN) +WRAP_FLOATCONV(int32_t, float32_to_int32_round_to_zero, float32, INT32_MIN) +WRAP_FLOATCONV(int32_t, float64_to_int32, float64, INT32_MIN) +WRAP_FLOATCONV(int32_t, float64_to_int32_round_to_zero, float64, INT32_MIN) +WRAP_FLOATCONV(int64_t, float32_to_int64, float32, INT64_MIN) +WRAP_FLOATCONV(int64_t, float32_to_int64_round_to_zero, float32, INT64_MIN) +WRAP_FLOATCONV(int64_t, float64_to_int64, float64, INT64_MIN) +WRAP_FLOATCONV(int64_t, float64_to_int64_round_to_zero, float64, INT64_MIN) + void helper_cvtps2dq(CPUX86State *env, XMMReg *d, XMMReg *s) { - d->XMM_L(0) = float32_to_int32(s->XMM_S(0), &env->sse_status); - d->XMM_L(1) = float32_to_int32(s->XMM_S(1), &env->sse_status); - d->XMM_L(2) = float32_to_int32(s->XMM_S(2), &env->sse_status); - d->XMM_L(3) = float32_to_int32(s->XMM_S(3), &env->sse_status); + d->XMM_L(0) = x86_float32_to_int32(s->XMM_S(0), &env->sse_status); + d->XMM_L(1) = x86_float32_to_int32(s->XMM_S(1), &env->sse_status); + d->XMM_L(2) = x86_float32_to_int32(s->XMM_S(2), &env->sse_status); + d->XMM_L(3) = x86_float32_to_int32(s->XMM_S(3), &env->sse_status); } void helper_cvtpd2dq(CPUX86State *env, XMMReg *d, XMMReg *s) { - d->XMM_L(0) = float64_to_int32(s->XMM_D(0), &env->sse_status); - d->XMM_L(1) = float64_to_int32(s->XMM_D(1), &env->sse_status); + d->XMM_L(0) = x86_float64_to_int32(s->XMM_D(0), &env->sse_status); + d->XMM_L(1) = x86_float64_to_int32(s->XMM_D(1), &env->sse_status); d->XMM_Q(1) = 0; } void helper_cvtps2pi(CPUX86State *env, MMXReg *d, XMMReg *s) { - d->MMX_L(0) = float32_to_int32(s->XMM_S(0), &env->sse_status); - d->MMX_L(1) = float32_to_int32(s->XMM_S(1), &env->sse_status); + d->MMX_L(0) = x86_float32_to_int32(s->XMM_S(0), &env->sse_status); + d->MMX_L(1) = x86_float32_to_int32(s->XMM_S(1), &env->sse_status); } void helper_cvtpd2pi(CPUX86State *env, MMXReg *d, XMMReg *s) { - d->MMX_L(0) = float64_to_int32(s->XMM_D(0), &env->sse_status); - d->MMX_L(1) = float64_to_int32(s->XMM_D(1), &env->sse_status); + d->MMX_L(0) = x86_float64_to_int32(s->XMM_D(0), &env->sse_status); + d->MMX_L(1) = x86_float64_to_int32(s->XMM_D(1), &env->sse_status); } int32_t helper_cvtss2si(CPUX86State *env, XMMReg *s) { - return float32_to_int32(s->XMM_S(0), &env->sse_status); + return x86_float32_to_int32(s->XMM_S(0), &env->sse_status); } int32_t helper_cvtsd2si(CPUX86State *env, XMMReg *s) { - return float64_to_int32(s->XMM_D(0), &env->sse_status); + return x86_float64_to_int32(s->XMM_D(0), &env->sse_status); } #ifdef TARGET_X86_64 int64_t helper_cvtss2sq(CPUX86State *env, XMMReg *s) { - return float32_to_int64(s->XMM_S(0), &env->sse_status); + return x86_float32_to_int64(s->XMM_S(0), &env->sse_status); } int64_t helper_cvtsd2sq(CPUX86State *env, XMMReg *s) { - return float64_to_int64(s->XMM_D(0), &env->sse_status); + return x86_float64_to_int64(s->XMM_D(0), &env->sse_status); } #endif /* float to integer truncated */ void helper_cvttps2dq(CPUX86State *env, XMMReg *d, XMMReg *s) { - d->XMM_L(0) = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status); - d->XMM_L(1) = float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status); - d->XMM_L(2) = float32_to_int32_round_to_zero(s->XMM_S(2), &env->sse_status); - d->XMM_L(3) = float32_to_int32_round_to_zero(s->XMM_S(3), &env->sse_status); + d->XMM_L(0) = x86_float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status); + d->XMM_L(1) = x86_float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status); + d->XMM_L(2) = x86_float32_to_int32_round_to_zero(s->XMM_S(2), &env->sse_status); + d->XMM_L(3) = x86_float32_to_int32_round_to_zero(s->XMM_S(3), &env->sse_status); } void helper_cvttpd2dq(CPUX86State *env, XMMReg *d, XMMReg *s) { - d->XMM_L(0) = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status); - d->XMM_L(1) = float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status); + d->XMM_L(0) = x86_float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status); + d->XMM_L(1) = x86_float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status); d->XMM_Q(1) = 0; } void helper_cvttps2pi(CPUX86State *env, MMXReg *d, XMMReg *s) { - d->MMX_L(0) = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status); - d->MMX_L(1) = float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status); + d->MMX_L(0) = x86_float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status); + d->MMX_L(1) = x86_float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status); } void helper_cvttpd2pi(CPUX86State *env, MMXReg *d, XMMReg *s) { - d->MMX_L(0) = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status); - d->MMX_L(1) = float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status); + d->MMX_L(0) = x86_float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status); + d->MMX_L(1) = x86_float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status); } int32_t helper_cvttss2si(CPUX86State *env, XMMReg *s) { - return float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status); + return x86_float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status); } int32_t helper_cvttsd2si(CPUX86State *env, XMMReg *s) { - return float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status); + return x86_float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status); } #ifdef TARGET_X86_64 int64_t helper_cvttss2sq(CPUX86State *env, XMMReg *s) { - return float32_to_int64_round_to_zero(s->XMM_S(0), &env->sse_status); + return x86_float32_to_int64_round_to_zero(s->XMM_S(0), &env->sse_status); } int64_t helper_cvttsd2sq(CPUX86State *env, XMMReg *s) { - return float64_to_int64_round_to_zero(s->XMM_D(0), &env->sse_status); + return x86_float64_to_int64_round_to_zero(s->XMM_D(0), &env->sse_status); } #endif From 644da9babca2df9c17b56e56c103d8de6a58a6bd Mon Sep 17 00:00:00 2001 From: lazymio Date: Tue, 22 Sep 2020 02:02:43 +0800 Subject: [PATCH 28/44] Fix setjmp/longjmp on native Windows (#1331) * Add setjmp wrapper * Add to projects * Use wrapper on x64 * Always build on x64 and exclude on win32 * Fix signature * Add comments * Add comments for os-win32.h * Add extern decleration * Support cmake Windows build * Fix for MinGW --- CMakeLists.txt | 4 +++ msvc/unicorn/unicorn/unicorn.vcxproj | 12 ++++++++- msvc/unicorn/unicorn/unicorn.vcxproj.filters | 3 +++ .../unicorn_static/unicorn_static.vcxproj | 12 ++++++++- .../unicorn_static.vcxproj.filters | 3 +++ qemu/include/sysemu/os-win32.h | 16 +++++++++++- qemu/util/setjmp-wrapper-win32.asm | 26 +++++++++++++++++++ 7 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 qemu/util/setjmp-wrapper-win32.asm diff --git a/CMakeLists.txt b/CMakeLists.txt index 59a1e695..696d070f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -859,6 +859,10 @@ if (MSVC) ${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/qapi-types.c ${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/qapi-visit.c ) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + enable_language(ASM_MASM) + set(UNICORN_SRCS ${UNICORN_SRCS} qemu/util/setjmp-wrapper-win32.asm) + endif() else() set(UNICORN_SRCS ${UNICORN_SRCS_COMMON} diff --git a/msvc/unicorn/unicorn/unicorn.vcxproj b/msvc/unicorn/unicorn/unicorn.vcxproj index 27f7762b..4b896c9e 100644 --- a/msvc/unicorn/unicorn/unicorn.vcxproj +++ b/msvc/unicorn/unicorn/unicorn.vcxproj @@ -53,6 +53,7 @@ + @@ -357,7 +358,16 @@ copy "$(SolutionDir)..\include\unicorn\*.h" "$(SolutionDir)distro\include\unicor + + + true + true + false + false + + + - + \ No newline at end of file diff --git a/msvc/unicorn/unicorn/unicorn.vcxproj.filters b/msvc/unicorn/unicorn/unicorn.vcxproj.filters index 149590fc..da3121fc 100644 --- a/msvc/unicorn/unicorn/unicorn.vcxproj.filters +++ b/msvc/unicorn/unicorn/unicorn.vcxproj.filters @@ -499,4 +499,7 @@ + + + \ No newline at end of file diff --git a/msvc/unicorn/unicorn_static/unicorn_static.vcxproj b/msvc/unicorn/unicorn_static/unicorn_static.vcxproj index 08d8cd02..57551e52 100644 --- a/msvc/unicorn/unicorn_static/unicorn_static.vcxproj +++ b/msvc/unicorn/unicorn_static/unicorn_static.vcxproj @@ -169,6 +169,14 @@ + + + true + true + false + false + + {B6EFD6D7-C2D4-4FBB-B363-2E08CE09CC96} Win32Proj @@ -204,6 +212,7 @@ + @@ -363,5 +372,6 @@ copy "$(SolutionDir)..\include\unicorn\*.h" "$(SolutionDir)distro\include\unicor + - + \ No newline at end of file diff --git a/msvc/unicorn/unicorn_static/unicorn_static.vcxproj.filters b/msvc/unicorn/unicorn_static/unicorn_static.vcxproj.filters index 8dd77e0a..121c3eee 100644 --- a/msvc/unicorn/unicorn_static/unicorn_static.vcxproj.filters +++ b/msvc/unicorn/unicorn_static/unicorn_static.vcxproj.filters @@ -498,4 +498,7 @@ qemu + + + \ No newline at end of file diff --git a/qemu/include/sysemu/os-win32.h b/qemu/include/sysemu/os-win32.h index 5d7b1d83..7825c310 100644 --- a/qemu/include/sysemu/os-win32.h +++ b/qemu/include/sysemu/os-win32.h @@ -56,13 +56,27 @@ # define EWOULDBLOCK WSAEWOULDBLOCK #endif -#if defined(_WIN64) && !defined(_MSC_VER) +#if defined(_WIN64) /* On w64, setjmp is implemented by _setjmp which needs a second parameter. * If this parameter is NULL, longjump does no stack unwinding. * That is what we need for QEMU. Passing the value of register rsp (default) * lets longjmp try a stack unwinding which will crash with generated code. */ + +#if defined(_MSC_VER) // MSVC + +// See qemu/include/utils/setjmp-wrapper-win32.asm for details. +extern int _setjmp_wrapper(jmp_buf); + +# undef setjmp +# define setjmp(env) _setjmp_wrapper(env) + +#else // MinGW + +// Original QEMU patch. # undef setjmp # define setjmp(env) _setjmp(env, NULL) +#endif + #endif /* QEMU uses sigsetjmp()/siglongjmp() as the portable way to specify * "longjmp and don't touch the signal masks". Since we know that the diff --git a/qemu/util/setjmp-wrapper-win32.asm b/qemu/util/setjmp-wrapper-win32.asm new file mode 100644 index 00000000..6e6b6ab9 --- /dev/null +++ b/qemu/util/setjmp-wrapper-win32.asm @@ -0,0 +1,26 @@ +EXTERN _setjmp: proc +PUBLIC _setjmp_wrapper + +_TEXT SEGMENT + +_setjmp_wrapper PROC + +; Why do we need this wrapper? +; Short answer: Windows default implementation of setjmp/longjmp is incompatible with generated code. +; A longer answer: https://blog.lazym.io/2020/09/21/Unicorn-Devblog-setjmp-longjmp-on-Windows/. + +; From qemu os-win32 comments: +; > On w64, setjmp is implemented by _setjmp which needs a second parameter. +; > If this parameter is NULL, longjump does no stack unwinding. +; > That is what we need for QEMU. Passing the value of register rsp (default) +; > lets longjmp try a stack unwinding which will crash with generated code. +; It's true indeed, but MSVC doesn't has a setjmp signature which receives two arguements. +; Therefore, we add a wrapper to keep the second argument zero. +xor rdx, rdx +jmp _setjmp + +_setjmp_wrapper ENDP + +_TEXT ENDS + +END \ No newline at end of file From 6c63235ebe8bdfb74eb504552087b95b6ed56d7a Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Tue, 22 Sep 2020 02:11:43 +0800 Subject: [PATCH 29/44] be ready for 1.0.2-rc5 --- ChangeLog | 16 ++++++++++++++++ pkgconfig.mk | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7e81b347..499c12d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,21 @@ This file details the changelog of Unicorn Engine. +------------------------------------ +[Version 1.0.2-rc5]: Sept 22th, 2020 + +- Add cmake option to build Unicorn as a static library +- Fix error handling of mmap() +- uc_emu_start() can be reentrant +- Fix naming conflicts when built with systemd +- Fix setjmp/longjmp on native Windows +- Fix enabled hooks even after deleting them +- X86: + - Fix 64bit fstenv + - Fix IP value of 16bit mode +- ARM: + - Fix APSR handling +- Python: Remove UC_ERR_TIMEOUT + ----------------------------------- [Version 1.0.2-rc4]: May 29th, 2020 diff --git a/pkgconfig.mk b/pkgconfig.mk index 8d9e14bd..c7953469 100644 --- a/pkgconfig.mk +++ b/pkgconfig.mk @@ -10,4 +10,4 @@ PKG_MINOR = 0 PKG_EXTRA = 2 # version tag. Examples: rc1, b2, post1 -PKG_TAG = rc4 +PKG_TAG = rc5 From 21235916b9f4f5853da2a24b74b3eed86195d607 Mon Sep 17 00:00:00 2001 From: chfl4gs <55137784+chfl4gs@users.noreply.github.com> Date: Tue, 22 Sep 2020 03:36:07 +0800 Subject: [PATCH 30/44] removing testpypi (#1332) * Adding Travis-CI cmake static * fix 64-bit fstenv (#1300) * fix 64-bit fstenv * fix fstenv * safe_zip to false and travis adjustment * Fixed zip_safe and cygwin setup * Removing testpypi Co-authored-by: liangjs <761232680@qq.com> --- .github/workflows/python-publish.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index 11d9e68b..7f0c1de2 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -60,15 +60,7 @@ jobs: name: artifact path: dist - - name: Publish distribution 📦 to test PyPI - uses: pypa/gh-action-pypi-publish@master - with: - user: __token__ - password: ${{ secrets.testpypi_pass }} - repository_url: https://test.pypi.org/legacy/ - - name: Publish distribution 📦 to PyPI - if: ${{ success() }} uses: pypa/gh-action-pypi-publish@master with: user: __token__ From 4441394258bf92f5e21fa3783f778623525764b8 Mon Sep 17 00:00:00 2001 From: lazymio Date: Thu, 24 Sep 2020 00:53:23 +0800 Subject: [PATCH 31/44] Fix context saving (#1335) * Fix context size * Make UcContext convertible to bytes and picklable Fix when updaing context * Test context pickling * Fix double free when the context is pickled from bytes --- bindings/python/sample_x86.py | 8 ++++++- bindings/python/unicorn/unicorn.py | 36 +++++++++++++++++++++++++----- uc.c | 4 ++-- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/bindings/python/sample_x86.py b/bindings/python/sample_x86.py index 5c9c0d69..25d947c1 100755 --- a/bindings/python/sample_x86.py +++ b/bindings/python/sample_x86.py @@ -4,7 +4,7 @@ from __future__ import print_function from unicorn import * from unicorn.x86_const import * - +import pickle X86_CODE32 = b"\x41\x4a\x66\x0f\xef\xc1" # INC ecx; DEC edx; PXOR xmm0, xmm1 X86_CODE32_LOOP = b"\x41\x4a\xeb\xfe" # INC ecx; DEC edx; JMP self-loop @@ -453,11 +453,17 @@ def test_i386_context_save(): print(">>> Saving CPU context") saved_context = mu.context_save() + print(">>> Pickling CPU context") + pickled_saved_context = pickle.dumps(saved_context) + print(">>> Running emulation for the second time") mu.emu_start(address, address+1) print(">>> Emulation done. Below is the CPU context") print(">>> EAX = 0x%x" %(mu.reg_read(UC_X86_REG_EAX))) + print(">>> Unpickling CPU context") + saved_context = pickle.loads(pickled_saved_context) + print(">>> CPU context restored. Below is the CPU context") mu.context_restore(saved_context) print(">>> EAX = 0x%x" %(mu.reg_read(UC_X86_REG_EAX))) diff --git a/bindings/python/unicorn/unicorn.py b/bindings/python/unicorn/unicorn.py index 7b8f49be..b97129e4 100644 --- a/bindings/python/unicorn/unicorn.py +++ b/bindings/python/unicorn/unicorn.py @@ -604,7 +604,7 @@ class Uc(object): return context def context_update(self, context): - status = _uc.uc_context_save(self._uch, context) + status = _uc.uc_context_save(self._uch, context.context) if status != uc.UC_ERR_OK: raise UcError(status) @@ -628,16 +628,40 @@ class Uc(object): _uc.uc_free(regions) -class UcContext(ctypes.Structure): +class UcContext: def __init__(self, h): - self.context = uc_context() - - status = _uc.uc_context_alloc(h, ctypes.byref(self.context)) + self._context = uc_context() + self._size = _uc.uc_context_size(h) + self._to_free = True + status = _uc.uc_context_alloc(h, ctypes.byref(self._context)) if status != uc.UC_ERR_OK: raise UcError(status) + + @property + def context(self): + return self._context + + @property + def size(self): + return self._size + + # Make UcContext picklable + def __getstate__(self): + return (bytes(self), self.size) + + def __setstate__(self, state): + self._size = state[1] + self._context = ctypes.cast(ctypes.create_string_buffer(state[0], self._size), uc_context) + # __init__ won'e be invoked, so we are safe to set it here. + self._to_free = False + + def __bytes__(self): + return ctypes.string_at(self.context, self.size) def __del__(self): - _uc.uc_free(self.context) + # We need this property since we shouldn't free it if the object is constructed from pickled bytes. + if self._to_free: + _uc.uc_free(self._context) # print out debugging info diff --git a/uc.c b/uc.c index 3e2f7dc9..f27a6a11 100644 --- a/uc.c +++ b/uc.c @@ -1321,12 +1321,12 @@ UNICORN_EXPORT uc_err uc_context_alloc(uc_engine *uc, uc_context **context) { struct uc_context **_context = context; - size_t size = cpu_context_size(uc->arch, uc->mode); + size_t size = uc_context_size(uc); *_context = malloc(size); if (*_context) { (*_context)->jmp_env_size = sizeof(*uc->cpu->jmp_env); - (*_context)->context_size = size - sizeof(uc_context) - (*_context)->jmp_env_size; + (*_context)->context_size = cpu_context_size(uc->arch, uc->mode); return UC_ERR_OK; } else { return UC_ERR_NOMEM; From 1044403d38368e0b575fce810fdc12cf0626256e Mon Sep 17 00:00:00 2001 From: lazymio Date: Thu, 24 Sep 2020 22:28:55 +0800 Subject: [PATCH 32/44] Implement uc_context_free (#1336) * Implement uc_context_free * Use uc_context_free for python bindings * Format code * Simplify code * Move next,context inside while loop * Add my name to CREDITS.TXT --- CREDITS.TXT | 1 + bindings/python/unicorn/unicorn.py | 3 ++- include/uc_priv.h | 4 +++- include/unicorn/unicorn.h | 22 ++++++++++++++++---- uc.c | 32 ++++++++++++++++++++++++++++-- 5 files changed, 54 insertions(+), 8 deletions(-) diff --git a/CREDITS.TXT b/CREDITS.TXT index db06ff6a..d10faf27 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -72,3 +72,4 @@ Philippe Antoine (Catena cyber): fuzzing Huitao Chen (chenhuitao) & KaiJern Lau (xwings): Cmake support Huitao Chen (chenhuitao) & KaiJern Lau (xwings): Python3 support for building Kevin Foo (chfl4gs): Travis-CI migration +Ziqiao Kong (lazymio): Various bug fix and improvement. \ No newline at end of file diff --git a/bindings/python/unicorn/unicorn.py b/bindings/python/unicorn/unicorn.py index b97129e4..7f76976c 100644 --- a/bindings/python/unicorn/unicorn.py +++ b/bindings/python/unicorn/unicorn.py @@ -139,6 +139,7 @@ _setup_prototype(_uc, "uc_free", ucerr, ctypes.c_void_p) _setup_prototype(_uc, "uc_context_save", ucerr, uc_engine, uc_context) _setup_prototype(_uc, "uc_context_restore", ucerr, uc_engine, uc_context) _setup_prototype(_uc, "uc_context_size", ctypes.c_size_t, uc_engine) +_setup_prototype(_uc, "uc_context_free", ucerr, uc_context) _setup_prototype(_uc, "uc_mem_regions", ucerr, uc_engine, ctypes.POINTER(ctypes.POINTER(_uc_mem_region)), ctypes.POINTER(ctypes.c_uint32)) # uc_hook_add is special due to variable number of arguments @@ -661,7 +662,7 @@ class UcContext: def __del__(self): # We need this property since we shouldn't free it if the object is constructed from pickled bytes. if self._to_free: - _uc.uc_free(self._context) + _uc.uc_context_free(self._context) # print out debugging info diff --git a/include/uc_priv.h b/include/uc_priv.h index 833a4238..77773b7d 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -250,13 +250,15 @@ struct uc_struct { uint32_t target_page_align; uint64_t next_pc; // save next PC for some special cases bool hook_insert; // insert new hook at begin of the hook list (append by default) + struct list saved_contexts; // The contexts saved by this uc_struct. }; // Metadata stub for the variable-size cpu context used with uc_context_*() // We also save cpu->jmp_env, so emulation can be reentrant struct uc_context { size_t context_size; // size of the real internal context structure - unsigned int jmp_env_size; // size of cpu->jmp_env + size_t jmp_env_size; // size of cpu->jmp_env + struct uc_struct* uc; // the uc_struct which creates this context char data[0]; // context + cpu->jmp_env }; diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index 6b415bb2..ab5485ed 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -707,10 +707,12 @@ UNICORN_EXPORT uc_err uc_context_alloc(uc_engine *uc, uc_context **context); /* - Free the memory allocated by uc_context_alloc & uc_mem_regions. + Free the memory allocated by uc_mem_regions. + WARNING: After Unicorn 1.0.1rc5, the memory allocated by uc_context_alloc should + be free-ed by uc_context_free(). Calling uc_free() may still work, but the result + is **undefined**. - @mem: memory allocated by uc_context_alloc (returned in *context), or - by uc_mem_regions (returned in *regions) + @mem: memory allocated by uc_mem_regions (returned in *regions). @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum for detailed error). @@ -738,7 +740,7 @@ uc_err uc_context_save(uc_engine *uc, uc_context *context); state saved by uc_context_save(). @uc: handle returned by uc_open() - @buffer: handle returned by uc_context_alloc that has been used with uc_context_save + @context: handle returned by uc_context_alloc that has been used with uc_context_save @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum for detailed error). @@ -758,6 +760,18 @@ uc_err uc_context_restore(uc_engine *uc, uc_context *context); UNICORN_EXPORT size_t uc_context_size(uc_engine *uc); + +/* + Free the context allocated by uc_context_alloc(). + + @context: handle returned by uc_context_alloc() + + @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum + for detailed error). +*/ +UNICORN_EXPORT +uc_err uc_context_free(uc_context *context); + #ifdef __cplusplus } #endif diff --git a/uc.c b/uc.c index f27a6a11..819b0bee 100644 --- a/uc.c +++ b/uc.c @@ -348,6 +348,16 @@ uc_err uc_close(uc_engine *uc) free(uc->mapped_blocks); + // free the saved contexts list and notify them that uc has been closed. + cur = uc->saved_contexts.head; + while (cur != NULL) { + struct list_item *next = cur->next; + struct uc_context *context = (struct uc_context*)cur->data; + context->uc = NULL; + cur = next; + } + list_clear(&uc->saved_contexts); + // finally, free uc itself. memset(uc, 0, sizeof(*uc)); free(uc); @@ -1327,7 +1337,12 @@ uc_err uc_context_alloc(uc_engine *uc, uc_context **context) if (*_context) { (*_context)->jmp_env_size = sizeof(*uc->cpu->jmp_env); (*_context)->context_size = cpu_context_size(uc->arch, uc->mode); - return UC_ERR_OK; + (*_context)->uc = uc; + if (list_insert(&uc->saved_contexts, *_context)) { + return UC_ERR_OK; + } else { + return UC_ERR_NOMEM; + } } else { return UC_ERR_NOMEM; } @@ -1360,7 +1375,20 @@ UNICORN_EXPORT uc_err uc_context_restore(uc_engine *uc, uc_context *context) { memcpy(uc->cpu->env_ptr, context->data, context->context_size); - memcpy(uc->cpu->jmp_env, context->data + context->context_size, context->jmp_env_size); + if (list_exists(&uc->saved_contexts, context)) { + memcpy(uc->cpu->jmp_env, context->data + context->context_size, context->jmp_env_size); + } return UC_ERR_OK; } + +UNICORN_EXPORT +uc_err uc_context_free(uc_context *context) +{ + uc_engine* uc = context->uc; + // if uc is NULL, it means that uc_engine has been free-ed. + if (uc) { + list_remove(&uc->saved_contexts, context); + } + return uc_free(context); +} \ No newline at end of file From 95e539f3e6c8d9c7cbc5f799f679acf81d2dcc65 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Thu, 24 Sep 2020 22:37:01 +0800 Subject: [PATCH 33/44] samples: make sample_x86.c to use uc_context_free() to free context (instead of uc_free()) --- samples/sample_x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/sample_x86.c b/samples/sample_x86.c index 1028504f..1b7ed33f 100644 --- a/samples/sample_x86.c +++ b/samples/sample_x86.c @@ -737,7 +737,7 @@ static void test_i386_context_save(void) printf(">>> EAX = 0x%x\n", r_eax); // free the CPU context - err = uc_free(context); + err = uc_context_free(context); if (err) { printf("Failed on uc_free() with error returned: %u\n", err); return; From 0291ac767595e8731009b4dbd1006171f98ecfcf Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Thu, 24 Sep 2020 22:37:59 +0800 Subject: [PATCH 34/44] update CREDITS.TXT --- CREDITS.TXT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CREDITS.TXT b/CREDITS.TXT index d10faf27..586d15ed 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -72,4 +72,4 @@ Philippe Antoine (Catena cyber): fuzzing Huitao Chen (chenhuitao) & KaiJern Lau (xwings): Cmake support Huitao Chen (chenhuitao) & KaiJern Lau (xwings): Python3 support for building Kevin Foo (chfl4gs): Travis-CI migration -Ziqiao Kong (lazymio): Various bug fix and improvement. \ No newline at end of file +Ziqiao Kong (lazymio): uc_context_free() API and various bug fix & improvement. From 198e432a1d7edbed6f4726acc42c50c3a4141b6b Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Thu, 24 Sep 2020 22:55:14 +0800 Subject: [PATCH 35/44] update Changelog for 1.0.2-rc6 --- ChangeLog | 8 +++++++- pkgconfig.mk | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 499c12d7..019c0b0a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,13 @@ This file details the changelog of Unicorn Engine. ------------------------------------ -[Version 1.0.2-rc5]: Sept 22th, 2020 +[Version 1.0.2-rc6]: Sept 24th, 2020 + +- Add uc_context_free() API +- Fix context saving/retoring API (core & Python binding) + +------------------------------------ +[Version 1.0.2-rc5]: Sept 22nd, 2020 - Add cmake option to build Unicorn as a static library - Fix error handling of mmap() diff --git a/pkgconfig.mk b/pkgconfig.mk index c7953469..13e3db63 100644 --- a/pkgconfig.mk +++ b/pkgconfig.mk @@ -10,4 +10,4 @@ PKG_MINOR = 0 PKG_EXTRA = 2 # version tag. Examples: rc1, b2, post1 -PKG_TAG = rc5 +PKG_TAG = rc6 From dbc6cc27c7c8d40e6061918c20ad513cae5da39f Mon Sep 17 00:00:00 2001 From: Brian Foley Date: Tue, 6 Oct 2020 20:42:14 -0700 Subject: [PATCH 36/44] Fix compile if HAS_ARM is defined but HAS_ARM_EB isn't (#1338) --- uc.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/uc.c b/uc.c index 819b0bee..eebce1fb 100644 --- a/uc.c +++ b/uc.c @@ -193,7 +193,11 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) return UC_ERR_MODE; } if (mode & UC_MODE_BIG_ENDIAN) { +#ifdef UNICORN_HAS_ARMEB uc->init_arch = armeb_uc_init; +#else + return UC_ERR_MODE; +#endif } else { uc->init_arch = arm_uc_init; } @@ -1299,7 +1303,13 @@ static size_t cpu_context_size(uc_arch arch, uc_mode mode) case UC_ARCH_X86: return X86_REGS_STORAGE_SIZE; #endif #ifdef UNICORN_HAS_ARM - case UC_ARCH_ARM: return mode & UC_MODE_BIG_ENDIAN ? ARM_REGS_STORAGE_SIZE_armeb : ARM_REGS_STORAGE_SIZE_arm; + case UC_ARCH_ARM: return mode & UC_MODE_BIG_ENDIAN ? +#ifdef UNICORN_HAS_ARMEB + ARM_REGS_STORAGE_SIZE_armeb +#else + 0 +#endif + : ARM_REGS_STORAGE_SIZE_arm; #endif #ifdef UNICORN_HAS_ARM64 case UC_ARCH_ARM64: return mode & UC_MODE_BIG_ENDIAN ? ARM64_REGS_STORAGE_SIZE_aarch64eb : ARM64_REGS_STORAGE_SIZE_aarch64; From e639d3fc93286f31b395085d1419fc7db60d53ac Mon Sep 17 00:00:00 2001 From: LAADHARI Date: Wed, 7 Oct 2020 05:43:26 +0200 Subject: [PATCH 37/44] FIX java binding compilation #1339 (#1340) --- bindings/java/Makefile.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/java/Makefile.build b/bindings/java/Makefile.build index c63fef3a..2aaf5113 100644 --- a/bindings/java/Makefile.build +++ b/bindings/java/Makefile.build @@ -3,7 +3,7 @@ JAVA_HOME := $(shell jrunscript -e 'java.lang.System.out.println(java.lang.System.getProperty("java.home"));') -JAVA_INC := $(shell realpath $(JAVA_HOME)/../include) +JAVA_INC := $(shell realpath $(JAVA_HOME)/include) JAVA_PLATFORM_INC := $(shell dirname `find $(JAVA_INC) -name jni_md.h`) From eb38c5b2e5f4de02e185a3e8fb35da60ba8548e2 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Tue, 20 Oct 2020 22:13:43 +0800 Subject: [PATCH 38/44] update ChangeLog for 1.0.2 --- ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 019c0b0a..64fb9069 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ This file details the changelog of Unicorn Engine. +----------------------------------- +[Version 1.0.2]: October 21st, 2020 + +- Fix Java binding compilation +- Enable building for ARM little-endian only (ignore big-endian) + ------------------------------------ [Version 1.0.2-rc6]: Sept 24th, 2020 From b1d7782c070f2d9f7ce6eb6afd0a94a2c3eef277 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Wed, 21 Oct 2020 13:42:20 +0800 Subject: [PATCH 39/44] update pkgconfig.mk for 1.0.2 --- pkgconfig.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgconfig.mk b/pkgconfig.mk index 13e3db63..d9c39741 100644 --- a/pkgconfig.mk +++ b/pkgconfig.mk @@ -10,4 +10,4 @@ PKG_MINOR = 0 PKG_EXTRA = 2 # version tag. Examples: rc1, b2, post1 -PKG_TAG = rc6 +# PKG_TAG = rc6 From 886acbf59910499e44194dadda9c069ef7d3b291 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Wed, 21 Oct 2020 19:34:41 +0800 Subject: [PATCH 40/44] add SPONSORS.TXT --- SPONSORS.TXT | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 SPONSORS.TXT diff --git a/SPONSORS.TXT b/SPONSORS.TXT new file mode 100644 index 00000000..d9827bbe --- /dev/null +++ b/SPONSORS.TXT @@ -0,0 +1,6 @@ +* Version 1.0.2 - October 21st, 2020 + +Release 1.0.2 was sponsored by the following companies (in no particular order). + +- Catena Cyber: https://catenacyber.fr +- Grayshift: https://grayshift.com From 4c054b9f0d67807b161ff94fbf8691fa3b6bf7e5 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 23 Oct 2020 00:03:54 +0800 Subject: [PATCH 41/44] update SPONSORS.TXT --- SPONSORS.TXT | 1 + 1 file changed, 1 insertion(+) diff --git a/SPONSORS.TXT b/SPONSORS.TXT index d9827bbe..ecdc4573 100644 --- a/SPONSORS.TXT +++ b/SPONSORS.TXT @@ -4,3 +4,4 @@ Release 1.0.2 was sponsored by the following companies (in no particular order). - Catena Cyber: https://catenacyber.fr - Grayshift: https://grayshift.com +- Google: https://google.com From 95bc0bdc211e5b89e8ba4c9fdf501a6e10ed0a89 Mon Sep 17 00:00:00 2001 From: pkubaj Date: Sat, 24 Oct 2020 23:34:57 +0000 Subject: [PATCH 42/44] Fix build with LLVM on powerpc64(le) (#1347) Conflicting symbols need to be undefined before including altivec.h. --- qemu/include/qemu-common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu/include/qemu-common.h b/qemu/include/qemu-common.h index 135a48f3..d2097dbf 100644 --- a/qemu/include/qemu-common.h +++ b/qemu/include/qemu-common.h @@ -205,7 +205,6 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) /* vector definitions */ #ifdef __ALTIVEC__ -#include /* The altivec.h header says we're allowed to undef these for * C++ compatibility. Here we don't care about C++, but we * undef them anyway to avoid namespace pollution. @@ -213,6 +212,7 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) #undef vector #undef pixel #undef bool +#include #define VECTYPE __vector unsigned char #define SPLAT(p) vec_splat(vec_ld(0, p), 0) #define ALL_EQ(v1, v2) vec_all_eq(v1, v2) From 5e4423a41940f5368d976dffba2d1e08b14b73fb Mon Sep 17 00:00:00 2001 From: smeng9 <38666763+smeng9@users.noreply.github.com> Date: Tue, 27 Oct 2020 20:47:59 -0500 Subject: [PATCH 43/44] Update binding list (#1349) --- bindings/README | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bindings/README b/bindings/README index 24dd2c18..4df67f62 100644 --- a/bindings/README +++ b/bindings/README @@ -33,3 +33,6 @@ More bindings created & maintained externally by community are available as foll - pharo-unicorn: Pharo binding (by Guille Polito) https://github.com/guillep/pharo-unicorn + +- Unicorn.js: JavaScript binding (by Alexandro Sanchez) + https://github.com/AlexAltea/unicorn.js From 770d5679c3f1c1104a190f3d40349af7cfecc5dc Mon Sep 17 00:00:00 2001 From: Peter Meerwald-Stadler Date: Thu, 29 Oct 2020 04:16:45 +0100 Subject: [PATCH 44/44] Fix some typos in include files (#1350) --- bindings/pascal/unicorn/Unicorn_dyn.pas | 2 +- include/unicorn/unicorn.h | 34 ++++++++++++------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/bindings/pascal/unicorn/Unicorn_dyn.pas b/bindings/pascal/unicorn/Unicorn_dyn.pas index 7db6bae7..427813cf 100755 --- a/bindings/pascal/unicorn/Unicorn_dyn.pas +++ b/bindings/pascal/unicorn/Unicorn_dyn.pas @@ -108,7 +108,7 @@ type @user_data: user data passed to tracing APIs @return: return true to continue, or false to stop program (due to invalid memory). - NOTE: returning true to continue execution will only work if if the accessed + NOTE: returning true to continue execution will only work if the accessed memory is made accessible with the correct permissions during the hook. In the event of a UC_MEM_READ_UNMAPPED or UC_MEM_WRITE_UNMAPPED callback, diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index ab5485ed..c7f17036 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -300,7 +300,7 @@ typedef void (*uc_cb_hookmem_t)(uc_engine *uc, uc_mem_type type, @user_data: user data passed to tracing APIs @return: return true to continue, or false to stop program (due to invalid memory). - NOTE: returning true to continue execution will only work if if the accessed + NOTE: returning true to continue execution will only work if the accessed memory is made accessible with the correct permissions during the hook. In the event of a UC_MEM_READ_UNMAPPED or UC_MEM_WRITE_UNMAPPED callback, @@ -413,7 +413,7 @@ UNICORN_EXPORT uc_err uc_query(uc_engine *uc, uc_query_type type, size_t *result); /* - Report the last error number when some API function fail. + Report the last error number when some API function fails. Like glibc's errno, uc_errno might not retain its old value once accessed. @uc: handle returned by uc_open() @@ -525,7 +525,7 @@ uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *bytes, size_t size); @uc: handle returned by uc_open() @begin: address where emulation starts - @until: address where emulation stops (i.e when this address is hit) + @until: address where emulation stops (i.e. when this address is hit) @timeout: duration to emulate the code (in microseconds). When this value is 0, we will emulate the code in infinite time, until the code is finished. @count: the number of instructions to be emulated. When this value is 0, @@ -555,12 +555,12 @@ uc_err uc_emu_stop(uc_engine *uc); @uc: handle returned by uc_open() @hh: hook handle returned from this registration. To be used in uc_hook_del() API - @type: hook type + @type: hook type, refer to uc_hook_type enum @callback: callback to be run when instruction is hit @user_data: user-defined data. This will be passed to callback function in its last argument @user_data - @begin: start address of the area where the callback is effect (inclusive) - @end: end address of the area where the callback is effect (inclusive) + @begin: start address of the area where the callback is in effect (inclusive) + @end: end address of the area where the callback is in effect (inclusive) NOTE 1: the callback is called only if related address is in range [@begin, @end] NOTE 2: if @begin > @end, callback is called whenever this hook type is triggered @...: variable arguments (depending on @type) @@ -577,7 +577,7 @@ uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback, Unregister (remove) a hook callback. This API removes the hook callback registered by uc_hook_add(). NOTE: this should be called only when you no longer want to trace. - After this, @hh is invalid, and nolonger usable. + After this, @hh is invalid, and no longer usable. @uc: handle returned by uc_open() @hh: handle returned by uc_hook_add() @@ -604,7 +604,7 @@ typedef enum uc_prot { @address: starting address of the new memory region to be mapped in. This address must be aligned to 4KB, or this will return with UC_ERR_ARG error. @size: size of the new memory region to be mapped in. - This size must be multiple of 4KB, or this will return with UC_ERR_ARG error. + This size must be a multiple of 4KB, or this will return with UC_ERR_ARG error. @perms: Permissions for the newly mapped region. This must be some combination of UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC, or this will return with UC_ERR_ARG error. @@ -623,12 +623,12 @@ uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms); @address: starting address of the new memory region to be mapped in. This address must be aligned to 4KB, or this will return with UC_ERR_ARG error. @size: size of the new memory region to be mapped in. - This size must be multiple of 4KB, or this will return with UC_ERR_ARG error. + This size must be a multiple of 4KB, or this will return with UC_ERR_ARG error. @perms: Permissions for the newly mapped region. This must be some combination of UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC, or this will return with UC_ERR_ARG error. @ptr: pointer to host memory backing the newly mapped memory. This host memory is - expected to be an equal or larger size than provided, and be mapped with at + expected to be of equal or larger size than provided, and be mapped with at least PROT_READ | PROT_WRITE. If it is not, the resulting behavior is undefined. @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum @@ -645,7 +645,7 @@ uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size, uint32_t per @address: starting address of the memory region to be unmapped. This address must be aligned to 4KB, or this will return with UC_ERR_ARG error. @size: size of the memory region to be modified. - This size must be multiple of 4KB, or this will return with UC_ERR_ARG error. + This size must be a multiple of 4KB, or this will return with UC_ERR_ARG error. @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum for detailed error). @@ -661,7 +661,7 @@ uc_err uc_mem_unmap(uc_engine *uc, uint64_t address, size_t size); @address: starting address of the memory region to be modified. This address must be aligned to 4KB, or this will return with UC_ERR_ARG error. @size: size of the memory region to be modified. - This size must be multiple of 4KB, or this will return with UC_ERR_ARG error. + This size must be a multiple of 4KB, or this will return with UC_ERR_ARG error. @perms: New permissions for the mapped region. This must be some combination of UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC, or this will return with UC_ERR_ARG error. @@ -675,8 +675,8 @@ uc_err uc_mem_protect(uc_engine *uc, uint64_t address, size_t size, uint32_t per /* Retrieve all memory regions mapped by uc_mem_map() and uc_mem_map_ptr() This API allocates memory for @regions, and user must free this memory later - by free() to avoid leaking memory. - NOTE: memory regions may be splitted by uc_mem_unmap() + by uc_free() to avoid leaking memory. + NOTE: memory regions may be split by uc_mem_unmap() @uc: handle returned by uc_open() @regions: pointer to an array of uc_mem_region struct. This is allocated by @@ -696,9 +696,9 @@ uc_err uc_mem_regions(uc_engine *uc, uc_mem_region **regions, uint32_t *count); differing arches or modes. @uc: handle returned by uc_open() - @context: pointer to a uc_engine*. This will be updated with the pointer to + @context: pointer to a uc_context*. This will be updated with the pointer to the new context on successful return of this function. - Later, this allocated memory must be freed with uc_free(). + Later, this allocated memory must be freed with uc_context_free(). @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum for detailed error). @@ -709,7 +709,7 @@ uc_err uc_context_alloc(uc_engine *uc, uc_context **context); /* Free the memory allocated by uc_mem_regions. WARNING: After Unicorn 1.0.1rc5, the memory allocated by uc_context_alloc should - be free-ed by uc_context_free(). Calling uc_free() may still work, but the result + be freed by uc_context_free(). Calling uc_free() may still work, but the result is **undefined**. @mem: memory allocated by uc_mem_regions (returned in *regions).