From 6ce7657589982788ab3f9d5808ce407b180985fc Mon Sep 17 00:00:00 2001 From: Antwy <38584695+Antwy@users.noreply.github.com> Date: Tue, 16 Jul 2024 16:58:05 +0300 Subject: [PATCH] Use riscv only with Capstone version 5+ --- .github/workflows/vcpkg.yml | 4 +-- CMakeLists.txt | 4 +++ src/libtriton/CMakeLists.txt | 28 ++++++++++++------- src/libtriton/arch/architecture.cpp | 6 ++++ src/libtriton/arch/irBuilder.cpp | 15 ++++++++-- .../python/namespaces/initArchNamespace.cpp | 2 ++ .../namespaces/initOpcodesNamespace.cpp | 2 ++ .../python/namespaces/initRegNamespace.cpp | 2 ++ src/libtriton/context/context.cpp | 4 +++ src/libtriton/includes/triton/archEnums.hpp | 4 +++ .../includes/triton/externalLibs.hpp | 2 ++ src/libtriton/includes/triton/irBuilder.hpp | 2 ++ .../includes/triton/shortcutRegister.hpp | 6 ++++ src/testers/CMakeLists.txt | 16 ++++++++--- src/testers/unittests/test_examples.py | 2 ++ 15 files changed, 81 insertions(+), 18 deletions(-) diff --git a/.github/workflows/vcpkg.yml b/.github/workflows/vcpkg.yml index 72f31a635..bbf027b81 100644 --- a/.github/workflows/vcpkg.yml +++ b/.github/workflows/vcpkg.yml @@ -64,7 +64,7 @@ jobs: - name: Configure (Windows) if: ${{ matrix.platform == 'windows' }} run: | - cmake --preset=${{ matrix.cmake-preset }} -DBUILD_SHARED_LIBS:BOOL=ON -DVCPKG_OVERLAY_TRIPLETS:PATH=${{ github.workspace }}\vcpkg\triplets -DVCPKG_TARGET_TRIPLET:STRING=${{ matrix.vcpkg-triplet }} + cmake --preset=${{ matrix.cmake-preset }} -DBUILD_SHARED_LIBS:BOOL=ON -DCOMPILE_RISCV:BOOL=ON -DVCPKG_OVERLAY_TRIPLETS:PATH=${{ github.workspace }}\vcpkg\triplets -DVCPKG_TARGET_TRIPLET:STRING=${{ matrix.vcpkg-triplet }} env: # capstone 4.0.2 does not produce a CMake Config, hence the need to point directly to include directories and libraries CAPSTONE_INCLUDE_DIRS: ${{ github.workspace }}/build/${{ matrix.cmake-preset }}/vcpkg_installed/${{ matrix.vcpkg-triplet }}/include @@ -76,7 +76,7 @@ jobs: if: ${{ matrix.platform != 'windows' }} run: | python -m pip install importlib-resources - cmake --preset=${{ matrix.cmake-preset }} -DBUILD_SHARED_LIBS:BOOL=ON -DVCPKG_OVERLAY_TRIPLETS:PATH=${{ github.workspace }}/vcpkg/triplets -DVCPKG_TARGET_TRIPLET:STRING=${{ matrix.vcpkg-triplet }} + cmake --preset=${{ matrix.cmake-preset }} -DBUILD_SHARED_LIBS:BOOL=ON -DCOMPILE_RISCV:BOOL=ON -DVCPKG_OVERLAY_TRIPLETS:PATH=${{ github.workspace }}/vcpkg/triplets -DVCPKG_TARGET_TRIPLET:STRING=${{ matrix.vcpkg-triplet }} env: # capstone 4.0.2 does not produce a CMake Config, hence the need to point directly to include directories and libraries CAPSTONE_INCLUDE_DIRS: ${{ github.workspace }}/build/${{ matrix.cmake-preset }}/vcpkg_installed/${{ matrix.vcpkg-triplet }}/include diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ccb41617..003028ca7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -194,6 +194,10 @@ endif() message(STATUS "Compiling with Capstone") find_package(CAPSTONE 5 REQUIRED) message(STATUS "CAPSTONE version: ${CAPSTONE_VERSION}") +if(NOT ${CS_VERSION_MAJOR} MATCHES 4) + set(COMPILE_RISCV ON) + add_definitions(-DCOMPILE_RISCV) +endif() if(TARGET capstone::capstone) link_libraries(capstone::capstone) elseif(DEFINED CAPSTONE_INCLUDE_DIRS) diff --git a/src/libtriton/CMakeLists.txt b/src/libtriton/CMakeLists.txt index 7379ddf16..4ae072db3 100644 --- a/src/libtriton/CMakeLists.txt +++ b/src/libtriton/CMakeLists.txt @@ -32,10 +32,6 @@ set(LIBTRITON_SOURCE_FILES arch/memoryAccess.cpp arch/operandWrapper.cpp arch/register.cpp - arch/riscv/riscv32Cpu.cpp - arch/riscv/riscv64Cpu.cpp - arch/riscv/riscvSemantics.cpp - arch/riscv/riscvSpecifications.cpp arch/x86/x8664Cpu.cpp arch/x86/x86Cpu.cpp arch/x86/x86Semantics.cpp @@ -122,12 +118,6 @@ set(LIBTRITON_HEADER_FILES includes/triton/pathConstraint.hpp includes/triton/pathManager.hpp includes/triton/register.hpp - includes/triton/riscv32.spec - includes/triton/riscv64.spec - includes/triton/riscv32Cpu.hpp - includes/triton/riscv64Cpu.hpp - includes/triton/riscvSemantics.hpp - includes/triton/riscvSpecifications.hpp includes/triton/semanticsInterface.hpp includes/triton/shortcutRegister.hpp includes/triton/solverEngine.hpp @@ -157,6 +147,24 @@ set(LIBTRITON_HEADER_FILES includes/triton/z3ToTriton.hpp ) +# Add riscv source and header files +if(${COMPILE_RISCV}) + list(APPEND LIBTRITON_SOURCE_FILES + arch/riscv/riscv32Cpu.cpp + arch/riscv/riscv64Cpu.cpp + arch/riscv/riscvSemantics.cpp + arch/riscv/riscvSpecifications.cpp + ) + list(APPEND LIBTRITON_HEADER_FILES + includes/triton/riscv32.spec + includes/triton/riscv64.spec + includes/triton/riscv32Cpu.hpp + includes/triton/riscv64Cpu.hpp + includes/triton/riscvSemantics.hpp + includes/triton/riscvSpecifications.hpp + ) +endif() + # Define all resource files set(LIBTRITON_RESOURCE_FILES includes/triton/version.hpp.in diff --git a/src/libtriton/arch/architecture.cpp b/src/libtriton/arch/architecture.cpp index ca1a9508e..70deb12c4 100644 --- a/src/libtriton/arch/architecture.cpp +++ b/src/libtriton/arch/architecture.cpp @@ -13,8 +13,10 @@ #include #include #include +#ifdef COMPILE_RISCV #include #include +#endif #include #include #include @@ -57,8 +59,10 @@ namespace triton { case triton::arch::ARCH_X86: this->cpu.reset(new(std::nothrow) triton::arch::x86::x86Cpu(this->callbacks)); break; case triton::arch::ARCH_AARCH64: this->cpu.reset(new(std::nothrow) triton::arch::arm::aarch64::AArch64Cpu(this->callbacks)); break; case triton::arch::ARCH_ARM32: this->cpu.reset(new(std::nothrow) triton::arch::arm::arm32::Arm32Cpu(this->callbacks)); break; + #ifdef COMPILE_RISCV case triton::arch::ARCH_RV64: this->cpu.reset(new(std::nothrow) triton::arch::riscv::riscv64Cpu(this->callbacks)); break; case triton::arch::ARCH_RV32: this->cpu.reset(new(std::nothrow) triton::arch::riscv::riscv32Cpu(this->callbacks)); break; + #endif default: throw triton::exceptions::Architecture("Architecture::setArchitecture(): Architecture not supported."); } @@ -405,9 +409,11 @@ namespace triton { case triton::arch::ARCH_X86_64: return triton::arch::x86::nop; + #ifdef COMPILE_RISCV case triton::arch::ARCH_RV64: case triton::arch::ARCH_RV32: return triton::arch::riscv::nop; + #endif default: throw triton::exceptions::Architecture("Architecture::getNopInstruction(): Invalid architecture."); diff --git a/src/libtriton/arch/irBuilder.cpp b/src/libtriton/arch/irBuilder.cpp index 2273f4939..7ed560d39 100644 --- a/src/libtriton/arch/irBuilder.cpp +++ b/src/libtriton/arch/irBuilder.cpp @@ -16,8 +16,9 @@ #include #include #include +#ifdef COMPILE_RISCV #include - +#endif namespace triton { @@ -45,9 +46,15 @@ namespace triton { this->aarch64Isa = new(std::nothrow) triton::arch::arm::aarch64::AArch64Semantics(architecture, symbolicEngine, taintEngine, astCtxt); this->arm32Isa = new(std::nothrow) triton::arch::arm::arm32::Arm32Semantics(architecture, symbolicEngine, taintEngine, astCtxt); this->x86Isa = new(std::nothrow) triton::arch::x86::x86Semantics(architecture, symbolicEngine, taintEngine, modes, astCtxt); + #ifdef COMPILE_RISCV this->riscvIsa = new(std::nothrow) triton::arch::riscv::riscvSemantics(architecture, symbolicEngine, taintEngine, modes, astCtxt); + #endif - if (this->x86Isa == nullptr || this->aarch64Isa == nullptr || this->arm32Isa == nullptr || this->riscvIsa == nullptr) + if (this->x86Isa == nullptr || this->aarch64Isa == nullptr || this->arm32Isa == nullptr + #ifdef COMPILE_RISCV + || this->riscvIsa == nullptr + #endif + ) throw triton::exceptions::IrBuilder("IrBuilder::IrBuilder(): Not enough memory."); } @@ -56,7 +63,9 @@ namespace triton { delete this->aarch64Isa; delete this->arm32Isa; delete this->x86Isa; + #ifdef COMPILE_RISCV delete this->riscvIsa; + #endif } @@ -92,10 +101,12 @@ namespace triton { ret = this->x86Isa->buildSemantics(inst); break; + #ifdef COMPILE_RISCV case triton::arch::ARCH_RV64: case triton::arch::ARCH_RV32: ret = this->riscvIsa->buildSemantics(inst); break; + #endif default: throw triton::exceptions::IrBuilder("IrBuilder::buildSemantics(): Architecture not supported."); diff --git a/src/libtriton/bindings/python/namespaces/initArchNamespace.cpp b/src/libtriton/bindings/python/namespaces/initArchNamespace.cpp index d622a3644..63ce23e08 100644 --- a/src/libtriton/bindings/python/namespaces/initArchNamespace.cpp +++ b/src/libtriton/bindings/python/namespaces/initArchNamespace.cpp @@ -43,8 +43,10 @@ namespace triton { void initArchNamespace(PyObject* archDict) { xPyDict_SetItemString(archDict, "AARCH64", PyLong_FromUint32(triton::arch::ARCH_AARCH64)); xPyDict_SetItemString(archDict, "ARM32", PyLong_FromUint32(triton::arch::ARCH_ARM32)); + #ifdef COMPILE_RISCV xPyDict_SetItemString(archDict, "RV32", PyLong_FromUint32(triton::arch::ARCH_RV32)); xPyDict_SetItemString(archDict, "RV64", PyLong_FromUint32(triton::arch::ARCH_RV64)); + #endif xPyDict_SetItemString(archDict, "X86", PyLong_FromUint32(triton::arch::ARCH_X86)); xPyDict_SetItemString(archDict, "X86_64", PyLong_FromUint32(triton::arch::ARCH_X86_64)); } diff --git a/src/libtriton/bindings/python/namespaces/initOpcodesNamespace.cpp b/src/libtriton/bindings/python/namespaces/initOpcodesNamespace.cpp index 0d02e7f39..edc5d0066 100644 --- a/src/libtriton/bindings/python/namespaces/initOpcodesNamespace.cpp +++ b/src/libtriton/bindings/python/namespaces/initOpcodesNamespace.cpp @@ -4527,6 +4527,7 @@ namespace triton { xPyDict_SetItemString(opcodesDict, "ARM32", arm32OpcodesDictClass); + #ifdef COMPILE_RISCV PyObject* riscv64OpcodesDict = xPyDict_New(); xPyDict_SetItemString(riscv64OpcodesDict, "ADD", PyLong_FromUint32(triton::arch::riscv::ID_INS_ADD)); @@ -4709,6 +4710,7 @@ namespace triton { PyObject* riscv32OpcodesDictClass = xPyClass_New(nullptr, riscv32OpcodesDict, xPyString_FromString("RV32")); xPyDict_SetItemString(opcodesDict, "RV32", riscv32OpcodesDictClass); + #endif } }; /* python namespace */ diff --git a/src/libtriton/bindings/python/namespaces/initRegNamespace.cpp b/src/libtriton/bindings/python/namespaces/initRegNamespace.cpp index 4886380a2..1722b054e 100644 --- a/src/libtriton/bindings/python/namespaces/initRegNamespace.cpp +++ b/src/libtriton/bindings/python/namespaces/initRegNamespace.cpp @@ -132,6 +132,7 @@ namespace triton { PyObject* arm32RegistersDictClass = xPyClass_New(nullptr, arm32RegistersDict, xPyString_FromString("ARM32")); xPyDict_SetItemString(registersDict, "ARM32", arm32RegistersDictClass); + #ifdef COMPILE_RISCV // Create RISCV64 REG namespace PyObject* riscv64RegistersDict = xPyDict_New(); @@ -159,6 +160,7 @@ namespace triton { PyObject* riscv32RegistersDictClass = xPyClass_New(nullptr, riscv32RegistersDict, xPyString_FromString("RV32")); xPyDict_SetItemString(registersDict, "RV32", riscv32RegistersDictClass); + #endif } }; /* python namespace */ diff --git a/src/libtriton/context/context.cpp b/src/libtriton/context/context.cpp index 34a559145..392692ded 100644 --- a/src/libtriton/context/context.cpp +++ b/src/libtriton/context/context.cpp @@ -10,8 +10,10 @@ #include #include #include +#ifdef COMPILE_RISCV #include #include +#endif #include #include @@ -464,12 +466,14 @@ namespace triton { case triton::arch::ARCH_AARCH64: *static_cast(this->getCpuInstance()) = *static_cast(other.getCpuInstance()); break; + #ifdef COMPILE_RISCV case triton::arch::ARCH_RV64: *static_cast(this->getCpuInstance()) = *static_cast(other.getCpuInstance()); break; case triton::arch::ARCH_RV32: *static_cast(this->getCpuInstance()) = *static_cast(other.getCpuInstance()); break; + #endif default: throw triton::exceptions::Engines("Context::setConcreteState(): Invalid architecture."); } diff --git a/src/libtriton/includes/triton/archEnums.hpp b/src/libtriton/includes/triton/archEnums.hpp index c6629c929..0167b3393 100644 --- a/src/libtriton/includes/triton/archEnums.hpp +++ b/src/libtriton/includes/triton/archEnums.hpp @@ -33,8 +33,10 @@ namespace triton { ARCH_INVALID = 0, /*!< Invalid architecture. */ ARCH_AARCH64, /*!< AArch64 architecture. */ ARCH_ARM32, /*!< ARM32 architecture. */ + #ifdef COMPILE_RISCV ARCH_RV32, /*!< RISCV32 architecture. */ ARCH_RV64, /*!< RISCV64 architecture. */ + #endif ARCH_X86, /*!< X86 architecture. */ ARCH_X86_64, /*!< X86_64 architecture. */ }; @@ -82,6 +84,7 @@ namespace triton { #define REG_SPEC_NO_CAPSTONE REG_SPEC #include "triton/arm32.spec" + #ifdef COMPILE_RISCV #define REG_SPEC(_1, UPPER_NAME, _2, _3, _4, _5, _6) \ ID_REG_RV64_##UPPER_NAME, #define REG_SPEC_NO_CAPSTONE REG_SPEC @@ -91,6 +94,7 @@ namespace triton { ID_REG_RV32_##UPPER_NAME, #define REG_SPEC_NO_CAPSTONE REG_SPEC #include "triton/riscv32.spec" + #endif /* Must be the last item */ ID_REG_LAST_ITEM //!< must be the last item diff --git a/src/libtriton/includes/triton/externalLibs.hpp b/src/libtriton/includes/triton/externalLibs.hpp index 49d699468..e4d640d33 100644 --- a/src/libtriton/includes/triton/externalLibs.hpp +++ b/src/libtriton/includes/triton/externalLibs.hpp @@ -32,7 +32,9 @@ namespace triton { #include #include #include + #ifdef COMPILE_RISCV #include + #endif #include /*! @} End of capstone namespace */ }; diff --git a/src/libtriton/includes/triton/irBuilder.hpp b/src/libtriton/includes/triton/irBuilder.hpp index 45d21f6f6..2838256b5 100644 --- a/src/libtriton/includes/triton/irBuilder.hpp +++ b/src/libtriton/includes/triton/irBuilder.hpp @@ -79,8 +79,10 @@ namespace triton { //! x86 ISA builder. triton::arch::SemanticsInterface* x86Isa; + #ifdef COMPILE_RISCV //! RISCV ISA builder. triton::arch::SemanticsInterface* riscvIsa; + #endif public: //! Constructor. diff --git a/src/libtriton/includes/triton/shortcutRegister.hpp b/src/libtriton/includes/triton/shortcutRegister.hpp index b701b7a79..d17088233 100644 --- a/src/libtriton/includes/triton/shortcutRegister.hpp +++ b/src/libtriton/includes/triton/shortcutRegister.hpp @@ -49,11 +49,13 @@ namespace triton { #define REG_SPEC_NO_CAPSTONE REG_SPEC #include "triton/arm32.spec" + #ifdef COMPILE_RISCV // ShortcutRegister set for RV32 is the same, #define REG_SPEC(_0, _1, LOWER_NAME, _2, _3, _4, _5) \ triton::arch::Register riscv_##LOWER_NAME; #define REG_SPEC_NO_CAPSTONE REG_SPEC #include "triton/riscv64.spec" + #endif /*! Constructor */ ShortcutRegister() {}; @@ -76,11 +78,13 @@ namespace triton { #define REG_SPEC_NO_CAPSTONE REG_SPEC #include "triton/arm32.spec" + #ifdef COMPILE_RISCV // ShortcutRegister set for RV32 is the same, #define REG_SPEC(_0, _1, LOWER_NAME, _2, _3, _4, _5) \ this->riscv_##LOWER_NAME = triton::arch::Register(); #define REG_SPEC_NO_CAPSTONE REG_SPEC #include "triton/riscv64.spec" + #endif }; /*! Inits the shortcut */ @@ -142,6 +146,7 @@ namespace triton { } break; + #ifdef COMPILE_RISCV case triton::arch::ARCH_RV64: { #define REG_SPEC(CS_UPPER_NAME, UPPER_NAME, LOWER_NAME, ABI_NAME, RISCV_UPPER, RISCV_LOWER, MUTABLE) \ this->riscv_##LOWER_NAME = triton::arch::Register(triton::arch::ID_REG_RV64_##UPPER_NAME, \ @@ -167,6 +172,7 @@ namespace triton { #include "triton/riscv32.spec" } break; + #endif default: throw triton::exceptions::Architecture("ShortcutRegister::init(): Invalid architecture."); diff --git a/src/testers/CMakeLists.txt b/src/testers/CMakeLists.txt index 614f19a5b..971dfda2e 100644 --- a/src/testers/CMakeLists.txt +++ b/src/testers/CMakeLists.txt @@ -5,8 +5,10 @@ if((${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin add_test(NAME UnicornAArch64Semantics COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/aarch64/unicorn_test_aarch64.py) add_test(NAME UnicornX86Semantics COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/x86/unicorn_test_x86.py) - add_test(NAME UnicornRiscv64Semantics COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/riscv/unicorn_test_riscv64.py) - add_test(NAME UnicornRiscv32Semantics COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/riscv/unicorn_test_riscv32.py) + if(${COMPILE_RISCV}) + add_test(NAME UnicornRiscv64Semantics COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/riscv/unicorn_test_riscv64.py) + add_test(NAME UnicornRiscv32Semantics COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/riscv/unicorn_test_riscv32.py) + endif() add_test(NAME UnicornARM32Semantics1 COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/arm32/unicorn_test_arm32_branch_arm_1.py) add_test(NAME UnicornARM32Semantics2 COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/arm32/unicorn_test_arm32_branch_arm_2.py) add_test(NAME UnicornARM32Semantics3 COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/arm32/unicorn_test_arm32_branch_pc_arm_1.py) @@ -46,8 +48,6 @@ if((${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin set_property(TEST UnicornAArch64Semantics UnicornX86Semantics - UnicornRiscv64Semantics - UnicornRiscv32Semantics UnicornARM32Semantics1 UnicornARM32Semantics2 UnicornARM32Semantics3 @@ -85,4 +85,12 @@ if((${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin UnicornARM32Semantics35 PROPERTY ENVIRONMENT "PYTHONPATH=$" ) + if(${COMPILE_RISCV}) + set_property(TEST + UnicornRiscv64Semantics + UnicornRiscv32Semantics + APPEND + PROPERTY ENVIRONMENT "PYTHONPATH=$" + ) + endif() endif() diff --git a/src/testers/unittests/test_examples.py b/src/testers/unittests/test_examples.py index c37c9b9a1..46e1c49bd 100644 --- a/src/testers/unittests/test_examples.py +++ b/src/testers/unittests/test_examples.py @@ -34,6 +34,8 @@ def _test_example(self, example_name=example): if ('TRAVIS' in os.environ or 'APPVEYOR' in os.environ) and example_name.find('hackcon-2016-angry-reverser') >= 0: # FIXME: Doesn't work on Travis and Appveyor... return + if ('APPVEYOR' in os.environ or not 'COMPILE_RISCV' in os.environ) and example_name.find('riscv') >= 0: + return p = subprocess.Popen([sys.executable, example_name] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate()