Modern Testing (#2456)

This commit is contained in:
Rot127 2024-08-31 13:33:38 +00:00 committed by GitHub
parent df72286749
commit 191db14531
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1754 changed files with 613736 additions and 22936 deletions

View File

@ -6,7 +6,7 @@ on:
- "docs/**" - "docs/**"
- "ChangeLog" - "ChangeLog"
- "CREDITS.TXT" - "CREDITS.TXT"
- "COMPILE.TXT" - "COMPILE_MAKE.TXT"
- "COMPILE_MSVC.TXT" - "COMPILE_MSVC.TXT"
- "COMPILE_CMAKE.TXT" - "COMPILE_CMAKE.TXT"
- "HACK.TXT" - "HACK.TXT"
@ -34,6 +34,7 @@ jobs:
os: ubuntu-22.04, os: ubuntu-22.04,
arch: x64, arch: x64,
build-system: 'make', build-system: 'make',
diet-build: 'OFF',
enable-asan: 'OFF' enable-asan: 'OFF'
} }
- { - {
@ -41,34 +42,37 @@ jobs:
os: ubuntu-22.04, os: ubuntu-22.04,
arch: x64, arch: x64,
build-system: 'cmake', build-system: 'cmake',
diet-build: 'OFF',
enable-asan: 'OFF' enable-asan: 'OFF'
} }
- { - {
name: 'ubuntu-22.04 x64 ASAN', name: 'ubuntu-24.04 x64 ASAN',
os: ubuntu-latest, os: ubuntu-24.04,
arch: x64, arch: x64,
build-system: 'cmake', build-system: 'cmake',
diet-build: 'OFF',
enable-asan: 'ON' enable-asan: 'ON'
} }
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: prepare - name: Set up Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.config.python-version }}
- name: Prepare fuzzing
run: | run: |
export LD_LIBRARY_PATH=`pwd`/tests/:$LD_LIBRARY_PATH export LD_LIBRARY_PATH=`pwd`/tests/:$LD_LIBRARY_PATH
wget https://github.com/groundx/capstonefuzz/raw/master/corpus/corpus-libFuzzer-capstone_fuzz_disasmnext-latest.zip wget https://github.com/groundx/capstonefuzz/raw/master/corpus/corpus-libFuzzer-capstone_fuzz_disasmnext-latest.zip
unzip -q corpus-libFuzzer-capstone_fuzz_disasmnext-latest.zip -d suite/fuzz unzip -q corpus-libFuzzer-capstone_fuzz_disasmnext-latest.zip -d suite/fuzz
git clone https://git.cryptomilk.org/projects/cmocka.git suite/cstest/cmocka
chmod +x suite/cstest/build_cstest.sh
- name: make - name: make
if: startsWith(matrix.config.build-system, 'make') if: startsWith(matrix.config.build-system, 'make')
run: | run: |
./make.sh ./make.sh
make check
sudo make install sudo make install
cp libcapstone.so.5 libcapstone.so.5.0
- name: cmake - name: cmake
if: startsWith(matrix.config.build-system, 'cmake') if: startsWith(matrix.config.build-system, 'cmake')
@ -82,47 +86,55 @@ jobs:
# build shared library # build shared library
cmake -DCAPSTONE_INSTALL=1 -DBUILD_SHARED_LIBS=1 -DCMAKE_INSTALL_PREFIX=/usr -DCAPSTONE_BUILD_CSTEST=ON -DENABLE_ASAN=${asan} .. cmake -DCAPSTONE_INSTALL=1 -DBUILD_SHARED_LIBS=1 -DCMAKE_INSTALL_PREFIX=/usr -DCAPSTONE_BUILD_CSTEST=ON -DENABLE_ASAN=${asan} ..
sudo cmake --build . --config Release --target install sudo cmake --build . --config Release --target install
cp libcapstone.* ../
cp libcapstone.* ../tests/
cp test_* ../tests/
- name: Lower number of KASL randomized address bits - name: Lower number of KASL randomized address bits
run: | run: |
# Work-around ASAN bug https://github.com/google/sanitizers/issues/1716 # Work-around ASAN bug https://github.com/google/sanitizers/issues/1716
sudo sysctl vm.mmap_rnd_bits=28 sudo sysctl vm.mmap_rnd_bits=28
- name: "Compatibility header test build" - name: "Compatibility header test"
if: matrix.config.diet-build == 'OFF' if: startsWith(matrix.config.build-system, 'cmake') && matrix.config.diet-build == 'OFF'
env:
asan: ${{ matrix.config.enable-asan }}
run: | run: |
cd "$(git rev-parse --show-toplevel)/suite/auto-sync/c_tests/" ctest --test-dir build --output-on-failure -R ASCompatibilityHeaderTest
if [ "$asan" = "ON" ]; then
clang -lcapstone -fsanitize=address src/test_arm64_compatibility_header.c -o test_arm64_compatibility_header
else
clang -lcapstone src/test_arm64_compatibility_header.c -o test_arm64_compatibility_header
fi
./test_arm64_compatibility_header
- name: cstool - reaches disassembler engine - name: cstool - reaches disassembler engine
run: | run: |
sh suite/run_invalid_cstool.sh sh suite/run_invalid_cstool.sh
- name: cstest (cmake) - name: cstest unit tests
if: startsWith(matrix.config.build-system, 'cmake') if: startsWith(matrix.config.build-system, 'cmake')
run: | run: |
python suite/cstest/cstest_report.py -D -d suite/MC ctest --test-dir build --output-on-failure -R UnitCSTest
python suite/cstest/cstest_report.py -D -f suite/cstest/issues.cs
python suite/cstest/cstest_report.py -D -f tests/cs_details/issue.cs
- name: cstest (make) - name: cstest integration tests
if: startsWith(matrix.config.build-system, 'make') if: startsWith(matrix.config.build-system, 'cmake')
run: | run: |
cd suite/cstest && ./build_cstest.sh ctest --test-dir build --output-on-failure -R IntegrationCSTest
python cstest_report.py -D -t build/cstest -d ../MC
python cstest_report.py -D -t build/cstest -f issues.cs - name: cstest MC
python cstest_report.py -D -t build/cstest -f ../../tests/cs_details/issue.cs if: startsWith(matrix.config.build-system, 'cmake')
cd ../../ run: |
ctest --test-dir build --output-on-failure -R MCTests
- name: cstest details
if: startsWith(matrix.config.build-system, 'cmake')
run: |
ctest --test-dir build --output-on-failure -R DetailTests
- name: cstest issues
if: startsWith(matrix.config.build-system, 'cmake')
run: |
ctest --test-dir build --output-on-failure -R IssueTests
- name: cstest features
if: startsWith(matrix.config.build-system, 'cmake')
run: |
ctest --test-dir build --output-on-failure -R FeaturesTests
- name: Legacy integration tests
if: startsWith(matrix.config.build-system, 'cmake')
run: |
ctest --test-dir build --output-on-failure -R legacy*
Windows: Windows:
runs-on: ${{ matrix.config.os }} runs-on: ${{ matrix.config.os }}

View File

@ -3,11 +3,17 @@ on:
push: push:
paths: paths:
- "suite/auto-sync/**" - "suite/auto-sync/**"
- ".github/workflows/auto-sync.yml"
pull_request: pull_request:
# Stop previous runs on the same branch on new push
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
check: check:
runs-on: ubuntu-latest runs-on: ubuntu-24.04
defaults: defaults:
run: run:
working-directory: suite/auto-sync/ working-directory: suite/auto-sync/
@ -30,9 +36,22 @@ jobs:
run: | run: |
python3.11 -m black --check src/autosync python3.11 -m black --check src/autosync
- name: Build llvm-tblgen - name: Install llvm-mc
run: |
sudo apt install llvm-18
llvm-mc-18 --version
FileCheck-18 --version
sudo ln -s $(whereis -b llvm-mc-18 | grep -Eo "/.*") /usr/local/bin/llvm-mc
sudo ln -s $(whereis -b FileCheck-18 | grep -Eo "/.*") /usr/local/bin/FileCheck
llvm-mc --version
FileCheck --version
- name: Clone llvm-capstone
run: | run: |
git clone https://github.com/capstone-engine/llvm-capstone.git vendor/llvm_root git clone https://github.com/capstone-engine/llvm-capstone.git vendor/llvm_root
- name: Build llvm-tblgen
run: |
cd vendor/llvm_root cd vendor/llvm_root
mkdir build mkdir build
cd build cd build
@ -40,6 +59,17 @@ jobs:
cmake --build . --target llvm-tblgen --config Debug cmake --build . --target llvm-tblgen --config Debug
cd ../../../ cd ../../../
- name: Test Header patcher
run: |
python -m unittest src/autosync/Tests/test_header_patcher.py
python -m unittest src/autosync/Tests/test_mcupdater.py
- name: Remove llvm-mc
run: |
sudo apt remove llvm-18
sudo rm /usr/local/bin/llvm-mc
sudo rm /usr/local/bin/FileCheck
- name: Test generation of inc files - name: Test generation of inc files
run: | run: |
./src/autosync/ASUpdater.py -d -a AArch64 -s IncGen ./src/autosync/ASUpdater.py -d -a AArch64 -s IncGen
@ -63,11 +93,9 @@ jobs:
./src/autosync/ASUpdater.py --ci -d -a PPC -s Translate ./src/autosync/ASUpdater.py --ci -d -a PPC -s Translate
./src/autosync/ASUpdater.py --ci -d -a LoongArch -s Translate ./src/autosync/ASUpdater.py --ci -d -a LoongArch -s Translate
- name: Test Header patcher
run: |
python -m unittest src/autosync/Tests/test_header_patcher.py
python -m unittest src/autosync/Tests/test_mcupdater.py
- name: Differ - Test save file is up-to-date - name: Differ - Test save file is up-to-date
run: | run: |
./src/autosync/cpptranslator/Differ.py -a AArch64 --check_saved ./src/autosync/cpptranslator/Differ.py -a AArch64 --check_saved
./src/autosync/cpptranslator/Differ.py -a ARM --check_saved
./src/autosync/cpptranslator/Differ.py -a PPC --check_saved
./src/autosync/cpptranslator/Differ.py -a LoongArch --check_saved

View File

@ -8,11 +8,11 @@ on:
jobs: jobs:
analyze: analyze:
runs-on: ubuntu-latest runs-on: ubuntu-24.04
name: clang-tidy name: clang-tidy
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Install clang-tidy - name: Install clang-tidy
@ -26,9 +26,9 @@ jobs:
CC=clang sudo cmake --build . --config Release CC=clang sudo cmake --build . --config Release
cd .. cd ..
- name: Install clang-tidy-15 - name: Install clang-tidy-18
run: | run: |
sudo apt install clang-tidy-15 sudo apt install clang-tidy-18
- name: Check for warnings - name: Check for warnings
env: env:
@ -36,3 +36,8 @@ jobs:
head_sha: ${{ github.event.pull_request.head.sha }} head_sha: ${{ github.event.pull_request.head.sha }}
run: | run: |
./run-clang-tidy.sh build ./run-clang-tidy.sh build
- uses: actions/upload-artifact@v4
if: ${{ failure() }}
with:
path: ct-warnings.txt

View File

@ -28,5 +28,30 @@ jobs:
- name: Build and install capstone - name: Build and install capstone
run: pip install ./bindings/python run: pip install ./bindings/python
- name: Run tests - name: Install cstest_py
run: pip install ./bindings/python/cstest_py
- name: Run legacy tests
run: python ./bindings/python/tests/test_all.py run: python ./bindings/python/tests/test_all.py
- name: cstest_py integration tests
run: |
cd suite/cstest/test/
python3 ./integration_tests.py cstest_py
cd ../../../
- name: cstest_py MC
run: |
cstest_py tests/MC/
- name: cstest_py details
run: |
cstest_py tests/details/
- name: cstest_py issues
run: |
cstest_py tests/issues/
- name: cstest_py features
run: |
cstest_py tests/features/

5
.gitignore vendored
View File

@ -25,6 +25,7 @@
# python # python
bindings/python/build/ bindings/python/build/
bindings/python/capstone.egg-info/ bindings/python/capstone.egg-info/
bindings/python/cstest_py/src/cstest_py.egg**
bindings/cython/capstone.egg-info/ bindings/cython/capstone.egg-info/
*.pyc *.pyc
@ -133,7 +134,6 @@ fuzz_disasm
fuzz_decode_platform fuzz_decode_platform
capstone_get_setup capstone_get_setup
suite/fuzz/corpus suite/fuzz/corpus
suite/cstest/cmocka/
*.s *.s
@ -147,3 +147,6 @@ android-ndk-*
# Auto-sync files # Auto-sync files
suite/auto-sync/src/autosync.egg-info suite/auto-sync/src/autosync.egg-info
# clangd cache
/.cache

View File

@ -60,7 +60,7 @@ option(BUILD_SHARED_LIBS "Build shared library" OFF)
option(CAPSTONE_BUILD_STATIC_RUNTIME "Embed static runtime" ${BUILD_SHARED_LIBS}) option(CAPSTONE_BUILD_STATIC_RUNTIME "Embed static runtime" ${BUILD_SHARED_LIBS})
option(CAPSTONE_BUILD_MACOS_THIN "Disable universal2 builds on macOS" OFF) option(CAPSTONE_BUILD_MACOS_THIN "Disable universal2 builds on macOS" OFF)
option(CAPSTONE_BUILD_DIET "Build diet library" OFF) option(CAPSTONE_BUILD_DIET "Build diet library" OFF)
option(CAPSTONE_BUILD_TESTS "Build tests" ${PROJECT_IS_TOP_LEVEL}) option(CAPSTONE_BUILD_LEGACY_TESTS "Build legacy tests" ${PROJECT_IS_TOP_LEVEL})
option(CAPSTONE_BUILD_CSTOOL "Build cstool" ${PROJECT_IS_TOP_LEVEL}) option(CAPSTONE_BUILD_CSTOOL "Build cstool" ${PROJECT_IS_TOP_LEVEL})
option(CAPSTONE_BUILD_CSTEST "Build cstest" OFF) option(CAPSTONE_BUILD_CSTEST "Build cstest" OFF)
option(CAPSTONE_USE_DEFAULT_ALLOC "Use default memory allocation functions" ON) option(CAPSTONE_USE_DEFAULT_ALLOC "Use default memory allocation functions" ON)
@ -69,13 +69,21 @@ option(CAPSTONE_ARCHITECTURE_DEFAULT "Whether architectures are enabled by defau
option(CAPSTONE_DEBUG "Whether to enable extra debug assertions" OFF) option(CAPSTONE_DEBUG "Whether to enable extra debug assertions" OFF)
option(CAPSTONE_INSTALL "Generate install target" ${PROJECT_IS_TOP_LEVEL}) option(CAPSTONE_INSTALL "Generate install target" ${PROJECT_IS_TOP_LEVEL})
option(ENABLE_ASAN "Enable address sanitizer" OFF) option(ENABLE_ASAN "Enable address sanitizer" OFF)
option(ENABLE_COVERAGE "Enable test coverage" OFF)
if (ENABLE_ASAN) if (ENABLE_ASAN)
message("Enabling ASAN")
add_definitions(-DASAN_ENABLED) add_definitions(-DASAN_ENABLED)
add_compile_options(-fsanitize=address) add_compile_options(-fsanitize=address)
add_link_options(-fsanitize=address) add_link_options(-fsanitize=address)
endif() endif()
if (ENABLE_COVERAGE)
message("Enabling COVERAGE")
add_compile_options(--coverage)
add_link_options(--coverage)
endif()
# If building for OSX it's best to allow CMake to handle building both architectures # If building for OSX it's best to allow CMake to handle building both architectures
if(APPLE AND NOT CAPSTONE_BUILD_MACOS_THIN) if(APPLE AND NOT CAPSTONE_BUILD_MACOS_THIN)
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64") set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
@ -208,8 +216,6 @@ set(HEADERS_COMMON
include/capstone/loongarch.h include/capstone/loongarch.h
) )
set(TEST_SOURCES test_basic.c test_detail.c test_skipdata.c test_iter.c)
## architecture support ## architecture support
if(CAPSTONE_ARM_SUPPORT) if(CAPSTONE_ARM_SUPPORT)
add_definitions(-DCAPSTONE_HAS_ARM) add_definitions(-DCAPSTONE_HAS_ARM)
@ -239,7 +245,6 @@ if(CAPSTONE_ARM_SUPPORT)
arch/ARM/ARMGenCSMappingInsnName.inc arch/ARM/ARMGenCSMappingInsnName.inc
arch/ARM/ARMGenSystemRegister.inc arch/ARM/ARMGenSystemRegister.inc
) )
set(TEST_SOURCES ${TEST_SOURCES} test_arm.c)
endif() endif()
if(CAPSTONE_AARCH64_SUPPORT) if(CAPSTONE_AARCH64_SUPPORT)
@ -270,7 +275,6 @@ if(CAPSTONE_AARCH64_SUPPORT)
arch/AArch64/AArch64GenCSMappingInsnName.inc arch/AArch64/AArch64GenCSMappingInsnName.inc
arch/AArch64/AArch64GenCSMappingInsnOp.inc arch/AArch64/AArch64GenCSMappingInsnOp.inc
) )
set(TEST_SOURCES ${TEST_SOURCES} test_aarch64.c)
endif() endif()
if(CAPSTONE_MIPS_SUPPORT) if(CAPSTONE_MIPS_SUPPORT)
@ -302,7 +306,6 @@ if(CAPSTONE_MIPS_SUPPORT)
arch/Mips/MipsInstPrinter.h arch/Mips/MipsInstPrinter.h
arch/Mips/MipsMapping.h arch/Mips/MipsMapping.h
) )
set(TEST_SOURCES ${TEST_SOURCES} test_mips.c)
endif() endif()
if(CAPSTONE_PPC_SUPPORT) if(CAPSTONE_PPC_SUPPORT)
@ -332,7 +335,6 @@ if(CAPSTONE_PPC_SUPPORT)
arch/PowerPC/PPCGenSubtargetInfo.inc arch/PowerPC/PPCGenSubtargetInfo.inc
arch/PowerPC/PPCGenRegisterInfo.inc arch/PowerPC/PPCGenRegisterInfo.inc
) )
set(TEST_SOURCES ${TEST_SOURCES} test_ppc.c)
endif() endif()
if(CAPSTONE_X86_SUPPORT) if(CAPSTONE_X86_SUPPORT)
@ -386,7 +388,6 @@ if(CAPSTONE_X86_SUPPORT)
if(NOT CAPSTONE_BUILD_DIET) if(NOT CAPSTONE_BUILD_DIET)
set(SOURCES_X86 ${SOURCES_X86} arch/X86/X86ATTInstPrinter.c) set(SOURCES_X86 ${SOURCES_X86} arch/X86/X86ATTInstPrinter.c)
endif() endif()
set(TEST_SOURCES ${TEST_SOURCES} test_x86.c test_customized_mnem.c)
endif() endif()
if(CAPSTONE_SPARC_SUPPORT) if(CAPSTONE_SPARC_SUPPORT)
@ -409,7 +410,6 @@ if(CAPSTONE_SPARC_SUPPORT)
arch/Sparc/SparcMapping.h arch/Sparc/SparcMapping.h
arch/Sparc/SparcMappingInsn.inc arch/Sparc/SparcMappingInsn.inc
) )
set(TEST_SOURCES ${TEST_SOURCES} test_sparc.c)
endif() endif()
if(CAPSTONE_SYSZ_SUPPORT) if(CAPSTONE_SYSZ_SUPPORT)
@ -434,7 +434,6 @@ if(CAPSTONE_SYSZ_SUPPORT)
arch/SystemZ/SystemZMappingInsn.inc arch/SystemZ/SystemZMappingInsn.inc
arch/SystemZ/SystemZMCTargetDesc.h arch/SystemZ/SystemZMCTargetDesc.h
) )
set(TEST_SOURCES ${TEST_SOURCES} test_systemz.c)
endif() endif()
if(CAPSTONE_XCORE_SUPPORT) if(CAPSTONE_XCORE_SUPPORT)
@ -455,7 +454,6 @@ if(CAPSTONE_XCORE_SUPPORT)
arch/XCore/XCoreMapping.h arch/XCore/XCoreMapping.h
arch/XCore/XCoreMappingInsn.inc arch/XCore/XCoreMappingInsn.inc
) )
set(TEST_SOURCES ${TEST_SOURCES} test_xcore.c)
endif() endif()
if(CAPSTONE_M68K_SUPPORT) if(CAPSTONE_M68K_SUPPORT)
@ -468,7 +466,6 @@ if(CAPSTONE_M68K_SUPPORT)
set(HEADERS_M68K set(HEADERS_M68K
arch/M68K/M68KDisassembler.h arch/M68K/M68KDisassembler.h
) )
set(TEST_SOURCES ${TEST_SOURCES} test_m68k.c)
endif() endif()
if(CAPSTONE_TMS320C64X_SUPPORT) if(CAPSTONE_TMS320C64X_SUPPORT)
@ -488,7 +485,6 @@ if(CAPSTONE_TMS320C64X_SUPPORT)
arch/TMS320C64x/TMS320C64xInstPrinter.h arch/TMS320C64x/TMS320C64xInstPrinter.h
arch/TMS320C64x/TMS320C64xMapping.h arch/TMS320C64x/TMS320C64xMapping.h
) )
set(TEST_SOURCES ${TEST_SOURCES} test_tms320c64x.c)
endif() endif()
if(CAPSTONE_M680X_SUPPORT) if(CAPSTONE_M680X_SUPPORT)
@ -503,7 +499,6 @@ if(CAPSTONE_M680X_SUPPORT)
arch/M680X/M680XDisassembler.h arch/M680X/M680XDisassembler.h
arch/M680X/M680XDisassemblerInternals.h arch/M680X/M680XDisassemblerInternals.h
) )
set(TEST_SOURCES ${TEST_SOURCES} test_m680x.c)
endif() endif()
if(CAPSTONE_EVM_SUPPORT) if(CAPSTONE_EVM_SUPPORT)
@ -520,7 +515,6 @@ if(CAPSTONE_EVM_SUPPORT)
arch/EVM/EVMMapping.h arch/EVM/EVMMapping.h
arch/EVM/EVMMappingInsn.inc arch/EVM/EVMMappingInsn.inc
) )
set(TEST_SOURCES ${TEST_SOURCES} test_evm.c)
endif() endif()
if(CAPSTONE_WASM_SUPPORT) if(CAPSTONE_WASM_SUPPORT)
@ -536,7 +530,6 @@ if(CAPSTONE_WASM_SUPPORT)
arch/WASM/WASMInstPrinter.h arch/WASM/WASMInstPrinter.h
arch/WASM/WASMMapping.h arch/WASM/WASMMapping.h
) )
set(TEST_SOURCES ${TEST_SOURCES} test_wasm.c)
endif() endif()
if(CAPSTONE_MOS65XX_SUPPORT) if(CAPSTONE_MOS65XX_SUPPORT)
@ -547,7 +540,6 @@ if(CAPSTONE_MOS65XX_SUPPORT)
set(HEADERS_SOURCES_MOS65XX set(HEADERS_SOURCES_MOS65XX
arch/MOS65XX/MOS65XXDisassembler.h arch/MOS65XX/MOS65XXDisassembler.h
) )
set(TEST_SOURCES ${TEST_SOURCES} test_mos65xx.c)
endif() endif()
if(CAPSTONE_BPF_SUPPORT) if(CAPSTONE_BPF_SUPPORT)
@ -565,7 +557,6 @@ if(CAPSTONE_BPF_SUPPORT)
arch/BPF/BPFMapping.h arch/BPF/BPFMapping.h
arch/BPF/BPFModule.h arch/BPF/BPFModule.h
) )
set(TEST_SOURCES ${TEST_SOURCES} test_bpf.c)
endif() endif()
if(CAPSTONE_RISCV_SUPPORT) if(CAPSTONE_RISCV_SUPPORT)
@ -591,7 +582,6 @@ if(CAPSTONE_RISCV_SUPPORT)
arch/RISCV/RISCVMappingInsn.inc arch/RISCV/RISCVMappingInsn.inc
arch/RISCV/RISCVMappingInsnOp.inc arch/RISCV/RISCVMappingInsnOp.inc
) )
set(TEST_SOURCES ${TEST_SOURCES} test_riscv.c)
endif() endif()
if(CAPSTONE_SH_SUPPORT) if(CAPSTONE_SH_SUPPORT)
@ -607,7 +597,6 @@ if(CAPSTONE_SH_SUPPORT)
arch/SH/SHModule.h arch/SH/SHModule.h
arch/SH/SHInsnTable.inc arch/SH/SHInsnTable.inc
) )
set(TEST_SOURCES ${TEST_SOURCES} test_sh.c)
endif() endif()
if (CAPSTONE_TRICORE_SUPPORT) if (CAPSTONE_TRICORE_SUPPORT)
@ -628,7 +617,6 @@ if (CAPSTONE_TRICORE_SUPPORT)
arch/TriCore/TriCoreMapping.h arch/TriCore/TriCoreMapping.h
arch/TriCore/TriCoreModule.h arch/TriCore/TriCoreModule.h
) )
set(TEST_SOURCES ${TEST_SOURCES} test_tricore.c)
endif () endif ()
if (CAPSTONE_ALPHA_SUPPORT) if (CAPSTONE_ALPHA_SUPPORT)
@ -652,7 +640,6 @@ if (CAPSTONE_ALPHA_SUPPORT)
arch/Alpha/AlphaGenCSMappingInsn.inc arch/Alpha/AlphaGenCSMappingInsn.inc
arch/Alpha/AlphaGenCSMappingInsnName.inc arch/Alpha/AlphaGenCSMappingInsnName.inc
) )
set(TEST_SOURCES ${TEST_SOURCES} test_alpha.c)
endif () endif ()
if(CAPSTONE_HPPA_SUPPORT) if(CAPSTONE_HPPA_SUPPORT)
@ -670,7 +657,6 @@ if(CAPSTONE_HPPA_SUPPORT)
arch/HPPA/HPPAMapping.h arch/HPPA/HPPAMapping.h
arch/HPPA/HPPAModule.h arch/HPPA/HPPAModule.h
) )
set(TEST_SOURCES ${TEST_SOURCES} test_hppa.c)
endif() endif()
if (CAPSTONE_LOONGARCH_SUPPORT) if (CAPSTONE_LOONGARCH_SUPPORT)
@ -688,7 +674,6 @@ if (CAPSTONE_LOONGARCH_SUPPORT)
arch/LoongArch/LoongArchModule.h arch/LoongArch/LoongArchModule.h
arch/LoongArch/LoongArchLinkage.h arch/LoongArch/LoongArchLinkage.h
) )
set(TEST_SOURCES ${TEST_SOURCES} test_loongarch.c)
endif () endif ()
if (CAPSTONE_OSXKERNEL_SUPPORT) if (CAPSTONE_OSXKERNEL_SUPPORT)
@ -766,27 +751,13 @@ if(BUILD_SHARED_LIBS)
) )
endif() endif()
if(CAPSTONE_BUILD_TESTS) # Fuzzer if this is moved to it's own CMakeLists.txt (as it should be)
set(CMAKE_FOLDER "Tests") # the OSS fuzzer build fails. And must be fixed.
enable_testing() # Simply because it builds the fuzzer there again with hard-coded paths.
foreach(TSRC ${TEST_SOURCES}) # See: https://github.com/google/oss-fuzz/blob/master/projects/capstone/build.sh
string(REGEX REPLACE ".c$" "" TBIN ${TSRC}) # and: https://github.com/capstone-engine/capstone/issues/2454
add_executable(${TBIN} "tests/${TSRC}") add_executable(fuzz_disasm ${PROJECT_SOURCE_DIR}/suite/fuzz/onefile.c ${PROJECT_SOURCE_DIR}/suite/fuzz/fuzz_disasm.c ${PROJECT_SOURCE_DIR}/suite/fuzz/platform.c)
target_link_libraries(${TBIN} PRIVATE capstone) target_link_libraries(fuzz_disasm PRIVATE capstone)
add_test(NAME "capstone_${TBIN}" COMMAND ${TBIN})
endforeach()
if(CAPSTONE_ARM_SUPPORT)
set(ARM_REGRESS_TEST test_arm_regression.c)
string(REGEX REPLACE ".c$" "" ARM_REGRESS_BIN ${ARM_REGRESS_TEST})
add_executable(${ARM_REGRESS_BIN} "suite/arm/${ARM_REGRESS_TEST}")
target_link_libraries(${ARM_REGRESS_BIN} PRIVATE capstone)
add_test(NAME "capstone_${ARM_REGRESS_BIN}" COMMAND ${ARM_REGRESS_BIN})
endif()
# fuzz target built with the tests
add_executable(fuzz_disasm suite/fuzz/onefile.c suite/fuzz/fuzz_disasm.c suite/fuzz/platform.c)
target_link_libraries(fuzz_disasm PRIVATE capstone)
unset(CMAKE_FOLDER)
endif()
source_group("Source\\Engine" FILES ${SOURCES_ENGINE}) source_group("Source\\Engine" FILES ${SOURCES_ENGINE})
source_group("Source\\ARM" FILES ${SOURCES_ARM}) source_group("Source\\ARM" FILES ${SOURCES_ARM})
@ -900,7 +871,6 @@ if(CAPSTONE_INSTALL)
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY IMMEDIATE @ONLY
) )
set(CMAKE_FOLDER)
add_custom_target(UNINSTALL COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) add_custom_target(UNINSTALL COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
set_target_properties(UNINSTALL PROPERTIES set_target_properties(UNINSTALL PROPERTIES
FOLDER CMakePredefinedTargets FOLDER CMakePredefinedTargets
@ -919,32 +889,17 @@ if(CAPSTONE_BUILD_CSTOOL)
endif() endif()
if(CAPSTONE_BUILD_CSTEST) if(CAPSTONE_BUILD_CSTEST)
include(ExternalProject) enable_testing()
ExternalProject_Add(cmocka_ext set(CSTEST_DIR ${PROJECT_SOURCE_DIR}/suite/cstest)
PREFIX extern add_subdirectory(${CSTEST_DIR})
GIT_REPOSITORY "https://git.cryptomilk.org/projects/cmocka.git"
GIT_TAG "origin/stable-1.1"
GIT_SHALLOW true
CONFIGURE_COMMAND cmake -DBUILD_SHARED_LIBS=OFF ../cmocka_ext/
BUILD_COMMAND cmake --build . --config Release
INSTALL_COMMAND ""
)
set(CMOCKA_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern/src/cmocka_ext/include)
set(CMOCKA_LIB_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern/src/cmocka_ext-build/src/)
add_library(cmocka STATIC IMPORTED)
set_target_properties(cmocka PROPERTIES IMPORTED_LOCATION ${CMOCKA_LIB_DIR}/libcmocka.a)
file(GLOB CSTEST_SRC suite/cstest/src/*.c) # Integration and unit tests
add_executable(cstest ${CSTEST_SRC}) set(TESTS_INTEGRATION_DIR ${PROJECT_SOURCE_DIR}/tests/integration)
add_dependencies(cstest cmocka_ext) add_subdirectory(${TESTS_INTEGRATION_DIR})
target_link_libraries(cstest PUBLIC capstone cmocka) set(TESTS_UNIT_DIR ${PROJECT_SOURCE_DIR}/tests/unit)
target_include_directories(cstest PRIVATE add_subdirectory(${TESTS_UNIT_DIR})
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
${PROJECT_SOURCE_DIR}/suite/cstest/include
${CMOCKA_INCLUDE_DIR}
)
if(CAPSTONE_INSTALL) # Unit tests for auto-sync
install(TARGETS cstest EXPORT capstone-targets DESTINATION ${CMAKE_INSTALL_BINDIR}) set(AUTO_SYNC_C_TEST_DIR ${PROJECT_SOURCE_DIR}/suite/auto-sync/c_tests/)
endif() add_subdirectory(${AUTO_SYNC_C_TEST_DIR})
endif() endif()

View File

@ -1,8 +1,6 @@
This documentation explains how to compile Capstone with CMake, focus on This documentation explains how to compile Capstone with CMake, focus on
using Microsoft Visual C as the compiler. using Microsoft Visual C as the compiler.
To compile Capstone on *nix, see COMPILE.TXT.
To compile Capstone on Windows using Visual Studio, see COMPILE_MSVC.TXT. To compile Capstone on Windows using Visual Studio, see COMPILE_MSVC.TXT.
*-*-*-*-*-* *-*-*-*-*-*
@ -57,7 +55,7 @@ Get CMake for free from http://www.cmake.org.
- CAPSTONE_X86_REDUCE: change this to ON to make X86 binary smaller. - CAPSTONE_X86_REDUCE: change this to ON to make X86 binary smaller.
- CAPSTONE_X86_ATT_DISABLE: change this to ON to disable AT&T syntax on x86. - CAPSTONE_X86_ATT_DISABLE: change this to ON to disable AT&T syntax on x86.
- CAPSTONE_DEBUG: change this to ON to enable extra debug assertions. - CAPSTONE_DEBUG: change this to ON to enable extra debug assertions.
- CAPSTONE_BUILD_CSTEST: Build `cstest` in `suite/cstest/` - CAPSTONE_BUILD_CSTEST: Build `cstest` in `suite/cstest/`. `cstest` requires `libyaml` on your system.
- ENABLE_ASAN: Compiles Capstone with the address sanitizer. - ENABLE_ASAN: Compiles Capstone with the address sanitizer.
By default, Capstone use system dynamic memory management, and both DIET and X86_REDUCE By default, Capstone use system dynamic memory management, and both DIET and X86_REDUCE

View File

@ -1,3 +1,11 @@
# NOTICE
> Please be aware that the Makefile build is deprecated.
> Use cmake instead.
<hr>
This documentation explains how to compile, install & run Capstone on MacOSX, This documentation explains how to compile, install & run Capstone on MacOSX,
Linux, *BSD & Solaris. We also show steps to cross-compile for Microsoft Windows. Linux, *BSD & Solaris. We also show steps to cross-compile for Microsoft Windows.

View File

@ -1,7 +1,7 @@
This documentation explains how to compile Capstone on Windows using This documentation explains how to compile Capstone on Windows using
Microsoft Visual Studio version 2010 or newer. Microsoft Visual Studio version 2010 or newer.
To compile Capstone on *nix, see COMPILE.TXT To compile Capstone on *nix, see COMPILE_CMAKE.TXT
To compile Capstone with CMake, see COMPILE_CMAKE.TXT To compile Capstone with CMake, see COMPILE_CMAKE.TXT

View File

@ -3,7 +3,7 @@ Code structure
Capstone source is organized as followings. Capstone source is organized as followings.
. <- core engine + README + COMPILE.TXT etc . <- core engine + README + COMPILE_CMAKE.TXT etc
├── arch <- code handling disasm engine for each arch ├── arch <- code handling disasm engine for each arch
│   ├── AArch64 <- AArch64 engine │   ├── AArch64 <- AArch64 engine
│   ├── Alpha <- Alpha engine │   ├── Alpha <- Alpha engine
@ -39,7 +39,7 @@ Capstone source is organized as followings.
└── xcode <- Xcode support (for MacOSX compile) └── xcode <- Xcode support (for MacOSX compile)
Follow the instructions in COMPILE.TXT for how to compile and run test code. Follow the instructions in COMPILE_CMAKE.TXT for how to compile and run test code.
Note: if you find some strange bugs, it is recommended to firstly clean Note: if you find some strange bugs, it is recommended to firstly clean
the code and try to recompile/reinstall again. This can be done with: the code and try to recompile/reinstall again. This can be done with:
@ -111,13 +111,13 @@ Compile:
Tests: Tests:
- tests/Makefile - tests/Makefile
- tests/test_basic.c - tests/test_basic.c
- tests/test_detail.c
- tests/test_iter.c - tests/test_iter.c
- tests/test_newarch.c - tests/test_newarch.c
- suite/fuzz/platform.c: add the architecture and its modes to the list of fuzzed platforms - suite/fuzz/platform.c: add the architecture and its modes to the list of fuzzed platforms
- suite/capstone_get_setup.c - suite/capstone_get_setup.c
- suite/MC/newarch/mode.mc: samples - suite/MC/newarch/mode.mc: samples
- suite/test_corpus.py: correspondence between architecture and mode as text and architecture number for fuzzing - suite/test_corpus.py: correspondence between architecture and mode as text and architecture number for fuzzing
- suite/cstest/
Bindings: Bindings:
- bindings/Makefile - bindings/Makefile

View File

@ -457,12 +457,6 @@ PKGCFGF = $(BLDIR)/$(LIBNAME).pc
all: $(LIBRARY) $(ARCHIVE) $(PKGCFGF) all: $(LIBRARY) $(ARCHIVE) $(PKGCFGF)
ifeq (,$(findstring yes,$(CAPSTONE_BUILD_CORE_ONLY))) ifeq (,$(findstring yes,$(CAPSTONE_BUILD_CORE_ONLY)))
@V=$(V) CC=$(CC) $(MAKE) -C cstool @V=$(V) CC=$(CC) $(MAKE) -C cstool
ifndef BUILDDIR
$(MAKE) -C tests
else
$(MAKE) -C tests BUILDDIR=$(BLDIR)
endif
$(call install-library,$(BLDIR)/tests/)
endif endif
ifeq ($(CAPSTONE_SHARED),yes) ifeq ($(CAPSTONE_SHARED),yes)
@ -556,9 +550,7 @@ clean:
ifeq (,$(findstring yes,$(CAPSTONE_BUILD_CORE_ONLY))) ifeq (,$(findstring yes,$(CAPSTONE_BUILD_CORE_ONLY)))
$(MAKE) -C cstool clean $(MAKE) -C cstool clean
$(MAKE) -C tests clean
$(MAKE) -C suite/fuzz clean $(MAKE) -C suite/fuzz clean
rm -f $(BLDIR)/tests/lib$(LIBNAME).$(EXT)
endif endif
ifdef BUILDDIR ifdef BUILDDIR
@ -583,23 +575,8 @@ dist:
git archive --format=tar.gz --prefix=capstone-$(DIST_VERSION)/ $(TAG) > capstone-$(DIST_VERSION).tgz git archive --format=tar.gz --prefix=capstone-$(DIST_VERSION)/ $(TAG) > capstone-$(DIST_VERSION).tgz
git archive --format=zip --prefix=capstone-$(DIST_VERSION)/ $(TAG) > capstone-$(DIST_VERSION).zip git archive --format=zip --prefix=capstone-$(DIST_VERSION)/ $(TAG) > capstone-$(DIST_VERSION).zip
TESTS = test_basic test_detail test_arm test_aarch64 test_m68k test_mips test_ppc test_sparc test_tricore test_hppa
TESTS += test_systemz test_x86 test_xcore test_iter test_evm test_riscv test_mos65xx test_wasm test_bpf test_alpha
TESTS += test_loongarch
TESTS += test_basic.static test_detail.static test_arm.static test_aarch64.static
TESTS += test_m68k.static test_mips.static test_ppc.static test_sparc.static
TESTS += test_systemz.static test_x86.static test_xcore.static test_m680x.static
TESTS += test_skipdata test_skipdata.static test_iter.static test_evm.static test_riscv.static
TESTS += test_mos65xx.static test_wasm.static test_bpf.static test_alpha.static test_hppa.static
TESTS += test_loongarch.static
check: $(TESTS)
checkfuzz: fuzztest fuzzallcorp checkfuzz: fuzztest fuzzallcorp
test_%:
./tests/$@ > /dev/null && echo OK || echo FAILED
FUZZ_INPUTS = $(shell find suite/MC -type f -name '*.cs') FUZZ_INPUTS = $(shell find suite/MC -type f -name '*.cs')
buildfuzz: buildfuzz:

View File

@ -400,3 +400,44 @@ void map_set_alias_id(MCInst *MI, const SStream *O, const name_map *alias_mnem_i
MI->flat_insn->alias_id = name2id(alias_mnem_id_map, map_size, alias_mnem); MI->flat_insn->alias_id = name2id(alias_mnem_id_map, map_size, alias_mnem);
} }
/// Does a binary search over the given map and searches for @id.
/// If @id exists in @map, it sets @found to true and returns
/// the value for the @id.
/// Otherwise, @found is set to false and it returns UINT64_MAX.
///
/// Of course it assumes the map is sorted.
uint64_t enum_map_bin_search(const cs_enum_id_map *map, size_t map_len,
const char *id, bool *found)
{
size_t l = 0;
size_t r = map_len;
size_t id_len = strlen(id);
while (l <= r) {
size_t m = (l + r) / 2;
size_t j = 0;
size_t i = 0;
size_t entry_len = strlen(map[m].str);
while (j < entry_len && i < id_len && id[i] == map[m].str[j]) {
++j, ++i;
}
if (i == id_len && j == entry_len) {
*found = true;
return map[m].val;
}
if (id[i] < map[m].str[j]) {
r = m - 1;
} else if (id[i] > map[m].str[j]) {
l = m + 1;
}
if (m == 0 || (l + r) / 2 >= map_len) {
// Break before we go out of bounds.
break;
}
}
*found = false;
return UINT64_MAX;
}

View File

@ -232,4 +232,27 @@ bool map_use_alias_details(const MCInst *MI);
void map_set_alias_id(MCInst *MI, const SStream *O, const name_map *alias_mnem_id_map, int map_size); void map_set_alias_id(MCInst *MI, const SStream *O, const name_map *alias_mnem_id_map, int map_size);
/// Mapping from Capstone enumeration identifiers and their values.
///
/// This map MUST BE sorted to allow binary searches.
/// Please always ensure the map is sorted after you added a value.
///
/// You can sort the map with Python.
/// Copy the map into a file and run:
///
/// ```python
/// with open("/tmp/file_with_map_entries") as f:
/// text = f.readlines()
///
/// text.sort()
/// print(''.join(text))
/// ```
typedef struct {
const char *str; ///< The name of the enumeration identifier
uint64_t val; ///< The value of the identifier
} cs_enum_id_map;
uint64_t enum_map_bin_search(const cs_enum_id_map *map, size_t map_len,
const char *id, bool *found);
#endif // CS_MAPPING_H #endif // CS_MAPPING_H

View File

@ -49,7 +49,7 @@ Further information is available at https://www.capstone-engine.org
Compile Compile
------- -------
See COMPILE.TXT file for how to compile and install Capstone. See [COMPILE_CMAKE.TXT](COMPILE_CMAKE.TXT) file for how to compile and install Capstone.
Documentation Documentation

View File

@ -35510,6 +35510,7 @@ static DecodeStatus fname(const uint8_t DecodeTable[], MCInst *MI, \
/* Decoding complete. */ \ /* Decoding complete. */ \
return S; \ return S; \
} else { \ } else { \
MCInst_clear(MI); \
/* If the decoding was incomplete, skip. */ \ /* If the decoding was incomplete, skip. */ \
Ptr += NumToSkip; \ Ptr += NumToSkip; \
/* Reset decode status. This also drops a SoftFail status that could be */ \ /* Reset decode status. This also drops a SoftFail status that could be */ \

View File

@ -462,12 +462,18 @@ void printInst(MCInst *MI, uint64_t Address, const char *Annot, SStream *O)
if ((Opcode == AArch64_MOVZXi || Opcode == AArch64_MOVZWi || if ((Opcode == AArch64_MOVZXi || Opcode == AArch64_MOVZWi ||
Opcode == AArch64_MOVNXi || Opcode == AArch64_MOVNWi) && Opcode == AArch64_MOVNXi || Opcode == AArch64_MOVNWi) &&
MCOperand_isExpr(MCInst_getOperand(MI, (1)))) { MCOperand_isExpr(MCInst_getOperand(MI, (1)))) {
SStream_concat0(O, "<llvm-expr>"); printUInt64Bang(O, MCInst_getOpVal(MI, 1));
if (detail_is_set(MI) && useAliasDetails) {
AArch64_set_detail_op_imm(MI, 1, AARCH64_OP_IMM, MCInst_getOpVal(MI, 1));
}
} }
if ((Opcode == AArch64_MOVKXi || Opcode == AArch64_MOVKWi) && if ((Opcode == AArch64_MOVKXi || Opcode == AArch64_MOVKWi) &&
MCOperand_isExpr(MCInst_getOperand(MI, (2)))) { MCOperand_isExpr(MCInst_getOperand(MI, (2)))) {
SStream_concat0(O, "<llvm-expr>"); printUInt64Bang(O, MCInst_getOpVal(MI, 2));
if (detail_is_set(MI) && useAliasDetails) {
AArch64_set_detail_op_imm(MI, 2, AARCH64_OP_IMM, MCInst_getOpVal(MI, 2));
}
} }
// MOVZ, MOVN and "ORR wzr, #imm" instructions are aliases for MOV, but // MOVZ, MOVN and "ORR wzr, #imm" instructions are aliases for MOV, but
@ -994,7 +1000,7 @@ void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
printInt64Bang(O, MCOperand_getImm(Op)); printInt64Bang(O, MCOperand_getImm(Op));
SStream_concat0(O, markup(">")); SStream_concat0(O, markup(">"));
} else { } else {
SStream_concat0(O, "<llvm-expr>"); printUInt64Bang(O, MCInst_getOpVal(MI, OpNo));
} }
} }
@ -1282,7 +1288,7 @@ DEFINE_printRegWithShiftExtend(false, 128, x, 0);
assert(0 && \ assert(0 && \
"Unsupported predicate-as-counter register"); \ "Unsupported predicate-as-counter register"); \
SStream_concat(O, "%s", "pn"); \ SStream_concat(O, "%s", "pn"); \
printUInt32(O, (Reg - AArch64_P0)); \ printUInt32(O, (Reg - AArch64_PN0)); \
switch (EltSize) { \ switch (EltSize) { \
case 0: \ case 0: \
break; \ break; \
@ -1380,7 +1386,7 @@ void printUImm12Offset(MCInst *MI, unsigned OpNum, unsigned Scale, SStream *O)
printUInt32Bang(O, (MCOperand_getImm(MO) * Scale)); printUInt32Bang(O, (MCOperand_getImm(MO) * Scale));
SStream_concat0(O, markup(">")); SStream_concat0(O, markup(">"));
} else { } else {
SStream_concat0(O, "<llvm-expr>"); printUInt64Bang(O, MCOperand_getImm(MO));
} }
} }
@ -1395,7 +1401,7 @@ void printAMIndexedWB(MCInst *MI, unsigned OpNum, unsigned Scale, SStream *O)
printUInt32Bang(O, MCOperand_getImm(MO1) * Scale); printUInt32Bang(O, MCOperand_getImm(MO1) * Scale);
SStream_concat0(O, markup(">")); SStream_concat0(O, markup(">"));
} else { } else {
SStream_concat0(O, "<llvm-expr>"); printUInt64Bang(O, MCOperand_getImm(MO1));
} }
SStream_concat0(O, "]"); SStream_concat0(O, "]");
} }
@ -1964,7 +1970,7 @@ void printImplicitlyTypedVectorList(MCInst *MI, unsigned OpNum, SStream *O)
NumLanes), \ NumLanes), \
LaneKind), \ LaneKind), \
OpNum, NumLanes, CHAR(LaneKind)); \ OpNum, NumLanes, CHAR(LaneKind)); \
if (CHAR(LaneKind) == 0) { \ if (CHAR(LaneKind) == '0') { \
printVectorList(MI, OpNum, O, ""); \ printVectorList(MI, OpNum, O, ""); \
return; \ return; \
} \ } \
@ -2026,7 +2032,7 @@ void printAlignedLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
return; return;
} }
SStream_concat0(O, "<llvm-expr>"); printUInt64Bang(O, MCOperand_getImm(Op));
} }
void printAdrLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O) void printAdrLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
@ -2048,7 +2054,7 @@ void printAdrLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
return; return;
} }
SStream_concat0(O, "<llvm-expr>"); printUInt64Bang(O, MCOperand_getImm(Op));
} }
void printAdrpLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O) void printAdrpLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
@ -2070,7 +2076,7 @@ void printAdrpLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
return; return;
} }
SStream_concat0(O, "<llvm-expr>"); printUInt64Bang(O, MCOperand_getImm(Op));
} }
void printAdrAdrpLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O) { void printAdrAdrpLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O) {
@ -2095,7 +2101,7 @@ void printAdrAdrpLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
return; return;
} }
SStream_concat0(O, "<llvm-expr>"); printUInt64Bang(O, MCOperand_getImm(Op));
} }
void printBarrierOption(MCInst *MI, unsigned OpNo, SStream *O) void printBarrierOption(MCInst *MI, unsigned OpNo, SStream *O)
@ -2287,6 +2293,8 @@ void printSVEPattern(MCInst *MI, unsigned OpNum, SStream *O)
AArch64SVEPredPattern_lookupSVEPREDPATByEncoding(Val); AArch64SVEPredPattern_lookupSVEPREDPATByEncoding(Val);
if (Pat) if (Pat)
SStream_concat0(O, Pat->Name); SStream_concat0(O, Pat->Name);
else
printUInt32Bang(O, Val);
} }
void printSVEVecLenSpecifier(MCInst *MI, unsigned OpNum, SStream *O) void printSVEVecLenSpecifier(MCInst *MI, unsigned OpNum, SStream *O)
@ -2371,7 +2379,7 @@ DECLARE_printImmSVE_U64(uint64_t);
#define DEFINE_isSignedType(T) \ #define DEFINE_isSignedType(T) \
static inline bool CONCAT(isSignedType, T)() \ static inline bool CONCAT(isSignedType, T)() \
{ \ { \
return CHAR(t) == 'i'; \ return CHAR(T) == 'i'; \
} }
DEFINE_isSignedType(int8_t); DEFINE_isSignedType(int8_t);
DEFINE_isSignedType(int16_t); DEFINE_isSignedType(int16_t);

View File

@ -97,9 +97,9 @@ static void setup_sme_operand(MCInst *MI)
AArch64_get_detail_op(MI, 0)->sme.type = AARCH64_SME_OP_INVALID; AArch64_get_detail_op(MI, 0)->sme.type = AARCH64_SME_OP_INVALID;
AArch64_get_detail_op(MI, 0)->sme.tile = AARCH64_REG_INVALID; AArch64_get_detail_op(MI, 0)->sme.tile = AARCH64_REG_INVALID;
AArch64_get_detail_op(MI, 0)->sme.slice_reg = AARCH64_REG_INVALID; AArch64_get_detail_op(MI, 0)->sme.slice_reg = AARCH64_REG_INVALID;
AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm = -1; AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm = AARCH64_SLICE_IMM_INVALID;
AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm_range.first = -1; AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm_range.first = AARCH64_SLICE_IMM_RANGE_INVALID;
AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm_range.offset = -1; AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm_range.offset = AARCH64_SLICE_IMM_RANGE_INVALID;
} }
static void setup_pred_operand(MCInst *MI) static void setup_pred_operand(MCInst *MI)
@ -556,6 +556,9 @@ static void AArch64_add_not_defined_ops(MCInst *MI, const SStream *OS)
default: default:
return; return;
case AARCH64_INS_ALIAS_FMOV: case AARCH64_INS_ALIAS_FMOV:
if (AArch64_get_detail_op(MI, -1)->type == AARCH64_OP_FP) {
break;
}
AArch64_insert_detail_op_float_at(MI, -1, 0.0f, CS_AC_READ); AArch64_insert_detail_op_float_at(MI, -1, 0.0f, CS_AC_READ);
break; break;
case AARCH64_INS_ALIAS_LD1: case AARCH64_INS_ALIAS_LD1:
@ -1315,6 +1318,10 @@ static void add_cs_detail_general(MCInst *MI, aarch64_op_group op_group,
int64_t Offset = MCInst_getOpVal(MI, OpNum); int64_t Offset = MCInst_getOpVal(MI, OpNum);
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM, AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
(MI->address & -4) + Offset); (MI->address & -4) + Offset);
} else {
// Expression
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
MCOperand_isImm(MCInst_getOperand(MI, OpNum)));
} }
break; break;
} }
@ -1323,11 +1330,18 @@ static void add_cs_detail_general(MCInst *MI, aarch64_op_group op_group,
int64_t Offset = MCInst_getOpVal(MI, OpNum) * 4096; int64_t Offset = MCInst_getOpVal(MI, OpNum) * 4096;
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM, AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
(MI->address & -4096) + Offset); (MI->address & -4096) + Offset);
} else {
// Expression
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
MCOperand_isImm(MCInst_getOperand(MI, OpNum)));
} }
break; break;
} }
case AArch64_OP_GROUP_AdrAdrpLabel: { case AArch64_OP_GROUP_AdrAdrpLabel: {
if (!MCOperand_isImm(MCInst_getOperand(MI, OpNum))) { if (!MCOperand_isImm(MCInst_getOperand(MI, OpNum))) {
// Expression
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
MCOperand_isImm(MCInst_getOperand(MI, OpNum)));
break; break;
} }
int64_t Offset = MCInst_getOpVal(MI, OpNum); int64_t Offset = MCInst_getOpVal(MI, OpNum);
@ -1345,6 +1359,10 @@ static void add_cs_detail_general(MCInst *MI, aarch64_op_group op_group,
int64_t Offset = MCInst_getOpVal(MI, OpNum) * 4; int64_t Offset = MCInst_getOpVal(MI, OpNum) * 4;
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM, AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
MI->address + Offset); MI->address + Offset);
} else {
// Expression
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
MCOperand_isImm(MCInst_getOperand(MI, OpNum)));
} }
break; break;
} }
@ -1502,7 +1520,7 @@ static void add_cs_detail_general(MCInst *MI, aarch64_op_group op_group,
AArch64_set_detail_op_sme(MI, OpNum, AArch64_set_detail_op_sme(MI, OpNum,
AARCH64_SME_MATRIX_TILE_LIST, AARCH64_SME_MATRIX_TILE_LIST,
AARCH64LAYOUT_VL_D, AARCH64LAYOUT_VL_D,
AARCH64_REG_ZAD0 + I); (int) (AARCH64_REG_ZAD0 + I));
AArch64_inc_op_count(MI); AArch64_inc_op_count(MI);
} }
break; break;
@ -1607,8 +1625,10 @@ static void add_cs_detail_general(MCInst *MI, aarch64_op_group op_group,
unsigned Val = MCInst_getOpVal(MI, OpNum); unsigned Val = MCInst_getOpVal(MI, OpNum);
const AArch64SVEPredPattern_SVEPREDPAT *Pat = const AArch64SVEPredPattern_SVEPREDPAT *Pat =
AArch64SVEPredPattern_lookupSVEPREDPATByEncoding(Val); AArch64SVEPredPattern_lookupSVEPREDPATByEncoding(Val);
if (!Pat) if (!Pat) {
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM, Val);
break; break;
}
aarch64_sysop sysop; aarch64_sysop sysop;
sysop.alias = Pat->SysAlias; sysop.alias = Pat->SysAlias;
sysop.sub_type = AARCH64_OP_SVEPREDPAT; sysop.sub_type = AARCH64_OP_SVEPREDPAT;
@ -1738,6 +1758,7 @@ static void add_cs_detail_template_1(MCInst *MI, aarch64_op_group op_group,
(1 << AArch64_AM_getShiftValue(Shift)); (1 << AArch64_AM_getShiftValue(Shift));
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM, AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
Val); Val);
break;
} }
case AArch64_OP_GROUP_Imm8OptLsl_uint16_t: case AArch64_OP_GROUP_Imm8OptLsl_uint16_t:
case AArch64_OP_GROUP_Imm8OptLsl_uint32_t: case AArch64_OP_GROUP_Imm8OptLsl_uint32_t:
@ -1747,6 +1768,7 @@ static void add_cs_detail_template_1(MCInst *MI, aarch64_op_group op_group,
(1 << AArch64_AM_getShiftValue(Shift)); (1 << AArch64_AM_getShiftValue(Shift));
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM, AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
Val); Val);
break;
} }
} }
break; break;
@ -1791,7 +1813,7 @@ static void add_cs_detail_template_1(MCInst *MI, aarch64_op_group op_group,
AArch64_set_detail_op_sme(MI, OpNum, AArch64_set_detail_op_sme(MI, OpNum,
AARCH64_SME_MATRIX_SLICE_OFF, AARCH64_SME_MATRIX_SLICE_OFF,
AARCH64LAYOUT_INVALID, AARCH64LAYOUT_INVALID,
MCInst_getOpVal(MI, OpNum) * scale); (uint32_t) (MCInst_getOpVal(MI, OpNum) * scale));
} else if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_PRED) { } else if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_PRED) {
// The index is part of a predicate // The index is part of a predicate
AArch64_set_detail_op_pred(MI, OpNum); AArch64_set_detail_op_pred(MI, OpNum);
@ -1852,7 +1874,7 @@ static void add_cs_detail_template_1(MCInst *MI, aarch64_op_group op_group,
unsigned EltSize = temp_arg_0; unsigned EltSize = temp_arg_0;
AArch64_get_detail_op(MI, 0)->vas = EltSize; AArch64_get_detail_op(MI, 0)->vas = EltSize;
AArch64_set_detail_op_reg( AArch64_set_detail_op_reg(
MI, OpNum, MCInst_getOpVal(MI, OpNum) - AArch64_P0); MI, OpNum, MCInst_getOpVal(MI, OpNum) - AArch64_PN0);
break; break;
} }
case AArch64_OP_GROUP_PrefetchOp_0: case AArch64_OP_GROUP_PrefetchOp_0:
@ -1925,7 +1947,8 @@ static void add_cs_detail_template_1(MCInst *MI, aarch64_op_group op_group,
case AArch64_OP_GROUP_UImm12Offset_2: case AArch64_OP_GROUP_UImm12Offset_2:
case AArch64_OP_GROUP_UImm12Offset_4: case AArch64_OP_GROUP_UImm12Offset_4:
case AArch64_OP_GROUP_UImm12Offset_8: { case AArch64_OP_GROUP_UImm12Offset_8: {
unsigned Scale = temp_arg_0; // Otherwise it is an expression. For which we only add the immediate
unsigned Scale = MCOperand_isImm(MCInst_getOperand(MI, OpNum)) ? temp_arg_0 : 1;
AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM, AArch64_set_detail_op_imm(MI, OpNum, AARCH64_OP_IMM,
Scale * MCInst_getOpVal(MI, OpNum)); Scale * MCInst_getOpVal(MI, OpNum));
break; break;
@ -2050,6 +2073,7 @@ static void add_cs_detail_template_2(MCInst *MI, aarch64_op_group op_group,
case AArch64_OP_GROUP_TypedVectorList_0_h: case AArch64_OP_GROUP_TypedVectorList_0_h:
case AArch64_OP_GROUP_TypedVectorList_0_q: case AArch64_OP_GROUP_TypedVectorList_0_q:
case AArch64_OP_GROUP_TypedVectorList_0_s: case AArch64_OP_GROUP_TypedVectorList_0_s:
case AArch64_OP_GROUP_TypedVectorList_0_0:
case AArch64_OP_GROUP_TypedVectorList_16_b: case AArch64_OP_GROUP_TypedVectorList_16_b:
case AArch64_OP_GROUP_TypedVectorList_1_d: case AArch64_OP_GROUP_TypedVectorList_1_d:
case AArch64_OP_GROUP_TypedVectorList_2_d: case AArch64_OP_GROUP_TypedVectorList_2_d:
@ -2107,7 +2131,7 @@ static void add_cs_detail_template_2(MCInst *MI, aarch64_op_group op_group,
case 'q': case 'q':
vas = AARCH64LAYOUT_VL_Q; vas = AARCH64LAYOUT_VL_Q;
break; break;
case '\0': case '0':
// Implicitly Typed register // Implicitly Typed register
break; break;
} }
@ -2389,6 +2413,7 @@ void AArch64_add_cs_detail(MCInst *MI, int /* aarch64_op_group */ op_group,
case AArch64_OP_GROUP_TypedVectorList_0_h: case AArch64_OP_GROUP_TypedVectorList_0_h:
case AArch64_OP_GROUP_TypedVectorList_0_q: case AArch64_OP_GROUP_TypedVectorList_0_q:
case AArch64_OP_GROUP_TypedVectorList_0_s: case AArch64_OP_GROUP_TypedVectorList_0_s:
case AArch64_OP_GROUP_TypedVectorList_0_0:
case AArch64_OP_GROUP_TypedVectorList_16_b: case AArch64_OP_GROUP_TypedVectorList_16_b:
case AArch64_OP_GROUP_TypedVectorList_1_d: case AArch64_OP_GROUP_TypedVectorList_1_d:
case AArch64_OP_GROUP_TypedVectorList_2_d: case AArch64_OP_GROUP_TypedVectorList_2_d:
@ -2500,7 +2525,7 @@ void AArch64_set_detail_op_imm(MCInst *MI, unsigned OpNum,
if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_SME) { if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_SME) {
AArch64_set_detail_op_sme(MI, OpNum, AArch64_set_detail_op_sme(MI, OpNum,
AARCH64_SME_MATRIX_SLICE_OFF, AARCH64_SME_MATRIX_SLICE_OFF,
AARCH64LAYOUT_INVALID, 1); AARCH64LAYOUT_INVALID, (uint32_t) 1);
} else if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_PRED) { } else if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_PRED) {
AArch64_set_detail_op_pred(MI, OpNum); AArch64_set_detail_op_pred(MI, OpNum);
} else { } else {
@ -2524,7 +2549,7 @@ void AArch64_set_detail_op_imm(MCInst *MI, unsigned OpNum,
} }
void AArch64_set_detail_op_imm_range(MCInst *MI, unsigned OpNum, void AArch64_set_detail_op_imm_range(MCInst *MI, unsigned OpNum,
int64_t FirstImm, int64_t Offset) uint32_t FirstImm, uint32_t Offset)
{ {
if (!detail_is_set(MI)) if (!detail_is_set(MI))
return; return;
@ -2534,8 +2559,8 @@ void AArch64_set_detail_op_imm_range(MCInst *MI, unsigned OpNum,
if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_SME) { if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_SME) {
AArch64_set_detail_op_sme(MI, OpNum, AArch64_set_detail_op_sme(MI, OpNum,
AARCH64_SME_MATRIX_SLICE_OFF_RANGE, AARCH64_SME_MATRIX_SLICE_OFF_RANGE,
AARCH64LAYOUT_INVALID, FirstImm, AARCH64LAYOUT_INVALID, (uint32_t) FirstImm,
Offset); (uint32_t) Offset);
} else if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_PRED) { } else if (AArch64_get_detail_op(MI, 0)->type == AARCH64_OP_PRED) {
assert(0 && "Unkown SME predicate imm range type"); assert(0 && "Unkown SME predicate imm range type");
} else { } else {
@ -2694,15 +2719,15 @@ void AArch64_set_detail_op_sme(MCInst *MI, unsigned OpNum,
if (!detail_is_set(MI)) if (!detail_is_set(MI))
return; return;
AArch64_get_detail_op(MI, 0)->type = AARCH64_OP_SME; AArch64_get_detail_op(MI, 0)->type = AARCH64_OP_SME;
va_list args;
switch (part) { switch (part) {
default: default:
printf("Unhandled SME operand part %d\n", part); printf("Unhandled SME operand part %d\n", part);
assert(0); assert(0);
case AARCH64_SME_MATRIX_TILE_LIST: case AARCH64_SME_MATRIX_TILE_LIST: {
setup_sme_operand(MI); setup_sme_operand(MI);
va_list args;
va_start(args, vas); va_start(args, vas);
int Tile = va_arg(args, int); int Tile = va_arg(args, int); // NOLINT(clang-analyzer-valist.Uninitialized)
va_end(args); va_end(args);
AArch64_get_detail_op(MI, 0)->sme.type = AARCH64_SME_OP_TILE; AArch64_get_detail_op(MI, 0)->sme.type = AARCH64_SME_OP_TILE;
AArch64_get_detail_op(MI, 0)->sme.tile = Tile; AArch64_get_detail_op(MI, 0)->sme.tile = Tile;
@ -2710,6 +2735,7 @@ void AArch64_set_detail_op_sme(MCInst *MI, unsigned OpNum,
AArch64_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum); AArch64_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
AArch64_get_detail(MI)->is_doing_sme = true; AArch64_get_detail(MI)->is_doing_sme = true;
break; break;
}
case AARCH64_SME_MATRIX_TILE: case AARCH64_SME_MATRIX_TILE:
assert(map_get_op_type(MI, OpNum) == CS_OP_REG); assert(map_get_op_type(MI, OpNum) == CS_OP_REG);
@ -2731,23 +2757,26 @@ void AArch64_set_detail_op_sme(MCInst *MI, unsigned OpNum,
AArch64_get_detail_op(MI, 0)->sme.slice_reg = AArch64_get_detail_op(MI, 0)->sme.slice_reg =
MCInst_getOpVal(MI, OpNum); MCInst_getOpVal(MI, OpNum);
break; break;
case AARCH64_SME_MATRIX_SLICE_OFF: case AARCH64_SME_MATRIX_SLICE_OFF: {
assert((map_get_op_type(MI, OpNum) & ~(CS_OP_MEM | CS_OP_BOUND)) == CS_OP_IMM); assert((map_get_op_type(MI, OpNum) & ~(CS_OP_MEM | CS_OP_BOUND)) == CS_OP_IMM);
// Because we took care of the slice register before, the op at -1 must be a SME operand. // Because we took care of the slice register before, the op at -1 must be a SME operand.
assert(AArch64_get_detail_op(MI, 0)->type == assert(AArch64_get_detail_op(MI, 0)->type ==
AARCH64_OP_SME); AARCH64_OP_SME);
assert(AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm == assert(AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm ==
-1); AARCH64_SLICE_IMM_INVALID);
va_list args;
va_start(args, vas); va_start(args, vas);
int64_t offset = va_arg(args, int64_t); uint16_t offset = va_arg(args, uint32_t); // NOLINT(clang-analyzer-valist.Uninitialized)
va_end(args); va_end(args);
AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm = AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm =
offset; offset;
break; break;
}
case AARCH64_SME_MATRIX_SLICE_OFF_RANGE: { case AARCH64_SME_MATRIX_SLICE_OFF_RANGE: {
va_list args;
va_start(args, vas); va_start(args, vas);
int8_t First = va_arg(args, int); uint8_t First = va_arg(args, uint32_t); // NOLINT(clang-analyzer-valist.Uninitialized)
int8_t Offset = va_arg(args, int); uint8_t Offset = va_arg(args, uint32_t); // NOLINT(clang-analyzer-valist.Uninitialized)
va_end(args); va_end(args);
AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm_range.first = AArch64_get_detail_op(MI, 0)->sme.slice_offset.imm_range.first =
First; First;

View File

@ -56,7 +56,7 @@ void AArch64_set_detail_op_reg(MCInst *MI, unsigned OpNum, aarch64_reg Reg);
void AArch64_set_detail_op_imm(MCInst *MI, unsigned OpNum, void AArch64_set_detail_op_imm(MCInst *MI, unsigned OpNum,
aarch64_op_type ImmType, int64_t Imm); aarch64_op_type ImmType, int64_t Imm);
void AArch64_set_detail_op_imm_range(MCInst *MI, unsigned OpNum, void AArch64_set_detail_op_imm_range(MCInst *MI, unsigned OpNum,
int64_t FirstImm, int64_t offset); uint32_t FirstImm, uint32_t offset);
void AArch64_set_detail_op_mem(MCInst *MI, unsigned OpNum, uint64_t Val); void AArch64_set_detail_op_mem(MCInst *MI, unsigned OpNum, uint64_t Val);
void AArch64_set_detail_op_mem_offset(MCInst *MI, unsigned OpNum, uint64_t Val); void AArch64_set_detail_op_mem_offset(MCInst *MI, unsigned OpNum, uint64_t Val);
void AArch64_set_detail_shift_ext(MCInst *MI, unsigned OpNum, bool SignExtend, void AArch64_set_detail_shift_ext(MCInst *MI, unsigned OpNum, bool SignExtend,

View File

@ -32,8 +32,11 @@ cs_err ALPHA_global_init(cs_struct *ud)
cs_err ALPHA_option(cs_struct *handle, cs_opt_type type, size_t value) cs_err ALPHA_option(cs_struct *handle, cs_opt_type type, size_t value)
{ {
if (type == CS_OPT_SYNTAX) if (type == CS_OPT_SYNTAX) {
handle->syntax = (int)value; handle->syntax = (int)value;
} else if (type == CS_OPT_MODE) {
handle->mode = (cs_mode)value;
}
return CS_ERR_OK; return CS_ERR_OK;
} }

View File

@ -278,10 +278,10 @@ static unsigned int peek_imm_16(const m68k_info *info) { return m68k_read_safe_1
static unsigned int peek_imm_32(const m68k_info *info) { return m68k_read_safe_32((info), (info)->pc); } static unsigned int peek_imm_32(const m68k_info *info) { return m68k_read_safe_32((info), (info)->pc); }
static unsigned long long peek_imm_64(const m68k_info *info) { return m68k_read_safe_64((info), (info)->pc); } static unsigned long long peek_imm_64(const m68k_info *info) { return m68k_read_safe_64((info), (info)->pc); }
static unsigned int read_imm_8(m68k_info *info) { const unsigned int value = peek_imm_8(info); (info)->pc+=2; return value; } static unsigned int read_imm_8(m68k_info *info) { const unsigned int value = peek_imm_8(info); (info)->pc+=2; return value & 0xff; }
static unsigned int read_imm_16(m68k_info *info) { const unsigned int value = peek_imm_16(info); (info)->pc+=2; return value; } static unsigned int read_imm_16(m68k_info *info) { const unsigned int value = peek_imm_16(info); (info)->pc+=2; return value & 0xffff; }
static unsigned int read_imm_32(m68k_info *info) { const unsigned int value = peek_imm_32(info); (info)->pc+=4; return value; } static unsigned int read_imm_32(m68k_info *info) { const unsigned int value = peek_imm_32(info); (info)->pc+=4; return value & 0xffffffff; }
static unsigned long long read_imm_64(m68k_info *info) { const unsigned long long value = peek_imm_64(info); (info)->pc+=8; return value; } static unsigned long long read_imm_64(m68k_info *info) { const unsigned long long value = peek_imm_64(info); (info)->pc+=8; return value & 0xffffffffffffffff; }
/* Fake a split interface */ /* Fake a split interface */
#define get_ea_mode_str_8(instruction) get_ea_mode_str(instruction, 0) #define get_ea_mode_str_8(instruction) get_ea_mode_str(instruction, 0)
@ -472,9 +472,9 @@ static void get_ea_mode_op(m68k_info *info, cs_m68k_op* op, uint32_t instruction
op->type = M68K_OP_IMM; op->type = M68K_OP_IMM;
if (size == 1) if (size == 1)
op->imm = read_imm_8(info) & 0xff; op->imm = read_imm_8(info);
else if (size == 2) else if (size == 2)
op->imm = read_imm_16(info) & 0xffff; op->imm = read_imm_16(info);
else if (size == 4) else if (size == 4)
op->imm = read_imm_32(info); op->imm = read_imm_32(info);
else else
@ -604,7 +604,7 @@ static void build_imm_ea(m68k_info *info, int opcode, uint8_t size, int imm)
op0->type = M68K_OP_IMM; op0->type = M68K_OP_IMM;
op0->address_mode = M68K_AM_IMMEDIATE; op0->address_mode = M68K_AM_IMMEDIATE;
op0->imm = imm; op0->imm = imm & info->address_mask;
get_ea_mode_op(info, op1, info->ir, size); get_ea_mode_op(info, op1, info->ir, size);
} }
@ -878,7 +878,8 @@ static uint16_t reverse_bits(uint32_t v)
s--; s--;
} }
return r <<= s; // shift when v's highest bits are zero r <<= s; // shift when v's highest bits are zero
return r;
} }
static uint8_t reverse_bits_8(uint32_t v) static uint8_t reverse_bits_8(uint32_t v)
@ -892,7 +893,8 @@ static uint8_t reverse_bits_8(uint32_t v)
s--; s--;
} }
return r <<= s; // shift when v's highest bits are zero r <<= s; // shift when v's highest bits are zero
return r;
} }

View File

@ -1,17 +1,6 @@
/* Capstone Disassembly Engine */ /* Capstone Disassembly Engine */
/* M68K Backend by Daniel Collin <daniel@collin.com> 2015-2016 */ /* M68K Backend by Daniel Collin <daniel@collin.com> 2015-2016 */
#ifdef _MSC_VER
// Disable security warnings for strcat & sprintf
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
//Banned API Usage : strcat / sprintf is a Banned API as listed in dontuse.h for
//security purposes.
#pragma warning(disable:28719)
#endif
#include <stdio.h> // DEBUG #include <stdio.h> // DEBUG
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -78,7 +67,7 @@ static const char* getRegName(m68k_reg reg)
return s_reg_names[(int)reg]; return s_reg_names[(int)reg];
} }
static void printRegbitsRange(char* buffer, uint32_t data, const char* prefix) static void printRegbitsRange(char* buffer, size_t buf_len, uint32_t data, const char* prefix)
{ {
unsigned int first = 0; unsigned int first = 0;
unsigned int run_length = 0; unsigned int run_length = 0;
@ -95,11 +84,11 @@ static void printRegbitsRange(char* buffer, uint32_t data, const char* prefix)
} }
if (buffer[0] != 0) if (buffer[0] != 0)
strcat(buffer, "/"); strncat(buffer, "/", buf_len - 1);
sprintf(buffer + strlen(buffer), "%s%d", prefix, first); snprintf(buffer + strlen(buffer), buf_len, "%s%d", prefix, first);
if (run_length > 0) if (run_length > 0)
sprintf(buffer + strlen(buffer), "-%s%d", prefix, first + run_length); snprintf(buffer + strlen(buffer), buf_len, "-%s%d", prefix, first + run_length);
} }
} }
} }
@ -116,9 +105,9 @@ static void registerBits(SStream* O, const cs_m68k_op* op)
return; return;
} }
printRegbitsRange(buffer, data & 0xff, "d"); printRegbitsRange(buffer, sizeof(buffer), data & 0xff, "d");
printRegbitsRange(buffer, (data >> 8) & 0xff, "a"); printRegbitsRange(buffer, sizeof(buffer), (data >> 8) & 0xff, "a");
printRegbitsRange(buffer, (data >> 16) & 0xff, "fp"); printRegbitsRange(buffer, sizeof(buffer), (data >> 16) & 0xff, "fp");
SStream_concat(O, "%s", buffer); SStream_concat(O, "%s", buffer);
} }
@ -386,3 +375,24 @@ const char *M68K_group_name(csh handle, unsigned int id)
#endif #endif
} }
#ifndef CAPSTONE_DIET
void M68K_reg_access(const cs_insn *insn,
cs_regs regs_read, uint8_t *regs_read_count,
cs_regs regs_write, uint8_t *regs_write_count)
{
uint8_t read_count, write_count;
read_count = insn->detail->regs_read_count;
write_count = insn->detail->regs_write_count;
// implicit registers
memcpy(regs_read, insn->detail->regs_read,
read_count * sizeof(insn->detail->regs_read[0]));
memcpy(regs_write, insn->detail->regs_write,
write_count * sizeof(insn->detail->regs_write[0]));
*regs_read_count = read_count;
*regs_write_count = write_count;
}
#endif

View File

@ -17,5 +17,10 @@ void M68K_get_insn_id(cs_struct* h, cs_insn* insn, unsigned int id);
const char *M68K_insn_name(csh handle, unsigned int id); const char *M68K_insn_name(csh handle, unsigned int id);
const char* M68K_group_name(csh handle, unsigned int id); const char* M68K_group_name(csh handle, unsigned int id);
void M68K_post_printer(csh handle, cs_insn* flat_insn, char* insn_asm, MCInst* mci); void M68K_post_printer(csh handle, cs_insn* flat_insn, char* insn_asm, MCInst* mci);
#ifndef CAPSTONE_DIET
void M68K_reg_access(const cs_insn *insn,
cs_regs regs_read, uint8_t *regs_read_count,
cs_regs regs_write, uint8_t *regs_write_count);
#endif
#endif #endif

View File

@ -13,7 +13,7 @@ cs_err M68K_global_init(cs_struct *ud)
{ {
m68k_info *info; m68k_info *info;
info = cs_mem_malloc(sizeof(m68k_info)); info = cs_mem_calloc(sizeof(m68k_info), 1);
if (!info) { if (!info) {
return CS_ERR_MEM; return CS_ERR_MEM;
} }
@ -29,6 +29,9 @@ cs_err M68K_global_init(cs_struct *ud)
ud->insn_id = M68K_get_insn_id; ud->insn_id = M68K_get_insn_id;
ud->insn_name = M68K_insn_name; ud->insn_name = M68K_insn_name;
ud->group_name = M68K_group_name; ud->group_name = M68K_group_name;
#ifndef CAPSTONE_DIET
ud->reg_access = M68K_reg_access;
#endif
return CS_ERR_OK; return CS_ERR_OK;
} }

View File

@ -33,8 +33,11 @@ cs_err RISCV_global_init(cs_struct * ud)
cs_err RISCV_option(cs_struct * handle, cs_opt_type type, size_t value) cs_err RISCV_option(cs_struct * handle, cs_opt_type type, size_t value)
{ {
if (type == CS_OPT_SYNTAX) if (type == CS_OPT_SYNTAX) {
handle->syntax = (int)value; handle->syntax = (int)value;
} else if (type == CS_OPT_MODE) {
handle->mode = (cs_mode)value;
}
return CS_ERR_OK; return CS_ERR_OK;
} }

View File

@ -35,8 +35,11 @@ cs_err TRICORE_global_init(cs_struct *ud)
cs_err TRICORE_option(cs_struct *handle, cs_opt_type type, size_t value) cs_err TRICORE_option(cs_struct *handle, cs_opt_type type, size_t value)
{ {
if (type == CS_OPT_SYNTAX) if (type == CS_OPT_SYNTAX) {
handle->syntax = (int)value; handle->syntax = (int)value;
} else if (type == CS_OPT_MODE) {
handle->mode = (cs_mode)value;
}
return CS_ERR_OK; return CS_ERR_OK;
} }

View File

@ -288,9 +288,7 @@ static void get_op_access(cs_struct *h, unsigned int id, uint8_t *access, uint64
// initialize access // initialize access
memset(access, 0, CS_X86_MAXIMUM_OPERAND_SIZE * sizeof(access[0])); memset(access, 0, CS_X86_MAXIMUM_OPERAND_SIZE * sizeof(access[0]));
if (!arr) { if (!arr) {
access[0] = 0;
return; return;
} }
@ -302,7 +300,7 @@ static void get_op_access(cs_struct *h, unsigned int id, uint8_t *access, uint64
// copy in reverse order this access array from Intel syntax -> AT&T syntax // copy in reverse order this access array from Intel syntax -> AT&T syntax
count--; count--;
for(i = 0; i <= count; i++) { for(i = 0; i <= count && ((count - i) < CS_X86_MAXIMUM_OPERAND_SIZE) && i < CS_X86_MAXIMUM_OPERAND_SIZE; i++) {
if (arr[count - i] != CS_AC_IGNORE) if (arr[count - i] != CS_AC_IGNORE)
access[i] = arr[count - i]; access[i] = arr[count - i];
else else

View File

@ -1,150 +0,0 @@
TMPDIR = /tmp/capstone_test
DIFF = diff -u -w
TEST_BASIC = $(TMPDIR)/test_basic
TEST_DETAIL = $(TMPDIR)/test_detail
TEST_CUSTOMIZED_MNEM = $(TMPDIR)/test_customized_mnem
TEST_ARM = $(TMPDIR)/test_arm
TEST_ARM64 = $(TMPDIR)/test_aarch64
TEST_M68K = $(TMPDIR)/test_m68k
TEST_MIPS = $(TMPDIR)/test_mips
TEST_MOS65XX = $(TMPDIR)/test_mos65xx
TEST_PPC = $(TMPDIR)/test_ppc
TEST_SPARC = $(TMPDIR)/test_sparc
TEST_SYSZ = $(TMPDIR)/test_systemz
TEST_X86 = $(TMPDIR)/test_x86
TEST_XCORE = $(TMPDIR)/test_xcore
TEST_WASM = $(TMPDIR)/test_wasm
TEST_BPF = $(TMPDIR)/test_bpf
TEST_RISCV = $(TMPDIR)/test_riscv
TEST_EVM = $(TMPDIR)/test_evm
TEST_M680X = $(TMPDIR)/test_m680x
TEST_TRICORE = $(TMPDIR)/test_tricore
TEST_SH = $(TMPDIR)/test_sh
TEST_TMS320C64X = $(TMPDIR)/test_tms320c64x
TEST_ALPHA = $(TMPDIR)/test_alpha
TEST_HPPA = $(TMPDIR)/test_hppa
PYTHON3 ?= python3
BUILD_TESTS ?= yes
.PHONY: all expected python java ocaml
all:
cd python && $(MAKE) gen_const
cd java && $(MAKE) gen_const
cd ocaml && $(MAKE) gen_const
tests: expected python #java oclma ruby
test_java: expected java
test_python: expected python
expected:
if [ "$(BUILD_TESTS)" = "yes" ]; then cd ../tests && $(MAKE); fi
mkdir -p $(TMPDIR)
../tests/test_basic > $(TEST_BASIC)_e
../tests/test_detail > $(TEST_DETAIL)_e
../tests/test_customized_mnem > $(TEST_CUSTOMIZED_MNEM)_e
../tests/test_arm > $(TEST_ARM)_e
../tests/test_aarch64 > $(TEST_ARM64)_e
../tests/test_m68k > $(TEST_M68K)_e
../tests/test_mips > $(TEST_MIPS)_e
../tests/test_mos65xx > $(TEST_MOS65XX)_e
../tests/test_ppc > $(TEST_PPC)_e
../tests/test_sparc > $(TEST_SPARC)_e
../tests/test_systemz > $(TEST_SYSZ)_e
../tests/test_x86 > $(TEST_X86)_e
../tests/test_xcore > $(TEST_XCORE)_e
../tests/test_wasm > $(TEST_WASM)_e
../tests/test_bpf > $(TEST_BPF)_e
../tests/test_riscv > $(TEST_RISCV)_e
../tests/test_evm > $(TEST_EVM)_e
../tests/test_m680x > $(TEST_M680X)_e
../tests/test_sh > $(TEST_SH)_e
../tests/test_tricore > $(TEST_TRICORE)_e
../tests/test_tms320c64x > $(TEST_TMS320C64X)_e
../tests/test_alpha > $(TEST_ALPHA)_e
../tests/test_hppa > $(TEST_HPPA)_e
python: FORCE
cd python && $(MAKE)
$(PYTHON3) python/test_basic.py > $(TEST_BASIC)_o
$(PYTHON3) python/test_detail.py > $(TEST_DETAIL)_o
$(PYTHON3) python/test_customized_mnem.py > $(TEST_CUSTOMIZED_MNEM)_o
$(PYTHON3) python/test_arm.py > $(TEST_ARM)_o
$(PYTHON3) python/test_aarch64.py > $(TEST_ARM64)_o
$(PYTHON3) python/test_m68k.py > $(TEST_M68K)_o
$(PYTHON3) python/test_mips.py > $(TEST_MIPS)_o
$(PYTHON3) python/test_mos65xx.py > $(TEST_MOS65XX)_o
$(PYTHON3) python/test_ppc.py > $(TEST_PPC)_o
$(PYTHON3) python/test_sparc.py > $(TEST_SPARC)_o
$(PYTHON3) python/test_systemz.py > $(TEST_SYSZ)_o
$(PYTHON3) python/test_x86.py > $(TEST_X86)_o
$(PYTHON3) python/test_xcore.py > $(TEST_XCORE)_o
$(PYTHON3) python/test_wasm.py > $(TEST_WASM)_o
$(PYTHON3) python/test_bpf.py > $(TEST_BPF)_o
$(PYTHON3) python/test_riscv.py > $(TEST_RISCV)_o
$(PYTHON3) python/test_evm.py > $(TEST_EVM)_o
$(PYTHON3) python/test_m680x.py > $(TEST_M680X)_o
$(PYTHON3) python/test_sh.py > $(TEST_SH)_o
$(PYTHON3) python/test_tricore.py > $(TEST_TRICORE)_o
$(PYTHON3) python/test_tms320c64x.py > $(TEST_TMS320C64X)_o
$(PYTHON3) python/test_alpha.py > $(TEST_ALPHA)_o
$(PYTHON3) python/test_hppa.py > $(TEST_HPPA)_o
$(MAKE) test_diff
java: FORCE
cd java && $(MAKE)
cd java && ./run.sh > $(TEST_BASIC)_o
cd java && ./run.sh arm > $(TEST_ARM)_o
cd java && ./run.sh arm64 > $(TEST_ARM64)_o
cd java && ./run.sh mips > $(TEST_MIPS)_o
cd java && ./run.sh ppc > $(TEST_PPC)_o
cd java && ./run.sh sparc > $(TEST_SPARC)_o
cd java && ./run.sh systemz > $(TEST_SYSZ)_o
cd java && ./run.sh x86 > $(TEST_X86)_o
cd java && ./run.sh xcore > $(TEST_XCORE)_o
$(MAKE) test_diff
ocaml: FORCE
test_diff: FORCE
$(DIFF) $(TEST_BASIC)_e $(TEST_BASIC)_o
$(DIFF) $(TEST_DETAIL)_e $(TEST_DETAIL)_o
$(DIFF) $(TEST_CUSTOMIZED_MNEM)_e $(TEST_CUSTOMIZED_MNEM)_o
$(DIFF) $(TEST_ARM)_e $(TEST_ARM)_o
$(DIFF) $(TEST_ARM64)_e $(TEST_ARM64)_o
$(DIFF) $(TEST_M68K)_e $(TEST_M68K)_o
$(DIFF) $(TEST_MIPS)_e $(TEST_MIPS)_o
$(DIFF) $(TEST_MOS65XX)_e $(TEST_MOS65XX)_o
$(DIFF) $(TEST_PPC)_e $(TEST_PPC)_o
$(DIFF) $(TEST_SPARC)_e $(TEST_SPARC)_o
$(DIFF) $(TEST_SYSZ)_e $(TEST_SYSZ)_o
$(DIFF) $(TEST_X86)_e $(TEST_X86)_o
$(DIFF) $(TEST_XCORE)_e $(TEST_XCORE)_o
$(DIFF) $(TEST_WASM)_e $(TEST_WASM)_o
$(DIFF) $(TEST_BPF)_e $(TEST_BPF)_o
$(DIFF) $(TEST_RISCV)_e $(TEST_RISCV)_o
$(DIFF) $(TEST_EVM)_e $(TEST_EVM)_o
$(DIFF) $(TEST_M680X)_e $(TEST_M680X)_o
$(DIFF) $(TEST_SH)_e $(TEST_SH)_o
$(DIFF) $(TEST_TRICORE)_e $(TEST_TRICORE)_o
$(DIFF) $(TEST_TMS320C64X)_e $(TEST_TMS320C64X)_o
$(DIFF) $(TEST_ALPHA)_e $(TEST_ALPHA)_o
$(DIFF) $(TEST_HPPA)_e $(TEST_HPPA)_o
clean:
rm -rf $(TMPDIR)
cd java && $(MAKE) clean
cd python && $(MAKE) clean
cd ocaml && $(MAKE) clean
check:
make -C ocaml check
make -C python check
make -C java check
FORCE:

View File

@ -1,11 +1,12 @@
# Capstone Disassembler Engine # Capstone Disassembler Engine
# By Dang Hoang Vu, 2013 # By Dang Hoang Vu, 2013
from __future__ import print_function from __future__ import print_function
import sys, re import sys
import re
INCL_DIR = '../include/capstone/' INCL_DIR = '../include/capstone/'
include = [ 'arm.h', 'aarch64.h', 'm68k.h', 'mips.h', 'x86.h', 'ppc.h', 'sparc.h', 'systemz.h', 'xcore.h', 'tms320c64x.h', 'm680x.h', 'evm.h', 'mos65xx.h', 'wasm.h', 'bpf.h' ,'riscv.h', 'sh.h', 'tricore.h', 'alpha.h', 'hppa.h' ] include = [ 'arm.h', 'aarch64.h', 'm68k.h', 'mips.h', 'x86.h', 'ppc.h', 'sparc.h', 'systemz.h', 'xcore.h', 'tms320c64x.h', 'm680x.h', 'evm.h', 'mos65xx.h', 'wasm.h', 'bpf.h' ,'riscv.h', 'sh.h', 'tricore.h', 'alpha.h', 'hppa.h', 'loongarch.h' ]
template = { template = {
'java': { 'java': {
@ -56,6 +57,7 @@ template = {
'tricore.h': ['TRICORE', 'TriCore'], 'tricore.h': ['TRICORE', 'TriCore'],
'alpha.h': ['ALPHA', 'Alpha'], 'alpha.h': ['ALPHA', 'Alpha'],
'hppa.h': 'hppa', 'hppa.h': 'hppa',
'loongarch.h': 'loongarch',
'comment_open': '#', 'comment_open': '#',
'comment_close': '', 'comment_close': '',
}, },
@ -80,81 +82,6 @@ template = {
'comment_open': '(*', 'comment_open': '(*',
'comment_close': ' *)', 'comment_close': ' *)',
}, },
# 'swift': {
# 'header': "// For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT (%s)\n\n",
# 'footer': "",
# 'enum_doc': '/// %s\n',
# 'enum_header': 'public enum %s: %s {\n',
# 'enum_default_type': 'UInt32',
# 'enum_types': {
# 'UInt16': r'^\w+Reg$',
# 'UInt8': r'^\w+Grp$'
# },
# 'option_set_header': 'public struct %s: OptionSet {\n public typealias RawValue = %s\n public let rawValue: RawValue\n public init(rawValue: RawValue) { self.rawValue = rawValue }\n',
# 'option_sets': {
# 'X86Eflags': 'UInt64',
# 'X86FpuFlags': 'UInt64',
# 'SparcHint': 'UInt32',
# 'M680xIdx': 'UInt8',
# 'M680xOpFlags': 'UInt8',
# },
# 'rename': {
# r'^M680X_(\w+_OP_IN_MNEM)$': r'M680X_OP_FLAGS_\1',
# },
# 'option_format': ' public static let {option} = {type}(rawValue: {value})\n',
# 'enum_extra_options': {
# # swift enum != OptionSet, so options must be specified
# 'ArmSysreg': {
# 'spsrCx': 'spsrC + spsrX',
# 'spsrCs': 'spsrC + spsrS',
# 'spsrXs': 'spsrX + spsrS',
# 'spsrCxs': 'spsrC + spsrX + spsrS',
# 'spsrCf': 'spsrC + spsrF',
# 'spsrXf': 'spsrX + spsrF',
# 'spsrCxf': 'spsrC + spsrX + spsrF',
# 'spsrSf': 'spsrS + spsrF',
# 'spsrCsf': 'spsrC + spsrS + spsrF',
# 'spsrXsf': 'spsrX + spsrS + spsrF',
# 'spsrCxsf': 'spsrC + spsrX + spsrS + spsrF',
# 'cpsrCx': 'cpsrC + cpsrX',
# 'cpsrCs': 'cpsrC + cpsrS',
# 'cpsrXs': 'cpsrX + cpsrS',
# 'cpsrCxs': 'cpsrC + cpsrX + cpsrS',
# 'cpsrCf': 'cpsrC + cpsrF',
# 'cpsrXf': 'cpsrX + cpsrF',
# 'cpsrCxf': 'cpsrC + cpsrX + cpsrF',
# 'cpsrSf': 'cpsrS + cpsrF',
# 'cpsrCsf': 'cpsrC + cpsrS + cpsrF',
# 'cpsrXsf': 'cpsrX + cpsrS + cpsrF',
# 'cpsrCxsf': 'cpsrC + cpsrX + cpsrS + cpsrF',
# }
# },
# 'enum_footer': '}\n\n',
# 'doc_line_format': ' /// %s\n',
# 'line_format': ' case %s = %s\n',
# 'dup_line_format': ' public static let %s = %s\n',
# 'out_file': './swift/Sources/Capstone/%sEnums.swift',
# 'reserved_words': [
# 'break', 'class', 'for', 'false', 'in', 'init', 'return', 'true'
# ],
# 'reserved_word_format': '`%s`',
# # prefixes for constant filenames of all archs - case sensitive
# 'arm.h': 'Arm',
# 'arm64.h': 'Arm64',
# 'm68k.h': 'M68k',
# 'mips.h': 'Mips',
# 'x86.h': 'X86',
# 'ppc.h': 'Ppc',
# 'sparc.h': 'Sparc',
# 'systemz.h': 'Sysz',
# 'xcore.h': 'Xcore',
# 'tms320c64x.h': 'TMS320C64x',
# 'm680x.h': 'M680x',
# 'evm.h': 'Evm',
# 'mos65xx.h': 'Mos65xx',
# 'comment_open': '\t//',
# 'comment_close': '',
# },
} }
excluded_prefixes = { excluded_prefixes = {
@ -237,6 +164,11 @@ def gen(lang):
elif line.startswith('}') or line.startswith('#'): elif line.startswith('}') or line.startswith('#'):
doc_lines = [] doc_lines = []
pass pass
elif re.search(r"^(\s*typedef\s+)?enum", line):
# First new enum value should be 0.
# Because `rhs` is incremented later, it must be set to -1 here.
# Everything about this code is so broken -.-
rhs = "-1"
if line == '' or line.startswith('//'): if line == '' or line.startswith('//'):
continue continue
@ -251,7 +183,7 @@ def gen(lang):
xline.insert(1, '=') # insert an = so the expression below can parse it xline.insert(1, '=') # insert an = so the expression below can parse it
line = ' '.join(xline) line = ' '.join(xline)
def is_with_prefix(x): def has_special_arch_prefix(x):
if target in excluded_prefixes and any(x.startswith(excl_pre) for excl_pre in excluded_prefixes[target]): if target in excluded_prefixes and any(x.startswith(excl_pre) for excl_pre in excluded_prefixes[target]):
return False return False
if prefixs: if prefixs:
@ -259,7 +191,7 @@ def gen(lang):
else: else:
return x.startswith(prefix.upper()) return x.startswith(prefix.upper())
if not is_with_prefix(line): if not has_special_arch_prefix(line):
continue continue
tmp = line.strip().split(',') tmp = line.strip().split(',')
@ -271,7 +203,7 @@ def gen(lang):
t = re.sub(r'\((\d+)ULL << (\d+)\)', r'\1 << \2', t) # (1ULL<<1) to 1 << 1 t = re.sub(r'\((\d+)ULL << (\d+)\)', r'\1 << \2', t) # (1ULL<<1) to 1 << 1
f = re.split('\s+', t) f = re.split('\s+', t)
if not is_with_prefix(f[0]): if not has_special_arch_prefix(f[0]):
continue continue
if len(f) > 1 and f[1] not in ('//', '///<', '='): if len(f) > 1 and f[1] not in ('//', '///<', '='):

View File

@ -1,6 +1,5 @@
MANIFEST MANIFEST
dist/ dist/
src/
capstone/lib capstone/lib
capstone/include capstone/include
pyx/lib pyx/lib

View File

@ -4,17 +4,12 @@
1. To install Capstone and the Python bindings on *nix, run the command below: 1. To install Capstone and the Python bindings on *nix, run the command below:
$ sudo make install ```
pip install bindings/python/
To control the install destination, set the DESTDIR environment variable. ```
2. The tests directory contains some test code to show how to use the Capstone API. 2. The tests directory contains some test code to show how to use the Capstone API.
- test_basic.py
This code shows the most simple form of API where we only want to get basic
information out of disassembled instruction, such as address, mnemonic and
operand string.
- test_lite.py - test_lite.py
Similarly to test_basic.py, but this code shows how to use disasm_lite(), a lighter Similarly to test_basic.py, but this code shows how to use disasm_lite(), a lighter
method to disassemble binary. Unlike disasm() API (used by test_basic.py), which returns method to disassemble binary. Unlike disasm() API (used by test_basic.py), which returns
@ -23,12 +18,3 @@
The main reason for using this API is better performance: disasm_lite() is at least The main reason for using this API is better performance: disasm_lite() is at least
20% faster than disasm(). Memory usage is also less. So if you just need basic 20% faster than disasm(). Memory usage is also less. So if you just need basic
information out of disassembler, use disasm_lite() instead of disasm(). information out of disassembler, use disasm_lite() instead of disasm().
- test_detail.py:
This code shows how to access to architecture-neutral information in disassembled
instructions, such as implicit registers read/written, or groups of instructions
that this instruction belong to.
- test_<arch>.py
These code show how to access architecture-specific information for each
architecture.

View File

@ -40,6 +40,7 @@ __all__ = [
'CS_ARCH_TRICORE', 'CS_ARCH_TRICORE',
'CS_ARCH_ALPHA', 'CS_ARCH_ALPHA',
'CS_ARCH_HPPA', 'CS_ARCH_HPPA',
'CS_ARCH_LOONGARCH',
'CS_ARCH_ALL', 'CS_ARCH_ALL',
'CS_MODE_LITTLE_ENDIAN', 'CS_MODE_LITTLE_ENDIAN',
@ -107,6 +108,8 @@ __all__ = [
'CS_MODE_HPPA_11', 'CS_MODE_HPPA_11',
'CS_MODE_HPPA_20', 'CS_MODE_HPPA_20',
'CS_MODE_HPPA_20W', 'CS_MODE_HPPA_20W',
'CS_MODE_LOONGARCH32',
'CS_MODE_LOONGARCH64',
'CS_OPT_SYNTAX', 'CS_OPT_SYNTAX',
'CS_OPT_SYNTAX_DEFAULT', 'CS_OPT_SYNTAX_DEFAULT',
@ -225,6 +228,7 @@ CS_ARCH_SH = 16
CS_ARCH_TRICORE = 17 CS_ARCH_TRICORE = 17
CS_ARCH_ALPHA = 18 CS_ARCH_ALPHA = 18
CS_ARCH_HPPA = 19 CS_ARCH_HPPA = 19
CS_ARCH_LOONGARCH = 20
CS_ARCH_MAX = 20 CS_ARCH_MAX = 20
CS_ARCH_ALL = 0xFFFF CS_ARCH_ALL = 0xFFFF
@ -294,6 +298,8 @@ CS_MODE_TRICORE_162 = 1 << 7 # Tricore 1.6.2
CS_MODE_HPPA_11 = 1 << 1 # HPPA 1.1 CS_MODE_HPPA_11 = 1 << 1 # HPPA 1.1
CS_MODE_HPPA_20 = 1 << 2 # HPPA 2.0 CS_MODE_HPPA_20 = 1 << 2 # HPPA 2.0
CS_MODE_HPPA_20W = CS_MODE_HPPA_20 | (1 << 3) # HPPA 2.0 wide CS_MODE_HPPA_20W = CS_MODE_HPPA_20 | (1 << 3) # HPPA 2.0 wide
CS_MODE_LOONGARCH32 = 1 << 0
CS_MODE_LOONGARCH64 = 1 << 1
# Capstone option type # Capstone option type
CS_OPT_INVALID = 0 # No option specified CS_OPT_INVALID = 0 # No option specified
@ -347,16 +353,18 @@ CS_GRP_BRANCH_RELATIVE = 7 # all relative branching instructions
CS_AC_INVALID = 0 # Invalid/uninitialized access type. CS_AC_INVALID = 0 # Invalid/uninitialized access type.
CS_AC_READ = (1 << 0) # Operand that is read from. CS_AC_READ = (1 << 0) # Operand that is read from.
CS_AC_WRITE = (1 << 1) # Operand that is written to. CS_AC_WRITE = (1 << 1) # Operand that is written to.
CS_AC_READ_WRITE = (2) CS_AC_READ_WRITE = CS_AC_READ | CS_AC_WRITE
# Capstone syntax value # Capstone syntax value
CS_OPT_SYNTAX_DEFAULT = 1 << 1 # Default assembly syntax of all platforms (CS_OPT_SYNTAX) CS_OPT_SYNTAX_DEFAULT = (1 << 1) # Default assembly syntax of all platforms (CS_OPT_SYNTAX)
CS_OPT_SYNTAX_INTEL = 1 << 2 # Intel X86 asm syntax - default syntax on X86 (CS_OPT_SYNTAX, CS_ARCH_X86) CS_OPT_SYNTAX_INTEL = (1 << 2) # Intel X86 asm syntax - default syntax on X86 (CS_OPT_SYNTAX, CS_ARCH_X86)
CS_OPT_SYNTAX_ATT = 1 << 3 # ATT asm syntax (CS_OPT_SYNTAX, CS_ARCH_X86) CS_OPT_SYNTAX_ATT = (1 << 3) # ATT asm syntax (CS_OPT_SYNTAX, CS_ARCH_X86)
CS_OPT_SYNTAX_NOREGNAME = 1 << 4 # Asm syntax prints register name with only number - (CS_OPT_SYNTAX, CS_ARCH_PPC, CS_ARCH_ARM) CS_OPT_SYNTAX_NOREGNAME = (1 << 4) # Asm syntax prints register name with only number - (CS_OPT_SYNTAX, CS_ARCH_PPC, CS_ARCH_ARM)
CS_OPT_SYNTAX_MASM = 1 << 5 # MASM syntax (CS_OPT_SYNTAX, CS_ARCH_X86) CS_OPT_SYNTAX_MASM = (1 << 5) # MASM syntax (CS_OPT_SYNTAX, CS_ARCH_X86)
CS_OPT_SYNTAX_MOTOROLA = 1 << 6 # MOS65XX use $ as hex prefix CS_OPT_SYNTAX_MOTOROLA = (1 << 6) # MOS65XX use $ as hex prefix
CS_OPT_SYNTAX_CS_REG_ALIAS = 1 << 7 # Prints common register alias which are not defined in LLVM (ARM: r9 = sb etc.) CS_OPT_SYNTAX_CS_REG_ALIAS = (1 << 7) # Prints common register alias which are not defined in LLVM (ARM: r9 = sb etc.)
CS_OPT_SYNTAX_PERCENT = (1 << 8) # Prints the % in front of PPC registers.
CS_OPT_DETAIL_REAL = (1 << 1) # If enabled, always sets the real instruction detail.Even if the instruction is an alias.
# Capstone error type # Capstone error type
CS_ERR_OK = 0 # No error: everything was fine CS_ERR_OK = 0 # No error: everything was fine
@ -460,7 +468,7 @@ def copy_ctypes_list(src):
return [copy_ctypes(n) for n in src] return [copy_ctypes(n) for n in src]
# Weird import placement because these modules are needed by the below code but need the above functions # Weird import placement because these modules are needed by the below code but need the above functions
from . import arm, aarch64, m68k, mips, ppc, sparc, systemz, x86, xcore, tms320c64x, m680x, evm, mos65xx, wasm, bpf, riscv, sh, tricore, alpha, hppa from . import arm, aarch64, m68k, mips, ppc, sparc, systemz, x86, xcore, tms320c64x, m680x, evm, mos65xx, wasm, bpf, riscv, sh, tricore, alpha, hppa, loongarch
class _cs_arch(ctypes.Union): class _cs_arch(ctypes.Union):
_fields_ = ( _fields_ = (
@ -484,6 +492,7 @@ class _cs_arch(ctypes.Union):
('tricore', tricore.CsTriCore), ('tricore', tricore.CsTriCore),
('alpha', alpha.CsAlpha), ('alpha', alpha.CsAlpha),
('hppa', hppa.CsHPPA), ('hppa', hppa.CsHPPA),
('loongarch', loongarch.CsLoongArch),
) )
class _cs_detail(ctypes.Structure): class _cs_detail(ctypes.Structure):
@ -695,6 +704,21 @@ class CsInsn(object):
def size(self): def size(self):
return self._raw.size return self._raw.size
# return instruction's is_alias flag
@property
def is_alias(self):
return self._raw.is_alias
# return instruction's alias_id
@property
def alias_id(self):
return self._raw.alias_id
# return instruction's flag if it uses alias details
@property
def uses_alias_details(self):
return self._raw.usesAliasDetails
# return instruction's machine bytes (which should have @size bytes). # return instruction's machine bytes (which should have @size bytes).
@property @property
def bytes(self): def bytes(self):
@ -802,7 +826,7 @@ class CsInsn(object):
elif arch == CS_ARCH_MIPS: elif arch == CS_ARCH_MIPS:
self.operands = mips.get_arch_info(self._raw.detail.contents.arch.mips) self.operands = mips.get_arch_info(self._raw.detail.contents.arch.mips)
elif arch == CS_ARCH_PPC: elif arch == CS_ARCH_PPC:
(self.bc, self.update_cr0, self.operands) = \ (self.bc, self.update_cr0, self.format, self.operands) = \
ppc.get_arch_info(self._raw.detail.contents.arch.ppc) ppc.get_arch_info(self._raw.detail.contents.arch.ppc)
elif arch == CS_ARCH_SPARC: elif arch == CS_ARCH_SPARC:
(self.cc, self.hint, self.operands) = sparc.get_arch_info(self._raw.detail.contents.arch.sparc) (self.cc, self.hint, self.operands) = sparc.get_arch_info(self._raw.detail.contents.arch.sparc)
@ -832,6 +856,8 @@ class CsInsn(object):
(self.operands) = alpha.get_arch_info(self._raw.detail.contents.arch.alpha) (self.operands) = alpha.get_arch_info(self._raw.detail.contents.arch.alpha)
elif arch == CS_ARCH_HPPA: elif arch == CS_ARCH_HPPA:
(self.operands) = hppa.get_arch_info(self._raw.detail.contents.arch.hppa) (self.operands) = hppa.get_arch_info(self._raw.detail.contents.arch.hppa)
elif arch == CS_ARCH_LOONGARCH:
(self.format, self.operands) = loongarch.get_arch_info(self._raw.detail.contents.arch.loongarch)
def __getattr__(self, name): def __getattr__(self, name):
@ -840,14 +866,14 @@ class CsInsn(object):
attr = object.__getattribute__ attr = object.__getattribute__
if not attr(self, '_cs')._detail: if not attr(self, '_cs')._detail:
raise AttributeError(name) raise AttributeError(f"'CsInsn' has no attribute '{name}'")
_dict = attr(self, '__dict__') _dict = attr(self, '__dict__')
if 'operands' not in _dict: if 'operands' not in _dict:
self.__gen_detail() self.__gen_detail()
if name not in _dict: if name not in _dict:
if self._raw.id == 0: if self._raw.id == 0:
raise CsError(CS_ERR_SKIPDATA) raise CsError(CS_ERR_SKIPDATA)
raise AttributeError(name) raise AttributeError(f"'CsInsn' has no attribute '{name}'")
return _dict[name] return _dict[name]
# get the last error code # get the last error code
@ -1021,9 +1047,16 @@ class Cs(object):
except: # _cs might be pulled from under our feet except: # _cs might be pulled from under our feet
pass pass
def option(self, opt_type, opt_value):
# def option(self, opt_type, opt_value): status = _cs.cs_option(self.csh, opt_type, opt_value)
# return _cs.cs_option(self.csh, opt_type, opt_value) if status != CS_ERR_OK:
raise CsError(status)
if opt_type == CS_OPT_DETAIL:
self._detail = opt_value == CS_OPT_ON
elif opt_type == CS_OPT_SKIPDATA:
self._skipdata = opt_value == CS_OPT_ON
elif opt_type == CS_OPT_UNSIGNED:
self._imm_unsigned = opt_value == CS_OPT_ON
# is this a diet engine? # is this a diet engine?
@ -1321,7 +1354,7 @@ def debug():
"m680x": CS_ARCH_M680X, 'evm': CS_ARCH_EVM, 'mos65xx': CS_ARCH_MOS65XX, "m680x": CS_ARCH_M680X, 'evm': CS_ARCH_EVM, 'mos65xx': CS_ARCH_MOS65XX,
'bpf': CS_ARCH_BPF, 'riscv': CS_ARCH_RISCV, 'tricore': CS_ARCH_TRICORE, 'bpf': CS_ARCH_BPF, 'riscv': CS_ARCH_RISCV, 'tricore': CS_ARCH_TRICORE,
'wasm': CS_ARCH_WASM, 'sh': CS_ARCH_SH, 'alpha': CS_ARCH_ALPHA, 'wasm': CS_ARCH_WASM, 'sh': CS_ARCH_SH, 'alpha': CS_ARCH_ALPHA,
'hppa': CS_ARCH_HPPA 'hppa': CS_ARCH_HPPA, 'loongarch': CS_ARCH_LOONGARCH
} }
all_archs = "" all_archs = ""

View File

@ -14,7 +14,7 @@ class AArch64OpMem(ctypes.Structure):
class AArch64ImmRange(ctypes.Structure): class AArch64ImmRange(ctypes.Structure):
_fields_ = ( _fields_ = (
('imm', ctypes.c_int8), ('first', ctypes.c_int8),
('offset', ctypes.c_int8), ('offset', ctypes.c_int8),
) )

File diff suppressed because it is too large Load Diff

View File

@ -76,164 +76,166 @@ Alpha_REG_R31 = 64
Alpha_REG_ENDING = 65 Alpha_REG_ENDING = 65
# Alpha instruction # Alpha instruction
Alpha_INS_INVALID = 66
Alpha_INS_ADDL = 67 Alpha_INS_INVALID = 0
Alpha_INS_ADDQ = 68 Alpha_INS_ADDL = 1
Alpha_INS_ADDSsSU = 69 Alpha_INS_ADDQ = 2
Alpha_INS_ADDTsSU = 70 Alpha_INS_ADDSsSU = 3
Alpha_INS_AND = 71 Alpha_INS_ADDTsSU = 4
Alpha_INS_BEQ = 72 Alpha_INS_AND = 5
Alpha_INS_BGE = 73 Alpha_INS_BEQ = 6
Alpha_INS_BGT = 74 Alpha_INS_BGE = 7
Alpha_INS_BIC = 75 Alpha_INS_BGT = 8
Alpha_INS_BIS = 76 Alpha_INS_BIC = 9
Alpha_INS_BLBC = 77 Alpha_INS_BIS = 10
Alpha_INS_BLBS = 78 Alpha_INS_BLBC = 11
Alpha_INS_BLE = 79 Alpha_INS_BLBS = 12
Alpha_INS_BLT = 80 Alpha_INS_BLE = 13
Alpha_INS_BNE = 81 Alpha_INS_BLT = 14
Alpha_INS_BR = 82 Alpha_INS_BNE = 15
Alpha_INS_BSR = 83 Alpha_INS_BR = 16
Alpha_INS_CMOVEQ = 84 Alpha_INS_BSR = 17
Alpha_INS_CMOVGE = 85 Alpha_INS_CMOVEQ = 18
Alpha_INS_CMOVGT = 86 Alpha_INS_CMOVGE = 19
Alpha_INS_CMOVLBC = 87 Alpha_INS_CMOVGT = 20
Alpha_INS_CMOVLBS = 88 Alpha_INS_CMOVLBC = 21
Alpha_INS_CMOVLE = 89 Alpha_INS_CMOVLBS = 22
Alpha_INS_CMOVLT = 90 Alpha_INS_CMOVLE = 23
Alpha_INS_CMOVNE = 91 Alpha_INS_CMOVLT = 24
Alpha_INS_CMPBGE = 92 Alpha_INS_CMOVNE = 25
Alpha_INS_CMPEQ = 93 Alpha_INS_CMPBGE = 26
Alpha_INS_CMPLE = 94 Alpha_INS_CMPEQ = 27
Alpha_INS_CMPLT = 95 Alpha_INS_CMPLE = 28
Alpha_INS_CMPTEQsSU = 96 Alpha_INS_CMPLT = 29
Alpha_INS_CMPTLEsSU = 97 Alpha_INS_CMPTEQsSU = 30
Alpha_INS_CMPTLTsSU = 98 Alpha_INS_CMPTLEsSU = 31
Alpha_INS_CMPTUNsSU = 99 Alpha_INS_CMPTLTsSU = 32
Alpha_INS_CMPULE = 100 Alpha_INS_CMPTUNsSU = 33
Alpha_INS_CMPULT = 101 Alpha_INS_CMPULE = 34
Alpha_INS_COND_BRANCH = 102 Alpha_INS_CMPULT = 35
Alpha_INS_CPYSE = 103 Alpha_INS_COND_BRANCH = 36
Alpha_INS_CPYSN = 104 Alpha_INS_CPYSE = 37
Alpha_INS_CPYS = 105 Alpha_INS_CPYSN = 38
Alpha_INS_CTLZ = 106 Alpha_INS_CPYS = 39
Alpha_INS_CTPOP = 107 Alpha_INS_CTLZ = 40
Alpha_INS_CTTZ = 108 Alpha_INS_CTPOP = 41
Alpha_INS_CVTQSsSUI = 109 Alpha_INS_CTTZ = 42
Alpha_INS_CVTQTsSUI = 110 Alpha_INS_CVTQSsSUI = 43
Alpha_INS_CVTSTsS = 111 Alpha_INS_CVTQTsSUI = 44
Alpha_INS_CVTTQsSVC = 112 Alpha_INS_CVTSTsS = 45
Alpha_INS_CVTTSsSUI = 113 Alpha_INS_CVTTQsSVC = 46
Alpha_INS_DIVSsSU = 114 Alpha_INS_CVTTSsSUI = 47
Alpha_INS_DIVTsSU = 115 Alpha_INS_DIVSsSU = 48
Alpha_INS_ECB = 116 Alpha_INS_DIVTsSU = 49
Alpha_INS_EQV = 117 Alpha_INS_ECB = 50
Alpha_INS_EXCB = 118 Alpha_INS_EQV = 51
Alpha_INS_EXTBL = 119 Alpha_INS_EXCB = 52
Alpha_INS_EXTLH = 120 Alpha_INS_EXTBL = 53
Alpha_INS_EXTLL = 121 Alpha_INS_EXTLH = 54
Alpha_INS_EXTQH = 122 Alpha_INS_EXTLL = 55
Alpha_INS_EXTQL = 123 Alpha_INS_EXTQH = 56
Alpha_INS_EXTWH = 124 Alpha_INS_EXTQL = 57
Alpha_INS_EXTWL = 125 Alpha_INS_EXTWH = 58
Alpha_INS_FBEQ = 126 Alpha_INS_EXTWL = 59
Alpha_INS_FBGE = 127 Alpha_INS_FBEQ = 60
Alpha_INS_FBGT = 128 Alpha_INS_FBGE = 61
Alpha_INS_FBLE = 129 Alpha_INS_FBGT = 62
Alpha_INS_FBLT = 130 Alpha_INS_FBLE = 63
Alpha_INS_FBNE = 131 Alpha_INS_FBLT = 64
Alpha_INS_FCMOVEQ = 132 Alpha_INS_FBNE = 65
Alpha_INS_FCMOVGE = 133 Alpha_INS_FCMOVEQ = 66
Alpha_INS_FCMOVGT = 134 Alpha_INS_FCMOVGE = 67
Alpha_INS_FCMOVLE = 135 Alpha_INS_FCMOVGT = 68
Alpha_INS_FCMOVLT = 136 Alpha_INS_FCMOVLE = 69
Alpha_INS_FCMOVNE = 137 Alpha_INS_FCMOVLT = 70
Alpha_INS_FETCH = 138 Alpha_INS_FCMOVNE = 71
Alpha_INS_FETCH_M = 139 Alpha_INS_FETCH = 72
Alpha_INS_FTOIS = 140 Alpha_INS_FETCH_M = 73
Alpha_INS_FTOIT = 141 Alpha_INS_FTOIS = 74
Alpha_INS_INSBL = 142 Alpha_INS_FTOIT = 75
Alpha_INS_INSLH = 143 Alpha_INS_INSBL = 76
Alpha_INS_INSLL = 144 Alpha_INS_INSLH = 77
Alpha_INS_INSQH = 145 Alpha_INS_INSLL = 78
Alpha_INS_INSQL = 146 Alpha_INS_INSQH = 79
Alpha_INS_INSWH = 147 Alpha_INS_INSQL = 80
Alpha_INS_INSWL = 148 Alpha_INS_INSWH = 81
Alpha_INS_ITOFS = 149 Alpha_INS_INSWL = 82
Alpha_INS_ITOFT = 150 Alpha_INS_ITOFS = 83
Alpha_INS_JMP = 151 Alpha_INS_ITOFT = 84
Alpha_INS_JSR = 152 Alpha_INS_JMP = 85
Alpha_INS_JSR_COROUTINE = 153 Alpha_INS_JSR = 86
Alpha_INS_LDA = 154 Alpha_INS_JSR_COROUTINE = 87
Alpha_INS_LDAH = 155 Alpha_INS_LDA = 88
Alpha_INS_LDBU = 156 Alpha_INS_LDAH = 89
Alpha_INS_LDL = 157 Alpha_INS_LDBU = 90
Alpha_INS_LDL_L = 158 Alpha_INS_LDL = 91
Alpha_INS_LDQ = 159 Alpha_INS_LDL_L = 92
Alpha_INS_LDQ_L = 160 Alpha_INS_LDQ = 93
Alpha_INS_LDQ_U = 161 Alpha_INS_LDQ_L = 94
Alpha_INS_LDS = 162 Alpha_INS_LDQ_U = 95
Alpha_INS_LDT = 163 Alpha_INS_LDS = 96
Alpha_INS_LDWU = 164 Alpha_INS_LDT = 97
Alpha_INS_MB = 165 Alpha_INS_LDWU = 98
Alpha_INS_MSKBL = 166 Alpha_INS_MB = 99
Alpha_INS_MSKLH = 167 Alpha_INS_MSKBL = 100
Alpha_INS_MSKLL = 168 Alpha_INS_MSKLH = 101
Alpha_INS_MSKQH = 169 Alpha_INS_MSKLL = 102
Alpha_INS_MSKQL = 170 Alpha_INS_MSKQH = 103
Alpha_INS_MSKWH = 171 Alpha_INS_MSKQL = 104
Alpha_INS_MSKWL = 172 Alpha_INS_MSKWH = 105
Alpha_INS_MULL = 173 Alpha_INS_MSKWL = 106
Alpha_INS_MULQ = 174 Alpha_INS_MULL = 107
Alpha_INS_MULSsSU = 175 Alpha_INS_MULQ = 108
Alpha_INS_MULTsSU = 176 Alpha_INS_MULSsSU = 109
Alpha_INS_ORNOT = 177 Alpha_INS_MULTsSU = 110
Alpha_INS_RC = 178 Alpha_INS_ORNOT = 111
Alpha_INS_RET = 179 Alpha_INS_RC = 112
Alpha_INS_RPCC = 180 Alpha_INS_RET = 113
Alpha_INS_RS = 181 Alpha_INS_RPCC = 114
Alpha_INS_S4ADDL = 182 Alpha_INS_RS = 115
Alpha_INS_S4ADDQ = 183 Alpha_INS_S4ADDL = 116
Alpha_INS_S4SUBL = 184 Alpha_INS_S4ADDQ = 117
Alpha_INS_S4SUBQ = 185 Alpha_INS_S4SUBL = 118
Alpha_INS_S8ADDL = 186 Alpha_INS_S4SUBQ = 119
Alpha_INS_S8ADDQ = 187 Alpha_INS_S8ADDL = 120
Alpha_INS_S8SUBL = 188 Alpha_INS_S8ADDQ = 121
Alpha_INS_S8SUBQ = 189 Alpha_INS_S8SUBL = 122
Alpha_INS_SEXTB = 190 Alpha_INS_S8SUBQ = 123
Alpha_INS_SEXTW = 191 Alpha_INS_SEXTB = 124
Alpha_INS_SLL = 192 Alpha_INS_SEXTW = 125
Alpha_INS_SQRTSsSU = 193 Alpha_INS_SLL = 126
Alpha_INS_SQRTTsSU = 194 Alpha_INS_SQRTSsSU = 127
Alpha_INS_SRA = 195 Alpha_INS_SQRTTsSU = 128
Alpha_INS_SRL = 196 Alpha_INS_SRA = 129
Alpha_INS_STB = 197 Alpha_INS_SRL = 130
Alpha_INS_STL = 198 Alpha_INS_STB = 131
Alpha_INS_STL_C = 199 Alpha_INS_STL = 132
Alpha_INS_STQ = 200 Alpha_INS_STL_C = 133
Alpha_INS_STQ_C = 201 Alpha_INS_STQ = 134
Alpha_INS_STQ_U = 202 Alpha_INS_STQ_C = 135
Alpha_INS_STS = 203 Alpha_INS_STQ_U = 136
Alpha_INS_STT = 204 Alpha_INS_STS = 137
Alpha_INS_STW = 205 Alpha_INS_STT = 138
Alpha_INS_SUBL = 206 Alpha_INS_STW = 139
Alpha_INS_SUBQ = 207 Alpha_INS_SUBL = 140
Alpha_INS_SUBSsSU = 208 Alpha_INS_SUBQ = 141
Alpha_INS_SUBTsSU = 209 Alpha_INS_SUBSsSU = 142
Alpha_INS_TRAPB = 210 Alpha_INS_SUBTsSU = 143
Alpha_INS_UMULH = 211 Alpha_INS_TRAPB = 144
Alpha_INS_WH64 = 212 Alpha_INS_UMULH = 145
Alpha_INS_WH64EN = 213 Alpha_INS_WH64 = 146
Alpha_INS_WMB = 214 Alpha_INS_WH64EN = 147
Alpha_INS_XOR = 215 Alpha_INS_WMB = 148
Alpha_INS_ZAPNOT = 216 Alpha_INS_XOR = 149
ALPHA_INS_ENDING = 217 Alpha_INS_ZAPNOT = 150
ALPHA_INS_ENDING = 151
# Group of Alpha instructions # Group of Alpha instructions
Alpha_GRP_INVALID = 218
Alpha_GRP_INVALID = 0
# Generic groups # Generic groups
Alpha_GRP_CALL = 219 Alpha_GRP_CALL = 1
Alpha_GRP_JUMP = 220 Alpha_GRP_JUMP = 2
Alpha_GRP_BRANCH_RELATIVE = 221 Alpha_GRP_BRANCH_RELATIVE = 3
Alpha_GRP_ENDING = 222 Alpha_GRP_ENDING = 4

View File

@ -12,6 +12,7 @@ class ArmOpMem(ctypes.Structure):
('scale', ctypes.c_int), ('scale', ctypes.c_int),
('disp', ctypes.c_int), ('disp', ctypes.c_int),
('lshift', ctypes.c_int), ('lshift', ctypes.c_int),
('align', ctypes.c_uint),
) )
class ArmOpShift(ctypes.Structure): class ArmOpShift(ctypes.Structure):
@ -38,7 +39,7 @@ class ArmOpValue(ctypes.Union):
_fields_ = ( _fields_ = (
('reg', ctypes.c_uint), ('reg', ctypes.c_uint),
('sysop', ArmOpSysop), ('sysop', ArmOpSysop),
('imm', ctypes.c_int32), ('imm', ctypes.c_int64),
('pred', ctypes.c_int), ('pred', ctypes.c_int),
('fp', ctypes.c_double), ('fp', ctypes.c_double),
('mem', ArmOpMem), ('mem', ArmOpMem),

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,55 @@
# Copyright © 2024 Rot127 <unisono@quyllur.org>
# SPDX-License-Identifier: BSD-3
import ctypes
from . import copy_ctypes_list
from .loongarch_const import *
class LoongArchOpMem(ctypes.Structure):
_fields_ = (
("base", ctypes.c_uint),
("index", ctypes.c_uint),
("disp", ctypes.c_int64),
)
class LoongArchOpValue(ctypes.Union):
_fields_ = (
("reg", ctypes.c_uint),
("imm", ctypes.c_int64),
("mem", LoongArchOpMem),
)
class LoongArchOp(ctypes.Structure):
_fields_ = (
("type", ctypes.c_uint8),
("value", LoongArchOpValue),
("access", ctypes.c_uint8),
)
@property
def imm(self):
return self.value.imm
@property
def reg(self):
return self.value.reg
@property
def mem(self):
return self.value.mem
# Instruction structure
class CsLoongArch(ctypes.Structure):
_fields_ = (
("format", ctypes.c_int),
("op_count", ctypes.c_uint8),
("operands", LoongArchOp * 8)
)
def get_arch_info(a):
return a.format, copy_ctypes_list(a.operands[: a.op_count])

File diff suppressed because it is too large Load Diff

View File

@ -60,5 +60,5 @@ class CsPpc(ctypes.Structure):
) )
def get_arch_info(a): def get_arch_info(a):
return (a.bc, a.update_cr0, copy_ctypes_list(a.operands[:a.op_count])) return (a.bc, a.update_cr0, a.format, copy_ctypes_list(a.operands[:a.op_count]))

File diff suppressed because it is too large Load Diff

View File

@ -140,10 +140,11 @@ SH_OP_MEM_GBR_DISP = 6
SH_OP_MEM_GBR_R0 = 7 SH_OP_MEM_GBR_R0 = 7
SH_OP_MEM_PCR = 8 SH_OP_MEM_PCR = 8
SH_OP_MEM_TBR_DISP = 9 SH_OP_MEM_TBR_DISP = 9
SH_INS_DSP_INVALID = 10
SH_INS_DSP_DOUBLE = 11 SH_INS_DSP_INVALID = 0
SH_INS_DSP_SINGLE = 12 SH_INS_DSP_DOUBLE = 1
SH_INS_DSP_PARALLEL = 13 SH_INS_DSP_SINGLE = 2
SH_INS_DSP_PARALLEL = 3
SH_INS_DSP_NOP = 1 SH_INS_DSP_NOP = 1
SH_INS_DSP_MOV = 2 SH_INS_DSP_MOV = 2
SH_INS_DSP_PSHL = 3 SH_INS_DSP_PSHL = 3
@ -174,177 +175,180 @@ SH_INS_DSP_PLDS = 27
SH_INS_DSP_PSWAP = 28 SH_INS_DSP_PSWAP = 28
SH_INS_DSP_PWAD = 29 SH_INS_DSP_PWAD = 29
SH_INS_DSP_PWSB = 30 SH_INS_DSP_PWSB = 30
SH_OP_DSP_INVALID = 31
SH_OP_DSP_REG_PRE = 32 SH_OP_DSP_INVALID = 0
SH_OP_DSP_REG_IND = 33 SH_OP_DSP_REG_PRE = 1
SH_OP_DSP_REG_POST = 34 SH_OP_DSP_REG_IND = 2
SH_OP_DSP_REG_INDEX = 35 SH_OP_DSP_REG_POST = 3
SH_OP_DSP_REG = 36 SH_OP_DSP_REG_INDEX = 4
SH_OP_DSP_IMM = 37 SH_OP_DSP_REG = 5
SH_DSP_CC_INVALID = 38 SH_OP_DSP_IMM = 6
SH_DSP_CC_NONE = 39
SH_DSP_CC_DCT = 40 SH_DSP_CC_INVALID = 0
SH_DSP_CC_DCF = 41 SH_DSP_CC_NONE = 1
SH_INS_INVALID = 42 SH_DSP_CC_DCT = 2
SH_INS_ADD_r = 43 SH_DSP_CC_DCF = 3
SH_INS_ADD = 44
SH_INS_ADDC = 45 SH_INS_INVALID = 0
SH_INS_ADDV = 46 SH_INS_ADD_r = 1
SH_INS_AND = 47 SH_INS_ADD = 2
SH_INS_BAND = 48 SH_INS_ADDC = 3
SH_INS_BANDNOT = 49 SH_INS_ADDV = 4
SH_INS_BCLR = 50 SH_INS_AND = 5
SH_INS_BF = 51 SH_INS_BAND = 6
SH_INS_BF_S = 52 SH_INS_BANDNOT = 7
SH_INS_BLD = 53 SH_INS_BCLR = 8
SH_INS_BLDNOT = 54 SH_INS_BF = 9
SH_INS_BOR = 55 SH_INS_BF_S = 10
SH_INS_BORNOT = 56 SH_INS_BLD = 11
SH_INS_BRA = 57 SH_INS_BLDNOT = 12
SH_INS_BRAF = 58 SH_INS_BOR = 13
SH_INS_BSET = 59 SH_INS_BORNOT = 14
SH_INS_BSR = 60 SH_INS_BRA = 15
SH_INS_BSRF = 61 SH_INS_BRAF = 16
SH_INS_BST = 62 SH_INS_BSET = 17
SH_INS_BT = 63 SH_INS_BSR = 18
SH_INS_BT_S = 64 SH_INS_BSRF = 19
SH_INS_BXOR = 65 SH_INS_BST = 20
SH_INS_CLIPS = 66 SH_INS_BT = 21
SH_INS_CLIPU = 67 SH_INS_BT_S = 22
SH_INS_CLRDMXY = 68 SH_INS_BXOR = 23
SH_INS_CLRMAC = 69 SH_INS_CLIPS = 24
SH_INS_CLRS = 70 SH_INS_CLIPU = 25
SH_INS_CLRT = 71 SH_INS_CLRDMXY = 26
SH_INS_CMP_EQ = 72 SH_INS_CLRMAC = 27
SH_INS_CMP_GE = 73 SH_INS_CLRS = 28
SH_INS_CMP_GT = 74 SH_INS_CLRT = 29
SH_INS_CMP_HI = 75 SH_INS_CMP_EQ = 30
SH_INS_CMP_HS = 76 SH_INS_CMP_GE = 31
SH_INS_CMP_PL = 77 SH_INS_CMP_GT = 32
SH_INS_CMP_PZ = 78 SH_INS_CMP_HI = 33
SH_INS_CMP_STR = 79 SH_INS_CMP_HS = 34
SH_INS_DIV0S = 80 SH_INS_CMP_PL = 35
SH_INS_DIV0U = 81 SH_INS_CMP_PZ = 36
SH_INS_DIV1 = 82 SH_INS_CMP_STR = 37
SH_INS_DIVS = 83 SH_INS_DIV0S = 38
SH_INS_DIVU = 84 SH_INS_DIV0U = 39
SH_INS_DMULS_L = 85 SH_INS_DIV1 = 40
SH_INS_DMULU_L = 86 SH_INS_DIVS = 41
SH_INS_DT = 87 SH_INS_DIVU = 42
SH_INS_EXTS_B = 88 SH_INS_DMULS_L = 43
SH_INS_EXTS_W = 89 SH_INS_DMULU_L = 44
SH_INS_EXTU_B = 90 SH_INS_DT = 45
SH_INS_EXTU_W = 91 SH_INS_EXTS_B = 46
SH_INS_FABS = 92 SH_INS_EXTS_W = 47
SH_INS_FADD = 93 SH_INS_EXTU_B = 48
SH_INS_FCMP_EQ = 94 SH_INS_EXTU_W = 49
SH_INS_FCMP_GT = 95 SH_INS_FABS = 50
SH_INS_FCNVDS = 96 SH_INS_FADD = 51
SH_INS_FCNVSD = 97 SH_INS_FCMP_EQ = 52
SH_INS_FDIV = 98 SH_INS_FCMP_GT = 53
SH_INS_FIPR = 99 SH_INS_FCNVDS = 54
SH_INS_FLDI0 = 100 SH_INS_FCNVSD = 55
SH_INS_FLDI1 = 101 SH_INS_FDIV = 56
SH_INS_FLDS = 102 SH_INS_FIPR = 57
SH_INS_FLOAT = 103 SH_INS_FLDI0 = 58
SH_INS_FMAC = 104 SH_INS_FLDI1 = 59
SH_INS_FMOV = 105 SH_INS_FLDS = 60
SH_INS_FMUL = 106 SH_INS_FLOAT = 61
SH_INS_FNEG = 107 SH_INS_FMAC = 62
SH_INS_FPCHG = 108 SH_INS_FMOV = 63
SH_INS_FRCHG = 109 SH_INS_FMUL = 64
SH_INS_FSCA = 110 SH_INS_FNEG = 65
SH_INS_FSCHG = 111 SH_INS_FPCHG = 66
SH_INS_FSQRT = 112 SH_INS_FRCHG = 67
SH_INS_FSRRA = 113 SH_INS_FSCA = 68
SH_INS_FSTS = 114 SH_INS_FSCHG = 69
SH_INS_FSUB = 115 SH_INS_FSQRT = 70
SH_INS_FTRC = 116 SH_INS_FSRRA = 71
SH_INS_FTRV = 117 SH_INS_FSTS = 72
SH_INS_ICBI = 118 SH_INS_FSUB = 73
SH_INS_JMP = 119 SH_INS_FTRC = 74
SH_INS_JSR = 120 SH_INS_FTRV = 75
SH_INS_JSR_N = 121 SH_INS_ICBI = 76
SH_INS_LDBANK = 122 SH_INS_JMP = 77
SH_INS_LDC = 123 SH_INS_JSR = 78
SH_INS_LDRC = 124 SH_INS_JSR_N = 79
SH_INS_LDRE = 125 SH_INS_LDBANK = 80
SH_INS_LDRS = 126 SH_INS_LDC = 81
SH_INS_LDS = 127 SH_INS_LDRC = 82
SH_INS_LDTLB = 128 SH_INS_LDRE = 83
SH_INS_MAC_L = 129 SH_INS_LDRS = 84
SH_INS_MAC_W = 130 SH_INS_LDS = 85
SH_INS_MOV = 131 SH_INS_LDTLB = 86
SH_INS_MOVA = 132 SH_INS_MAC_L = 87
SH_INS_MOVCA = 133 SH_INS_MAC_W = 88
SH_INS_MOVCO = 134 SH_INS_MOV = 89
SH_INS_MOVI20 = 135 SH_INS_MOVA = 90
SH_INS_MOVI20S = 136 SH_INS_MOVCA = 91
SH_INS_MOVLI = 137 SH_INS_MOVCO = 92
SH_INS_MOVML = 138 SH_INS_MOVI20 = 93
SH_INS_MOVMU = 139 SH_INS_MOVI20S = 94
SH_INS_MOVRT = 140 SH_INS_MOVLI = 95
SH_INS_MOVT = 141 SH_INS_MOVML = 96
SH_INS_MOVU = 142 SH_INS_MOVMU = 97
SH_INS_MOVUA = 143 SH_INS_MOVRT = 98
SH_INS_MUL_L = 144 SH_INS_MOVT = 99
SH_INS_MULR = 145 SH_INS_MOVU = 100
SH_INS_MULS_W = 146 SH_INS_MOVUA = 101
SH_INS_MULU_W = 147 SH_INS_MUL_L = 102
SH_INS_NEG = 148 SH_INS_MULR = 103
SH_INS_NEGC = 149 SH_INS_MULS_W = 104
SH_INS_NOP = 150 SH_INS_MULU_W = 105
SH_INS_NOT = 151 SH_INS_NEG = 106
SH_INS_NOTT = 152 SH_INS_NEGC = 107
SH_INS_OCBI = 153 SH_INS_NOP = 108
SH_INS_OCBP = 154 SH_INS_NOT = 109
SH_INS_OCBWB = 155 SH_INS_NOTT = 110
SH_INS_OR = 156 SH_INS_OCBI = 111
SH_INS_PREF = 157 SH_INS_OCBP = 112
SH_INS_PREFI = 158 SH_INS_OCBWB = 113
SH_INS_RESBANK = 159 SH_INS_OR = 114
SH_INS_ROTCL = 160 SH_INS_PREF = 115
SH_INS_ROTCR = 161 SH_INS_PREFI = 116
SH_INS_ROTL = 162 SH_INS_RESBANK = 117
SH_INS_ROTR = 163 SH_INS_ROTCL = 118
SH_INS_RTE = 164 SH_INS_ROTCR = 119
SH_INS_RTS = 165 SH_INS_ROTL = 120
SH_INS_RTS_N = 166 SH_INS_ROTR = 121
SH_INS_RTV_N = 167 SH_INS_RTE = 122
SH_INS_SETDMX = 168 SH_INS_RTS = 123
SH_INS_SETDMY = 169 SH_INS_RTS_N = 124
SH_INS_SETRC = 170 SH_INS_RTV_N = 125
SH_INS_SETS = 171 SH_INS_SETDMX = 126
SH_INS_SETT = 172 SH_INS_SETDMY = 127
SH_INS_SHAD = 173 SH_INS_SETRC = 128
SH_INS_SHAL = 174 SH_INS_SETS = 129
SH_INS_SHAR = 175 SH_INS_SETT = 130
SH_INS_SHLD = 176 SH_INS_SHAD = 131
SH_INS_SHLL = 177 SH_INS_SHAL = 132
SH_INS_SHLL16 = 178 SH_INS_SHAR = 133
SH_INS_SHLL2 = 179 SH_INS_SHLD = 134
SH_INS_SHLL8 = 180 SH_INS_SHLL = 135
SH_INS_SHLR = 181 SH_INS_SHLL16 = 136
SH_INS_SHLR16 = 182 SH_INS_SHLL2 = 137
SH_INS_SHLR2 = 183 SH_INS_SHLL8 = 138
SH_INS_SHLR8 = 184 SH_INS_SHLR = 139
SH_INS_SLEEP = 185 SH_INS_SHLR16 = 140
SH_INS_STBANK = 186 SH_INS_SHLR2 = 141
SH_INS_STC = 187 SH_INS_SHLR8 = 142
SH_INS_STS = 188 SH_INS_SLEEP = 143
SH_INS_SUB = 189 SH_INS_STBANK = 144
SH_INS_SUBC = 190 SH_INS_STC = 145
SH_INS_SUBV = 191 SH_INS_STS = 146
SH_INS_SWAP_B = 192 SH_INS_SUB = 147
SH_INS_SWAP_W = 193 SH_INS_SUBC = 148
SH_INS_SYNCO = 194 SH_INS_SUBV = 149
SH_INS_TAS = 195 SH_INS_SWAP_B = 150
SH_INS_TRAPA = 196 SH_INS_SWAP_W = 151
SH_INS_TST = 197 SH_INS_SYNCO = 152
SH_INS_XOR = 198 SH_INS_TAS = 153
SH_INS_XTRCT = 199 SH_INS_TRAPA = 154
SH_INS_DSP = 200 SH_INS_TST = 155
SH_INS_ENDING = 201 SH_INS_XOR = 156
SH_INS_XTRCT = 157
SH_INS_DSP = 158
SH_INS_ENDING = 159
SH_GRP_INVALID = 0 SH_GRP_INVALID = 0
SH_GRP_JUMP = 1 SH_GRP_JUMP = 1

View File

@ -39,6 +39,8 @@ SPARC_HINT_INVALID = 0
SPARC_HINT_A = 1<<0 SPARC_HINT_A = 1<<0
SPARC_HINT_PT = 1<<1 SPARC_HINT_PT = 1<<1
SPARC_HINT_PN = 1<<2 SPARC_HINT_PN = 1<<2
SPARC_HINT_A_PN = SPARC_HINT_A|SPARC_HINT_PN
SPARC_HINT_A_PT = SPARC_HINT_A|SPARC_HINT_PT
SPARC_OP_INVALID = 0 SPARC_OP_INVALID = 0
SPARC_OP_REG = 1 SPARC_OP_REG = 1

View File

@ -461,10 +461,11 @@ TRICORE_INS_XOR_LT = 388
TRICORE_INS_XOR_NE = 389 TRICORE_INS_XOR_NE = 389
TRICORE_INS_XOR = 390 TRICORE_INS_XOR = 390
TRICORE_INS_ENDING = 391 TRICORE_INS_ENDING = 391
TRICORE_GRP_INVALID = 392
TRICORE_GRP_CALL = 393 TRICORE_GRP_INVALID = 0
TRICORE_GRP_JUMP = 394 TRICORE_GRP_CALL = 1
TRICORE_GRP_ENDING = 395 TRICORE_GRP_JUMP = 2
TRICORE_GRP_ENDING = 3
TRICORE_FEATURE_INVALID = 0 TRICORE_FEATURE_INVALID = 0
TRICORE_FEATURE_HasV110 = 128 TRICORE_FEATURE_HasV110 = 128

View File

@ -398,6 +398,7 @@ X86_AVX_RM_RN = 1
X86_AVX_RM_RD = 2 X86_AVX_RM_RD = 2
X86_AVX_RM_RU = 3 X86_AVX_RM_RU = 3
X86_AVX_RM_RZ = 4 X86_AVX_RM_RZ = 4
X86_PREFIX_0 = 0x0
X86_PREFIX_LOCK = 0xf0 X86_PREFIX_LOCK = 0xf0
X86_PREFIX_REP = 0xf3 X86_PREFIX_REP = 0xf3
X86_PREFIX_REPE = 0xf3 X86_PREFIX_REPE = 0xf3

View File

@ -0,0 +1,4 @@
## Python cstest
This is the equivalent testing tool to `suite/cstest/`. It consumes the `yaml` test files
in `<repo-root>/tests/` and reports the results.

View File

@ -0,0 +1,18 @@
# Copyright © 2024 Rot127 <unisono@quyllur.org>
# SPDX-License-Identifier: BSD-3
[project]
name = "cstest_py"
version = "0.1.0"
dependencies = [
"pyyaml >= 6.0.2",
"capstone >= 5.0.0",
]
requires-python = ">= 3.8"
[tool.setuptools]
packages = ["cstest_py"]
package-dir = {"" = "src"}
[project.scripts]
cstest_py = "cstest_py.cstest:main"

View File

@ -0,0 +1,337 @@
# Copyright © 2024 Rot127 <unisono@quyllur.org>
# SPDX-License-Identifier: BSD-3
# Typing for Python3.8
from __future__ import annotations
import struct
import capstone
import re
from capstone import arm_const
from capstone import aarch64_const
from capstone import m68k_const
from capstone import mips_const
from capstone import ppc_const
from capstone import sparc_const
from capstone import sysz_const
from capstone import x86_const
from capstone import xcore_const
from capstone import tms320c64x_const
from capstone import m680x_const
from capstone import evm_const
from capstone import mos65xx_const
from capstone import wasm_const
from capstone import bpf_const
from capstone import riscv_const
from capstone import sh_const
from capstone import tricore_const
from capstone import alpha_const
from capstone import hppa_const
from capstone import loongarch_const
def cs_const_getattr(identifier: str):
attr = getattr(capstone, identifier, None)
if attr is not None:
return attr
attr = getattr(arm_const, identifier, None)
if attr is not None:
return attr
attr = getattr(aarch64_const, identifier, None)
if attr is not None:
return attr
attr = getattr(m68k_const, identifier, None)
if attr is not None:
return attr
attr = getattr(mips_const, identifier, None)
if attr is not None:
return attr
attr = getattr(ppc_const, identifier, None)
if attr is not None:
return attr
attr = getattr(sparc_const, identifier, None)
if attr is not None:
return attr
attr = getattr(sysz_const, identifier, None)
if attr is not None:
return attr
attr = getattr(x86_const, identifier, None)
if attr is not None:
return attr
attr = getattr(xcore_const, identifier, None)
if attr is not None:
return attr
attr = getattr(tms320c64x_const, identifier, None)
if attr is not None:
return attr
attr = getattr(m680x_const, identifier, None)
if attr is not None:
return attr
attr = getattr(evm_const, identifier, None)
if attr is not None:
return attr
attr = getattr(mos65xx_const, identifier, None)
if attr is not None:
return attr
attr = getattr(wasm_const, identifier, None)
if attr is not None:
return attr
attr = getattr(bpf_const, identifier, None)
if attr is not None:
return attr
attr = getattr(riscv_const, identifier, None)
if attr is not None:
return attr
attr = getattr(sh_const, identifier, None)
if attr is not None:
return attr
attr = getattr(tricore_const, identifier, None)
if attr is not None:
return attr
attr = getattr(alpha_const, identifier, None)
if attr is not None:
return attr
attr = getattr(hppa_const, identifier, None)
if attr is not None:
return attr
attr = getattr(loongarch_const, identifier, None)
if attr is not None:
return attr
raise ValueError(f"Python capstone doesn't have the constant: {identifier}")
def twos_complement(val, bits):
if (val & (1 << (bits - 1))) != 0:
val = val - (1 << bits)
return val & ((1 << bits) - 1)
def normalize_asm_text(text: str, arch_bits: int) -> str:
text = text.strip()
text = re.sub(r"\s+", " ", text)
# Replace hex numbers with decimals
for hex_num in re.findall(r"0x[0-9a-fA-F]+", text):
text = re.sub(hex_num, f"{int(hex_num, base=16)}", text, count=1)
# Replace negatives with twos-complement
for num in re.findall(r"-\d+", text):
n = twos_complement(int(num, base=10), arch_bits)
text = re.sub(num, f"{n}", text)
text = text.lower()
return text
def compare_asm_text(
a_insn: capstone.CsInsn, expected: None | str, arch_bits: int
) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
actual = f"{a_insn.mnemonic} {a_insn.op_str}"
actual = normalize_asm_text(actual, arch_bits)
expected = normalize_asm_text(expected, arch_bits)
if actual != expected:
log.error(
"Normalized asm-text doesn't match:\n"
f"decoded: '{actual}'\n"
f"expected: '{expected}'\n"
)
return False
return True
def compare_str(actual: str, expected: None | str, msg: str) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
if actual != expected:
log.error(f"{msg}: {actual} != {expected}")
return False
return True
def compare_tbool(actual: bool, expected: None | int, msg: str) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
if expected == 0:
# Unset
return True
if (expected < 0 and actual) or (expected > 0 and not actual):
log.error(f"{msg}: {actual} != {expected}")
return False
return True
def compare_uint8(actual: int, expected: None | int, msg: str) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
actual = actual & 0xFF
expected = expected & 0xFF
if actual != expected:
log.error(f"{msg}: {actual} != {expected}")
return False
return True
def compare_int8(actual: int, expected: None | int, msg: str) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
actual = actual & 0xFF
expected = expected & 0xFF
if actual != expected:
log.error(f"{msg}: {actual} != {expected}")
return False
return True
def compare_uint16(actual: int, expected: None | int, msg: str) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
actual = actual & 0xFFFF
expected = expected & 0xFFFF
if actual != expected:
log.error(f"{msg}: {actual} != {expected}")
return False
return True
def compare_int16(actual: int, expected: None | int, msg: str) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
actual = actual & 0xFFFF
expected = expected & 0xFFFF
if actual != expected:
log.error(f"{msg}: {actual} != {expected}")
return False
return True
def compare_uint32(actual: int, expected: None | int, msg: str) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
actual = actual & 0xFFFFFFFF
expected = expected & 0xFFFFFFFF
if actual != expected:
log.error(f"{msg}: {actual} != {expected}")
return False
return True
def compare_int32(actual: int, expected: None | int, msg: str) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
actual = actual & 0xFFFFFFFF
expected = expected & 0xFFFFFFFF
if actual != expected:
log.error(f"{msg}: {actual} != {expected}")
return False
return True
def compare_uint64(actual: int, expected: None | int, msg: str) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
actual = actual & 0xFFFFFFFFFFFFFFFF
expected = expected & 0xFFFFFFFFFFFFFFFF
if actual != expected:
log.error(f"{msg}: {actual} != {expected}")
return False
return True
def compare_int64(actual: int, expected: None | int, msg: str) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
actual = actual & 0xFFFFFFFFFFFFFFFF
expected = expected & 0xFFFFFFFFFFFFFFFF
if actual != expected:
log.error(f"{msg}: {actual} != {expected}")
return False
return True
def compare_fp(actual: float, expected: None | float, msg: str) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
def floatToBits(f):
return struct.unpack("=L", struct.pack("=f", f))[0]
if floatToBits(actual) != floatToBits(expected):
log.error(f"{msg}: {actual} != {expected}")
return False
return True
def compare_dp(actual: float, expected: None | float, msg: str) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
def doubleToBits(f):
return struct.unpack("=Q", struct.pack("=d", f))[0]
if doubleToBits(actual) != doubleToBits(expected):
log.error(f"{msg}: {actual} != {expected}")
return False
return True
def compare_enum(actual, expected: None | str, msg: str) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
enum_val = cs_const_getattr(expected)
if actual != enum_val:
log.error(f"{msg}: {actual} != {expected} ({enum_val})")
return False
return True
def compare_bit_flags(actual: int, expected: None | list[str], msg: str) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
for flag in expected:
enum_val = cs_const_getattr(flag)
if not actual & enum_val:
log.error(f"{msg}: In {actual:x} the flag {expected} isn't set.")
return False
return True
def compare_reg(
insn: capstone.CsInsn, actual: int, expected: None | str, msg: str
) -> bool:
if expected is None:
return True
from cstest_py.cstest import log
if insn.reg_name(actual) != expected:
log.error(f"{msg}: {actual} != {expected}")
return False
return True

View File

@ -0,0 +1,41 @@
# Copyright © 2024 Rot127 <unisono@quyllur.org>
# SPDX-License-Identifier: BSD-3
import capstone as cs
configs = {
"CS_OPT_DETAIL": {"type": cs.CS_OPT_DETAIL, "val": cs.CS_OPT_ON},
"CS_OPT_DETAIL_REAL": {
"type": cs.CS_OPT_DETAIL,
"val": cs.CS_OPT_DETAIL_REAL | cs.CS_OPT_ON,
},
"CS_OPT_SKIPDATA": {"type": cs.CS_OPT_SKIPDATA, "val": cs.CS_OPT_ON},
"CS_OPT_UNSIGNED": {"type": cs.CS_OPT_UNSIGNED, "val": cs.CS_OPT_ON},
"CS_OPT_NO_BRANCH_OFFSET": {
"type": cs.CS_OPT_NO_BRANCH_OFFSET,
"val": cs.CS_OPT_ON,
},
"CS_OPT_SYNTAX_DEFAULT": {
"type": cs.CS_OPT_SYNTAX,
"val": cs.CS_OPT_SYNTAX_DEFAULT,
},
"CS_OPT_SYNTAX_INTEL": {"type": cs.CS_OPT_SYNTAX, "val": cs.CS_OPT_SYNTAX_INTEL},
"CS_OPT_SYNTAX_ATT": {"type": cs.CS_OPT_SYNTAX, "val": cs.CS_OPT_SYNTAX_ATT},
"CS_OPT_SYNTAX_NOREGNAME": {
"type": cs.CS_OPT_SYNTAX,
"val": cs.CS_OPT_SYNTAX_NOREGNAME,
},
"CS_OPT_SYNTAX_MASM": {"type": cs.CS_OPT_SYNTAX, "val": cs.CS_OPT_SYNTAX_MASM},
"CS_OPT_SYNTAX_MOTOROLA": {
"type": cs.CS_OPT_SYNTAX,
"val": cs.CS_OPT_SYNTAX_MOTOROLA,
},
"CS_OPT_SYNTAX_CS_REG_ALIAS": {
"type": cs.CS_OPT_SYNTAX,
"val": cs.CS_OPT_SYNTAX_CS_REG_ALIAS,
},
"CS_OPT_SYNTAX_PERCENT": {
"type": cs.CS_OPT_SYNTAX,
"val": cs.CS_OPT_SYNTAX_PERCENT,
},
}

View File

@ -0,0 +1,493 @@
#!/usr/bin/env python3
# Copyright © 2024 Rot127 <unisono@quyllur.org>
# SPDX-License-Identifier: BSD-3
# Typing for Python3.8
from __future__ import annotations
import argparse
import logging
import subprocess as sp
import sys
import os
import yaml
import capstone
import traceback
from capstone import CsInsn, Cs, CS_ARCH_AARCH64, CS_MODE_64, CS_MODE_16
from cstest_py.cs_modes import configs
from cstest_py.details import compare_details
from cstest_py.compare import (
compare_asm_text,
compare_str,
compare_tbool,
compare_uint32,
)
from enum import Enum
from pathlib import Path
log = logging.getLogger("__name__")
def get_cs_int_attr(cs, attr: str, err_msg_pre: str):
try:
attr_int = getattr(cs, attr)
if not isinstance(attr_int, int):
raise AttributeError(f"{attr} not found")
return attr_int
except AttributeError:
log.warning(f"{err_msg_pre}: Capstone doesn't have the attribute '{attr}'")
return None
def arch_bits(arch: int, mode: int) -> int:
if arch == CS_ARCH_AARCH64 or mode & CS_MODE_64:
return 64
elif mode & CS_MODE_16:
return 16
return 32
class TestResult(Enum):
SUCCESS = 0
FAILED = 1
SKIPPED = 2
ERROR = 3
class TestStats:
def __init__(self, total_file_count: int):
self.total_file_count = total_file_count
self.valid_test_files = 0
self.test_case_count = 0
self.success = 0
self.failed = 0
self.skipped = 0
self.errors = 0
self.invalid_files = 0
self.total_valid_files = 0
self.err_msgs: list[str] = list()
self.failing_files = set()
def add_failing_file(self, test_file: Path):
self.failing_files.add(test_file)
def add_error_msg(self, msg: str):
self.err_msgs.append(msg)
def add_invalid_file_dp(self, tfile: Path):
self.invalid_files += 1
self.errors += 1
self.add_failing_file(tfile)
def add_test_case_data_point(self, dp: TestResult):
if dp == TestResult.SUCCESS:
self.success += 1
elif dp == TestResult.FAILED:
self.failed += 1
elif dp == TestResult.SKIPPED:
self.skipped += 1
elif dp == TestResult.ERROR:
self.errors += 1
self.failed += 1
else:
raise ValueError(f"Unhandled TestResult: {dp}")
def set_total_valid_files(self, total_valid_files: int):
self.total_valid_files = total_valid_files
def set_total_test_cases(self, total_test_cases: int):
self.test_case_count = total_test_cases
def get_test_case_count(self) -> int:
return self.test_case_count
def print_evaluate(self):
if self.total_file_count == 0:
log.error("No test files found!")
exit(-1)
if self.test_case_count == 0:
log.error("No test cases found!")
exit(-1)
if self.failing_files:
print("Test files with failures:")
for tf in self.failing_files:
print(f" - {tf}")
print()
if self.err_msgs:
print("Error messages:")
for error in self.err_msgs:
print(f" - {error}")
print("\n-----------------------------------------")
print("Test run statistics\n")
print(f"Valid files: {self.total_valid_files}")
print(f"Invalid files: {self.invalid_files}")
print(f"Errors: {self.errors}\n")
print("Test cases:")
print(f"\tTotal: {self.test_case_count}")
print(f"\tSuccessful: {self.success}")
print(f"\tSkipped: {self.skipped}")
print(f"\tFailed: {self.failed}")
print("-----------------------------------------")
print("")
if self.test_case_count != self.success + self.failed + self.skipped:
log.error(
"Inconsistent statistics: total != successful + failed + skipped\n"
)
if self.errors != 0:
log.error("Failed with errors\n")
exit(-1)
elif self.failed != 0:
log.warning("Not all tests succeeded\n")
exit(-1)
log.info("All tests succeeded.\n")
exit(0)
class TestInput:
def __init__(self, input_dict: dict):
self.input_dict = input_dict
if "bytes" not in self.input_dict:
raise ValueError("Error: 'Missing required mapping field'\nField: 'bytes'.")
if "options" not in self.input_dict:
raise ValueError(
"Error: 'Missing required mapping field'\nField: 'options'."
)
if "arch" not in self.input_dict:
raise ValueError("Error: 'Missing required mapping field'\nField: 'arch'.")
self.in_bytes = bytes(self.input_dict["bytes"])
self.options = self.input_dict["options"]
self.arch = self.input_dict["arch"]
self.name = "" if "name" not in self.input_dict else self.input_dict["name"]
if "address" not in self.input_dict:
self.address: int = 0
else:
assert isinstance(self.input_dict["address"], int)
self.address = self.input_dict["address"]
self.handle = None
self.arch_bits = 0
def setup(self):
log.debug(f"Init {self}")
arch = get_cs_int_attr(capstone, self.arch, "CS_ARCH")
if arch is None:
cs_name = f"CS_ARCH_{self.arch.upper()}"
arch = get_cs_int_attr(capstone, cs_name, "CS_ARCH")
if arch is None:
raise ValueError(
f"Couldn't init architecture as '{self.arch}' or '{cs_name}'.\n"
f"'{self.arch}' is not mapped to a capstone architecture."
)
new_mode = 0
for opt in self.options:
if "CS_MODE_" in opt:
mode = get_cs_int_attr(capstone, opt, "CS_OPT")
if mode is not None:
new_mode |= mode
continue
self.handle = Cs(arch, new_mode)
for opt in self.options:
if "CS_MODE_" in opt:
continue
if "CS_OPT_" in opt and opt in configs:
mtype = configs[opt]["type"]
val = configs[opt]["val"]
self.handle.option(mtype, val)
continue
log.warning(f"Option: '{opt}' not used")
self.arch_bits = arch_bits(self.handle.arch, self.handle.mode)
log.debug("Init done")
def decode(self) -> list[CsInsn]:
if not self.handle:
raise ValueError("self.handle is None. Must be setup before.")
return [i for i in self.handle.disasm(self.in_bytes, self.address)]
def __str__(self):
default = (
f"TestInput {{ arch: {self.arch}, options: {self.options}, "
f"addr: {self.address:x}, bytes: [ {','.join([f'{b:#04x}' for b in self.in_bytes])} ] }}"
)
if self.name:
return f"{self.name} -- {default}"
return default
class TestExpected:
def __init__(self, expected_dict: dict):
self.expected_dict = expected_dict
self.insns = (
list() if "insns" not in self.expected_dict else self.expected_dict["insns"]
)
def compare(self, actual_insns: list[CsInsn], bits: int) -> TestResult:
if len(actual_insns) != len(self.insns):
log.error(
"Number of decoded instructions don't match (actual != expected): "
f"{len(actual_insns)} != {len(self.insns):#x}"
)
return TestResult.FAILED
for a_insn, e_insn in zip(actual_insns, self.insns):
if not compare_asm_text(
a_insn,
e_insn.get("asm_text"),
bits,
):
return TestResult.FAILED
if not compare_str(a_insn.mnemonic, e_insn.get("mnemonic"), "mnemonic"):
return TestResult.FAILED
if not compare_str(a_insn.op_str, e_insn.get("op_str"), "op_str"):
return TestResult.FAILED
if not compare_uint32(a_insn.id, e_insn.get("id"), "id"):
return TestResult.FAILED
if not compare_tbool(a_insn.is_alias, e_insn.get("is_alias"), "is_alias"):
return TestResult.FAILED
if not compare_uint32(a_insn.alias_id, e_insn.get("alias_id"), "alias_id"):
return TestResult.FAILED
if not compare_details(a_insn, e_insn.get("details")):
return TestResult.FAILED
return TestResult.SUCCESS
class TestCase:
def __init__(self, test_case_dict: dict):
self.tc_dict = test_case_dict
if "input" not in self.tc_dict:
raise ValueError("Mandatory field 'input' missing")
if "expected" not in self.tc_dict:
raise ValueError("Mandatory field 'expected' missing")
self.input = TestInput(self.tc_dict["input"])
self.expected = TestExpected(self.tc_dict["expected"])
self.skip = "skip" in self.tc_dict
if self.skip and "skip_reason" not in self.tc_dict:
raise ValueError(
"If 'skip' field is set a 'skip_reason' field must be set as well."
)
self.skip_reason = (
self.tc_dict["skip_reason"] if "skip_reason" in self.tc_dict else ""
)
def __str__(self) -> str:
return f"{self.input}"
def test(self) -> TestResult:
if self.skip:
log.info(f"Skip {self}\nReason: {self.skip_reason}")
return TestResult.SKIPPED
try:
self.input.setup()
except Exception as e:
log.error(f"Setup failed at with: {e}")
traceback.print_exc()
return TestResult.ERROR
try:
insns = self.input.decode()
except Exception as e:
log.error(f"Decode failed with: {e}")
traceback.print_exc()
return TestResult.ERROR
try:
return self.expected.compare(insns, self.input.arch_bits)
except Exception as e:
log.error(f"Compare expected failed with: {e}")
traceback.print_exc()
return TestResult.ERROR
class TestFile:
def __init__(self, tfile_path: Path):
self.path = tfile_path
with open(tfile_path) as f:
try:
self.content = yaml.safe_load(f)
except yaml.YAMLError as e:
raise e
self.test_cases = list()
if not self.content:
raise ValueError("Empty file")
for tc_dict in self.content["test_cases"]:
tc = TestCase(tc_dict)
self.test_cases.append(tc)
def num_test_cases(self) -> int:
return len(self.test_cases)
def __str__(self) -> str:
return f"{self.path}"
class CSTest:
def __init__(self, path: Path, exclude: list[Path], include: list[Path]):
self.yaml_paths: list[Path] = list()
log.info(f"Search test files in {path}")
if path.is_file():
self.yaml_paths.append(path)
else:
for root, dirs, files in os.walk(path, onerror=print):
for file in files:
f = Path(root).joinpath(file)
if f.suffix not in [".yaml", ".yml"]:
continue
if f.name in exclude:
continue
if not include or f.name in include:
log.debug(f"Add: {f}")
self.yaml_paths.append(f)
log.info(f"Test files found: {len(self.yaml_paths)}")
self.stats = TestStats(len(self.yaml_paths))
self.test_files: list[TestFile] = list()
def parse_files(self):
total_test_cases = 0
total_files = len(self.yaml_paths)
count = 1
for tfile in self.yaml_paths:
print(
f"Parse {count}/{total_files}: {tfile.name}",
end=f"{' ' * 20}\r",
flush=True,
)
try:
tf = TestFile(tfile)
total_test_cases += tf.num_test_cases()
self.test_files.append(tf)
except yaml.YAMLError as e:
self.stats.add_error_msg(str(e))
self.stats.add_invalid_file_dp(tfile)
log.error("Error: 'libyaml parser error'")
log.error(f"{e}")
log.error(f"Failed to parse test file '{tfile}'")
except ValueError as e:
self.stats.add_error_msg(str(e))
self.stats.add_invalid_file_dp(tfile)
log.error(f"Error: ValueError: {e}")
log.error(f"Failed to parse test file '{tfile}'")
finally:
count += 1
self.stats.set_total_valid_files(len(self.test_files))
self.stats.set_total_test_cases(total_test_cases)
log.info(f"Found {self.stats.get_test_case_count()} test cases.{' ' * 20}")
def run_tests(self):
self.parse_files()
for tf in self.test_files:
log.info(f"Test file: {tf}\n")
for tc in tf.test_cases:
log.info(f"Run test: {tc}")
try:
result = tc.test()
except Exception as e:
result = TestResult.ERROR
self.stats.add_error_msg(str(e))
if result == TestResult.FAILED or result == TestResult.ERROR:
self.stats.add_failing_file(tf.path)
self.stats.add_test_case_data_point(result)
log.info(result)
print()
self.stats.print_evaluate()
def get_repo_root() -> str | None:
res = sp.run(["git", "rev-parse", "--show-toplevel"], capture_output=True)
if res.stderr:
log.error("Could not get repository root directory.")
return None
return res.stdout.decode("utf8").strip()
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
prog="Python CSTest",
description="Pyton binding cstest implementation.",
)
repo_root = get_repo_root()
if repo_root:
parser.add_argument(
dest="search_dir",
help="Directory to search for .yaml test files.",
default=Path(f"{repo_root}/tests/"),
type=Path,
)
else:
parser.add_argument(
dest="search_dir",
help="Directory to search for .yaml test files.",
required=True,
type=Path,
)
parser.add_argument(
"-e",
dest="exclude",
help="List of file names to exclude.",
nargs="+",
required=False,
default=list(),
)
parser.add_argument(
"-i",
dest="include",
help="List of file names to include.",
nargs="+",
required=False,
default=list(),
)
parser.add_argument(
"-v",
dest="verbosity",
help="Verbosity of the log messages.",
choices=["debug", "info", "warning", "error", "fatal", "critical"],
default="info",
)
arguments = parser.parse_args()
return arguments
def main():
log_levels = {
"debug": logging.DEBUG,
"info": logging.INFO,
"warning": logging.WARNING,
"error": logging.ERROR,
"fatal": logging.FATAL,
"critical": logging.CRITICAL,
}
args = parse_args()
format = logging.Formatter("%(levelname)-5s - %(message)s", None, "%")
log.setLevel(log_levels[args.verbosity])
h1 = logging.StreamHandler(sys.stdout)
h1.addFilter(
lambda record: record.levelno >= log_levels[args.verbosity]
and record.levelno < logging.WARNING
)
h1.setFormatter(format)
h2 = logging.StreamHandler(sys.stderr)
h2.setLevel(logging.WARNING)
h2.setFormatter(format)
log.addHandler(h1)
log.addHandler(h2)
CSTest(args.search_dir, args.exclude, args.include).run_tests()
if __name__ == "__main__":
main()

File diff suppressed because it is too large Load Diff

View File

@ -72,10 +72,12 @@ else:
LIBRARY_FILE = "libcapstone.so" LIBRARY_FILE = "libcapstone.so"
STATIC_LIBRARY_FILE = 'libcapstone.a' STATIC_LIBRARY_FILE = 'libcapstone.a'
def clean_bins(): def clean_bins():
shutil.rmtree(LIBS_DIR, ignore_errors=True) shutil.rmtree(LIBS_DIR, ignore_errors=True)
shutil.rmtree(HEADERS_DIR, ignore_errors=True) shutil.rmtree(HEADERS_DIR, ignore_errors=True)
def copy_sources(): def copy_sources():
"""Copy the C sources into the source directory. """Copy the C sources into the source directory.
This rearranges the source files under the python distribution This rearranges the source files under the python distribution
@ -92,22 +94,19 @@ def copy_sources():
shutil.copytree(os.path.join(BUILD_DIR, "include"), os.path.join(SRC_DIR, "include")) shutil.copytree(os.path.join(BUILD_DIR, "include"), os.path.join(SRC_DIR, "include"))
src.extend(glob.glob(os.path.join(BUILD_DIR, "*.[ch]"))) src.extend(glob.glob(os.path.join(BUILD_DIR, "*.[ch]")))
src.extend(glob.glob(os.path.join(BUILD_DIR, "*.mk")))
src.extend(glob.glob(os.path.join(BUILD_DIR, "Makefile")))
src.extend(glob.glob(os.path.join(BUILD_DIR, "LICENSES/*"))) src.extend(glob.glob(os.path.join(BUILD_DIR, "LICENSES/*")))
src.extend(glob.glob(os.path.join(BUILD_DIR, "README"))) src.extend(glob.glob(os.path.join(BUILD_DIR, "README")))
src.extend(glob.glob(os.path.join(BUILD_DIR, "*.TXT"))) src.extend(glob.glob(os.path.join(BUILD_DIR, "*.TXT")))
src.extend(glob.glob(os.path.join(BUILD_DIR, "RELEASE_NOTES"))) src.extend(glob.glob(os.path.join(BUILD_DIR, "RELEASE_NOTES")))
src.extend(glob.glob(os.path.join(BUILD_DIR, "make.sh")))
src.extend(glob.glob(os.path.join(BUILD_DIR, "CMakeLists.txt"))) src.extend(glob.glob(os.path.join(BUILD_DIR, "CMakeLists.txt")))
src.extend(glob.glob(os.path.join(BUILD_DIR, "pkgconfig.mk")))
for filename in src: for filename in src:
outpath = os.path.join(SRC_DIR, os.path.basename(filename)) outpath = os.path.join(SRC_DIR, os.path.basename(filename))
logger.info("%s -> %s" % (filename, outpath)) logger.info("%s -> %s" % (filename, outpath))
shutil.copy(filename, outpath) shutil.copy(filename, outpath)
def build_libraries(): def build_libraries():
""" """
Prepare the capstone directory for a binary distribution or installation. Prepare the capstone directory for a binary distribution or installation.
@ -134,23 +133,22 @@ def build_libraries():
os.chdir(BUILD_DIR) os.chdir(BUILD_DIR)
# platform description refers at https://docs.python.org/3/library/sys.html#sys.platform # Windows build: this process requires few things:
# Use cmake for both Darwin and Windows since it can generate fat binaries # - MSVC installed
if SYSTEM == "win32" or SYSTEM == 'darwin': # - Run this command in an environment setup for MSVC
# Windows build: this process requires few things: if not os.path.exists("build_py"):
# - CMake + MSVC installed os.mkdir("build_py")
# - Run this command in an environment setup for MSVC os.chdir("build_py")
if not os.path.exists("build"): os.mkdir("build") print("Build Directory: {}\n".format(os.getcwd()))
os.chdir("build") # Only build capstone.dll / libcapstone.dylib
print("Build Directory: {}\n".format(os.getcwd())) if SYSTEM == "win32":
# Only build capstone.dll / libcapstone.dylib os.system('cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCAPSTONE_BUILD_LEGACY_TESTS=OFF -DCAPSTONE_BUILD_CSTOOL=OFF -G "NMake Makefiles" ..')
if SYSTEM == "win32": elif 'AFL_NOOPT' in os.environ:
os.system('cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCAPSTONE_BUILD_TESTS=OFF -DCAPSTONE_BUILD_CSTOOL=OFF -G "NMake Makefiles" ..') # build for test_corpus
else: os.system('cmake -DBUILD_SHARED_LIBS=ON -DCAPSTONE_BUILD_LEGACY_TESTS=OFF -DCAPSTONE_BUILD_CSTOOL=OFF ..')
os.system('cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCAPSTONE_BUILD_TESTS=OFF -DCAPSTONE_BUILD_CSTOOL=OFF -G "Unix Makefiles" ..') else:
os.system("cmake --build .") os.system('cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCAPSTONE_BUILD_LEGACY_TESTS=OFF -DCAPSTONE_BUILD_CSTOOL=OFF -G "Unix Makefiles" ..')
else: # Unix incl. cygwin os.system("cmake --build .")
os.system("CAPSTONE_BUILD_CORE_ONLY=yes bash ./make.sh")
shutil.copy(VERSIONED_LIBRARY_FILE, os.path.join(LIBS_DIR, LIBRARY_FILE)) shutil.copy(VERSIONED_LIBRARY_FILE, os.path.join(LIBS_DIR, LIBRARY_FILE))
@ -182,8 +180,6 @@ class custom_bdist_egg(bdist_egg):
self.run_command('build') self.run_command('build')
return bdist_egg.run(self) return bdist_egg.run(self)
def dummy_src():
return []
cmdclass = {} cmdclass = {}
cmdclass['build'] = custom_build cmdclass['build'] = custom_build
@ -192,6 +188,7 @@ cmdclass['bdist_egg'] = custom_bdist_egg
try: try:
from setuptools.command.develop import develop from setuptools.command.develop import develop
class custom_develop(develop): class custom_develop(develop):
def run(self): def run(self):
logger.info("Building C extensions") logger.info("Building C extensions")

View File

@ -1,193 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
from capstone import *
from capstone.aarch64 import *
from xprint import to_hex, to_x, to_x_32
AArch64_CODE = b"\x09\x00\x38\xd5\xbf\x40\x00\xd5\x0c\x05\x13\xd5\x20\x50\x02\x0e\x20\xe4\x3d\x0f\x00\x18\xa0\x5f\xa2\x00\xae\x9e\x9f\x37\x03\xd5\xbf\x33\x03\xd5\xdf\x3f\x03\xd5\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x20\x04\x81\xda\x20\x08\x02\x8b\x10\x5b\xe8\x3c\xfd\x7b\xba\xa9\xfd\xc7\x43\xf8"
all_tests = (
(CS_ARCH_AARCH64, CS_MODE_ARM, AArch64_CODE, "AARCH64"),
)
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = -1
for i in insn.operands:
c += 1
if i.type == AARCH64_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
if i.type == AARCH64_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm)))
if i.type == AARCH64_OP_CIMM:
print("\t\toperands[%u].type: C-IMM = %u" % (c, i.imm))
if i.type == AARCH64_OP_FP:
print("\t\toperands[%u].type: FP = %f" % (c, i.fp))
if i.type == AARCH64_OP_MEM:
print("\t\toperands[%u].type: MEM" % c)
if i.mem.base != 0:
print("\t\t\toperands[%u].mem.base: REG = %s" \
% (c, insn.reg_name(i.mem.base)))
if i.mem.index != 0:
print("\t\t\toperands[%u].mem.index: REG = %s" \
% (c, insn.reg_name(i.mem.index)))
if i.mem.disp != 0:
print("\t\t\toperands[%u].mem.disp: 0x%s" \
% (c, to_x_32(i.mem.disp)))
if insn.post_index:
print("\t\t\tpost-indexed: true");
if i.type == AARCH64_OP_SME:
print("\t\toperands[%u].type: SME_MATRIX" % (c))
print("\t\toperands[%u].sme.type: %d" % (c, i.sme.type))
if i.sme.tile != AARCH64_REG_INVALID:
print("\t\toperands[%u].sme.tile: %s" % (c, insn.reg_name(i.sme.tile)))
if i.sme.slice_reg != AARCH64_REG_INVALID:
print("\t\toperands[%u].sme.slice_reg: %s" % (c, insn.reg_name(i.sme.slice_reg)))
if i.sme.slice_offset.imm != -1 or i.sme.slice_offset.imm_range.first != -1:
print("\t\toperands[%u].sme.slice_offset: " % (c))
if i.sme.has_range_offset:
print("%hhd:%hhd" % (i.sme.slice_offset.imm_range.first, i.sme.slice_offset.imm_range.offset))
else:
print("%d" % (i.sme.slice_offset.imm))
if i.sme.slice_reg != AARCH64_REG_INVALID or i.sme.slice_offset.imm != -1:
print("\t\toperands[%u].sme.is_vertical: %s" % (c, ("true" if i.sme.is_vertical else "false")))
if i.type == AARCH64_OP_PRED:
print("\t\toperands[%u].type: PREDICATE\n" % c);
if (op.pred.reg != AARCH64_REG_INVALID):
print("\t\toperands[%u].pred.reg: %s\n" % (c, insn.reg_name(i.pred.reg)));
if (op.pred.vec_select != AARCH64_REG_INVALID):
print("\t\toperands[%u].pred.vec_select: %s\n" % (c, insn.reg_name(i.pred.vec_select)));
if (op.pred.imm_index != -1):
print("\t\toperands[%u].pred.imm_index: %d\n" % (i, op.pred.imm_index));
break;
if i.type == AARCH64_OP_SYSREG:
print("\t\toperands[%u].type: SYS REG:" % (c))
if i.sysop.sub_type == AARCH64_OP_REG_MRS:
print("\t\toperands[%u].subtype: REG_MRS = 0x%x" % (c, i.sysop.reg.sysreg))
if i.sysop.sub_type == AARCH64_OP_REG_MSR:
print("\t\toperands[%u].subtype: REG_MSR = 0x%x" % (c, i.sysop.reg.sysreg))
if i.sysop.sub_type == AARCH64_OP_TLBI:
print("\t\toperands[%u].subtype TLBI = 0x%x" % (c, i.sysop.reg.tlbi))
if i.sysop.sub_type == AARCH64_OP_IC:
print("\t\toperands[%u].subtype IC = 0x%x" % (c, i.sysop.reg.ic))
if i.type == AARCH64_OP_SYSALIAS:
print("\t\toperands[%u].type: SYS ALIAS:" % (c))
if i.sysop.sub_type == AARCH64_OP_SVCR:
if i.sysop.alias.svcr == AARCH64_SVCR_SVCRSM:
print("\t\t\toperands[%u].svcr: BIT = SM" % (c))
elif i.sysop.alias.svcr == AARCH64_SVCR_SVCRZA:
print("\t\t\toperands[%u].svcr: BIT = ZA" % (c))
elif i.sysop.alias.svcr == AARCH64_SVCR_SVCRSMZA:
print("\t\t\toperands[%u].svcr: BIT = SM & ZA" % (c))
if i.sysop.sub_type == AARCH64_OP_AT:
print("\t\toperands[%u].subtype AT = 0x%x" % (c, i.sysop.alias.at))
if i.sysop.sub_type == AARCH64_OP_DB:
print("\t\toperands[%u].subtype DB = 0x%x" % (c, i.sysop.alias.db))
if i.sysop.sub_type == AARCH64_OP_DC:
print("\t\toperands[%u].subtype DC = 0x%x" % (c, i.sysop.alias.dc))
if i.sysop.sub_type == AARCH64_OP_ISB:
print("\t\toperands[%u].subtype ISB = 0x%x" % (c, i.sysop.alias.isb))
if i.sysop.sub_type == AARCH64_OP_TSB:
print("\t\toperands[%u].subtype TSB = 0x%x" % (c, i.sysop.alias.tsb))
if i.sysop.sub_type == AARCH64_OP_PRFM:
print("\t\toperands[%u].subtype PRFM = 0x%x" % (c, i.sysop.alias.prfm))
if i.sysop.sub_type == AARCH64_OP_SVEPRFM:
print("\t\toperands[%u].subtype SVEPRFM = 0x%x" % (c, i.sysop.alias.sveprfm))
if i.sysop.sub_type == AARCH64_OP_RPRFM:
print("\t\toperands[%u].subtype RPRFM = 0x%x" % (c, i.sysop.alias.rprfm))
if i.sysop.sub_type == AARCH64_OP_PSTATEIMM0_15:
print("\t\toperands[%u].subtype PSTATEIMM0_15 = 0x%x" % (c, i.sysop.alias.pstateimm0_15))
if i.sysop.sub_type == AARCH64_OP_PSTATEIMM0_1:
print("\t\toperands[%u].subtype PSTATEIMM0_1 = 0x%x" % (c, i.sysop.alias.pstateimm0_1))
if i.sysop.sub_type == AARCH64_OP_PSB:
print("\t\toperands[%u].subtype PSB = 0x%x" % (c, i.sysop.alias.psb))
if i.sysop.sub_type == AARCH64_OP_BTI:
print("\t\toperands[%u].subtype BTI = 0x%x" % (c, i.sysop.alias.bti))
if i.sysop.sub_type == AARCH64_OP_SVEPREDPAT:
print("\t\toperands[%u].subtype SVEPREDPAT = 0x%x" % (c, i.sysop.alias.svepredpat))
if i.sysop.sub_type == AARCH64_OP_SVEVECLENSPECIFIER:
print("\t\toperands[%u].subtype SVEVECLENSPECIFIER = 0x%x" % (c, i.sysop.alias.sveveclenspecifier))
if i.type == AARCH64_OP_SYSIMM:
print("\t\toperands[%u].type: SYS IMM:" % (c))
if i.sysop.sub_type == AARCH64_OP_EXACTFPIMM:
print("\t\toperands[%u].subtype EXACTFPIMM = %d" % (c, i.sysop.imm.exactfpimm))
if i.sysop.sub_type == AARCH64_OP_DBNXS:
print("\t\toperands[%u].subtype DBNXS = %d" % (c, i.sysop.imm.dbnxs))
if i.access == CS_AC_READ:
print("\t\toperands[%u].access: READ" % (c))
elif i.access == CS_AC_WRITE:
print("\t\toperands[%u].access: WRITE" % (c))
elif i.access == CS_AC_READ | CS_AC_WRITE:
print("\t\toperands[%u].access: READ | WRITE" % (c))
if i.shift.type != AARCH64_SFT_INVALID and i.shift.value:
print("\t\t\tShift: type = %u, value = %u" % (i.shift.type, i.shift.value))
if i.ext != AARCH64_EXT_INVALID:
print("\t\t\tExt: %u" % i.ext)
if i.vas != AARCH64LAYOUT_INVALID:
print("\t\t\tVector Arrangement Specifier: 0x%x" % i.vas)
if i.vector_index != -1:
print("\t\t\tVector Index: %u" % i.vector_index)
if insn.writeback:
print("\tWrite-back: True")
if insn.cc != AArch64CC_Invalid:
print("\tCode-condition: %u" % insn.cc)
if insn.update_flags:
print("\tUpdate-flags: True")
(regs_read, regs_write) = insn.regs_access()
if len(regs_read) > 0:
print("\tRegisters read:", end="")
for r in regs_read:
print(" %s" %(insn.reg_name(r)), end="")
print("")
if len(regs_write) > 0:
print("\tRegisters modified:", end="")
for r in regs_write:
print(" %s" %(insn.reg_name(r)), end="")
print("")
# ## Test class Cs
def test_class():
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" % comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
for insn in md.disasm(code, 0x2c):
print_insn_detail(insn)
print ()
print("0x%x:\n" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" % e)
if __name__ == '__main__':
test_class()

View File

@ -1,26 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import test_basic, test_arm, test_aarch64, test_detail, test_lite, test_m68k, test_mips, \ import test_lite
test_ppc, test_x86, test_skipdata, test_sparc, test_systemz, test_tms320c64x, test_customized_mnem, \ import test_skipdata
test_m680x, test_mos65xx, test_xcore, test_riscv, test_alpha, test_hppa import test_customized_mnem
test_basic.test_class()
test_arm.test_class()
test_aarch64.test_class()
test_detail.test_class()
test_lite.test_class() test_lite.test_class()
test_m68k.test_class()
test_mips.test_class()
test_mos65xx.test_class()
test_ppc.test_class()
test_sparc.test_class()
test_systemz.test_class()
test_x86.test_class()
test_tms320c64x.test_class()
test_m680x.test_class()
test_skipdata.test_class() test_skipdata.test_class()
test_customized_mnem.test() test_customized_mnem.test()
test_xcore.test_class()
test_riscv.test_class()
test_alpha.test_class()
test_hppa.test_class()

View File

@ -1,57 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Dmitry Sibirtsev <sibirtsev_dl@gmail.com>
from capstone import *
from capstone.alpha import *
from xprint import to_x, to_hex
ALPHA_CODE = b'\x02\x00\xbb\x27\x50\x7a\xbd\x23\xd0\xff\xde\x23\x00\x00\x5e\xb7'
ALPHA_CODE_BE = b'\x27\xbb\x00\x02\x23\xbd\x7a\x50\x23\xde\xff\xd0\xb7\x5e\x00\x00'
all_tests = (
(CS_ARCH_ALPHA, CS_MODE_LITTLE_ENDIAN, ALPHA_CODE, "Alpha (Little-endian)"),
(CS_ARCH_ALPHA, CS_MODE_BIG_ENDIAN, ALPHA_CODE_BE, "Alpha (Big-endian)"),
)
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = 0
for i in insn.operands:
if i.type == ALPHA_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
if i.type == ALPHA_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm)))
c += 1
# ## Test class Cs
def test_class():
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" % comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
for insn in md.disasm(code, 0x1000):
print_insn_detail(insn)
print()
print("0x%x:\n" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" % e)
if __name__ == '__main__':
test_class()

View File

@ -1,189 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
from capstone import *
from capstone.arm import *
from xprint import to_hex, to_x_32
ARM_CODE = b"\x86\x48\x60\xf4\x4d\x0f\xe2\xf4\xED\xFF\xFF\xEB\x04\xe0\x2d\xe5\x00\x00\x00\x00\xe0\x83\x22\xe5\xf1\x02\x03\x0e\x00\x00\xa0\xe3\x02\x30\xc1\xe7\x00\x00\x53\xe3\x00\x02\x01\xf1\x05\x40\xd0\xe8\xf4\x80\x00\x00"
ARM_CODE2 = b"\xd1\xe8\x00\xf0\xf0\x24\x04\x07\x1f\x3c\xf2\xc0\x00\x00\x4f\xf0\x00\x01\x46\x6c"
THUMB_CODE = b"\x60\xf9\x1f\x04\xe0\xf9\x4f\x07\x70\x47\x00\xf0\x10\xe8\xeb\x46\x83\xb0\xc9\x68\x1f\xb1\x30\xbf\xaf\xf3\x20\x84\x52\xf8\x23\xf0"
THUMB_CODE2 = b"\x4f\xf0\x00\x01\xbd\xe8\x00\x88\xd1\xe8\x00\xf0\x18\xbf\xad\xbf\xf3\xff\x0b\x0c\x86\xf3\x00\x89\x80\xf3\x00\x8c\x4f\xfa\x99\xf6\xd0\xff\xa2\x01"
THUMB_MCLASS = b"\xef\xf3\x02\x80"
ARMV8 = b"\xe0\x3b\xb2\xee\x42\x00\x01\xe1\x51\xf0\x7f\xf5"
all_tests = (
(CS_ARCH_ARM, CS_MODE_ARM, ARM_CODE, "ARM", None),
(CS_ARCH_ARM, CS_MODE_THUMB, THUMB_CODE, "Thumb", None),
(CS_ARCH_ARM, CS_MODE_THUMB, ARM_CODE2, "Thumb-mixed", None),
(CS_ARCH_ARM, CS_MODE_THUMB, THUMB_CODE2, "Thumb-2 & register named with numbers", CS_OPT_SYNTAX_NOREGNAME),
(CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_MCLASS, THUMB_MCLASS, "Thumb-MClass", None),
(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_V8, ARMV8, "Arm-V8", None),
)
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = 0
for i in insn.operands:
if i.type == ARM_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
elif i.type == ARM_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x_32(i.imm)))
elif i.type == ARM_OP_FP:
print("\t\toperands[%u].type: FP = %f" % (c, i.fp))
elif i.type == ARM_OP_PRED:
print("\t\toperands[%u].type: PRED = %d" % (c, i.pred))
elif i.type == ARM_OP_CIMM:
print("\t\toperands[%u].type: C-IMM = %u" % (c, i.imm))
elif i.type == ARM_OP_PIMM:
print("\t\toperands[%u].type: P-IMM = %u" % (c, i.imm))
elif i.type == ARM_OP_SETEND:
if i.setend == ARM_SETEND_BE:
print("\t\toperands[%u].type: SETEND = be" % c)
else:
print("\t\toperands[%u].type: SETEND = le" % c)
elif i.type == ARM_OP_MEM:
print("\t\toperands[%u].type: MEM" % c)
if i.mem.base != 0:
print("\t\t\toperands[%u].mem.base: REG = %s" \
% (c, insn.reg_name(i.mem.base)))
if i.mem.index != 0:
print("\t\t\toperands[%u].mem.index: REG = %s" \
% (c, insn.reg_name(i.mem.index)))
if i.mem.scale != 1:
print("\t\t\toperands[%u].mem.scale: %u" \
% (c, i.mem.scale))
if i.mem.disp != 0:
print("\t\t\toperands[%u].mem.disp: 0x%s" \
% (c, to_x_32(i.mem.disp)))
if i.mem.lshift != 0:
print("\t\t\toperands[%u].mem.lshift: 0x%s" \
% (c, to_x_32(i.mem.lshift)))
elif i.type == ARM_OP_SYSM:
print("\t\toperands[%u].type: SYSM = 0x%x" % (c, i.sysop.sysm))
print("\t\toperands[%u].type: MASK = %u" % (c, i.sysop.msr_mask))
elif i.type == ARM_OP_SYSREG:
print("\t\toperands[%u].type: SYSREG = %s" % (c, insn.reg_name(i.sysop.reg.mclasssysreg)))
print("\t\toperands[%u].type: MASK = %u" % (c, i.sysop.msr_mask))
elif i.type == ARM_OP_BANKEDREG:
print("\t\toperands[%u].type: BANKEDREG = %u" % (c, i.sysop.reg.bankedreg))
if i.sysop.msr_mask != 2 ** (ctypes.sizeof(ctypes.c_uint8) * 8) - 1:
print("\t\toperands[%u].type: MASK = %u" % (c, i.sysop.msr_mask))
elif i.type in [ARM_OP_SPSR, ARM_OP_CPSR]:
print("\t\toperands[%u].type: %sPSR = " % (c, "S" if i.type == ARM_OP_SPSR else "C"), end="")
field = i.sysop.psr_bits
if (field & ARM_FIELD_SPSR_F) > 0 or (field & ARM_FIELD_CPSR_F) > 0:
print("f", end="")
if (field & ARM_FIELD_SPSR_S) > 0 or (field & ARM_FIELD_CPSR_S) > 0:
print("s", end="")
if (field & ARM_FIELD_SPSR_X) > 0 or (field & ARM_FIELD_CPSR_X) > 0:
print("x", end="")
if (field & ARM_FIELD_SPSR_C) > 0 or (field & ARM_FIELD_CPSR_C) > 0:
print("c", end="")
print()
print("\t\toperands[%u].type: MASK = %u" % (c, i.sysop.msr_mask))
else:
print("\t\toperands[%u].type: UNKNOWN = %u" % (c, i.type))
if i.neon_lane != -1:
print("\t\toperands[%u].neon_lane = %u" % (c, i.neon_lane))
if i.access == CS_AC_READ:
print("\t\toperands[%u].access: READ" % (c))
elif i.access == CS_AC_WRITE:
print("\t\toperands[%u].access: WRITE" % (c))
elif i.access == CS_AC_READ | CS_AC_WRITE:
print("\t\toperands[%u].access: READ | WRITE" % (c))
if i.shift.type != ARM_SFT_INVALID and i.shift.value:
if i.shift.type < ARM_SFT_ASR_REG:
# shift with constant value
print("\t\t\tShift: %u = %u" \
% (i.shift.type, i.shift.value))
else:
# shift with register
print("\t\t\tShift: %u = %s" \
% (i.shift.type, insn.reg_name(i.shift.value)))
if i.vector_index != -1:
print("\t\t\toperands[%u].vector_index = %u" %(c, i.vector_index))
if i.subtracted:
print("\t\t\toperands[%u].subtracted = True" %c)
c += 1
if not insn.cc in [ARMCC_AL, ARMCC_UNDEF]:
print("\tCode condition: %u" % insn.cc)
if insn.vcc != ARMVCC_None:
print("\tVector code condition: %u" % insn.vcc)
if insn.update_flags:
print("\tUpdate-flags: True")
if insn.writeback:
if insn.post_index:
print("\tWrite-back: Post")
else:
print("\tWrite-back: Pre")
if insn.cps_mode:
print("\tCPSI-mode: %u" %(insn.cps_mode))
if insn.cps_flag:
print("\tCPSI-flag: %u" %(insn.cps_flag))
if insn.vector_data:
print("\tVector-data: %u" %(insn.vector_data))
if insn.vector_size:
print("\tVector-size: %u" %(insn.vector_size))
if insn.usermode:
print("\tUser-mode: True")
if insn.mem_barrier:
print("\tMemory-barrier: %u" %(insn.mem_barrier))
if insn.pred_mask:
print("\tPredicate Mask: 0x%x" %(insn.pred_mask))
(regs_read, regs_write) = insn.regs_access()
if len(regs_read) > 0:
print("\tRegisters read:", end="")
for r in regs_read:
print(" %s" %(insn.reg_name(r)), end="")
print("")
if len(regs_write) > 0:
print("\tRegisters modified:", end="")
for r in regs_write:
print(" %s" %(insn.reg_name(r)), end="")
print("")
# ## Test class Cs
def test_class():
for (arch, mode, code, comment, syntax) in all_tests:
print("*" * 16)
print("Platform: %s" % comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
if syntax is not None:
md.syntax = syntax
md.detail = True
for insn in md.disasm(code, 0x80001000):
print_insn_detail(insn)
print ()
print("0x%x:\n" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" % e)
if __name__ == '__main__':
test_class()

View File

@ -1,144 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
from capstone import *
from xprint import to_hex
X86_CODE16 = b"\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00"
X86_CODE32 = b"\xba\xcd\xab\x00\x00\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00"
X86_CODE64 = b"\x55\x48\x8b\x05\xb8\x13\x00\x00"
ARM_CODE = b"\xED\xFF\xFF\xEB\x04\xe0\x2d\xe5\x00\x00\x00\x00\xe0\x83\x22\xe5\xf1\x02\x03\x0e\x00\x00\xa0\xe3\x02\x30\xc1\xe7\x00\x00\x53\xe3"
ARM_CODE2 = b"\x10\xf1\x10\xe7\x11\xf2\x31\xe7\xdc\xa1\x2e\xf3\xe8\x4e\x62\xf3"
THUMB_CODE = b"\x70\x47\xeb\x46\x83\xb0\xc9\x68"
THUMB_CODE2 = b"\x4f\xf0\x00\x01\xbd\xe8\x00\x88\xd1\xe8\x00\xf0"
THUMB_MCLASS = b"\xef\xf3\x02\x80"
ARMV8 = b"\xe0\x3b\xb2\xee\x42\x00\x01\xe1\x51\xf0\x7f\xf5"
MIPS_CODE = b"\x0C\x10\x00\x97\x00\x00\x00\x00\x24\x02\x00\x0c\x8f\xa2\x00\x00\x34\x21\x34\x56"
MIPS_CODE2 = b"\x56\x34\x21\x34\xc2\x17\x01\x00"
MIPS_32R6M = b"\x00\x07\x00\x07\x00\x11\x93\x7c\x01\x8c\x8b\x7c\x00\xc7\x48\xd0"
MIPS_32R6 = b"\xec\x80\x00\x19\x7c\x43\x22\xa0"
AARCH64_CODE = b"\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9"
PPC_CODE = b"\x80\x20\x00\x00\x80\x3f\x00\x00\x10\x43\x23\x0e\xd0\x44\x00\x80\x4c\x43\x22\x02\x2d\x03\x00\x80\x7c\x43\x20\x14\x7c\x43\x20\x93\x4f\x20\x00\x21\x4c\xc8\x00\x21"
PPC_CODE2 = b"\x10\x60\x2a\x10\x10\x64\x28\x88\x7c\x4a\x5d\x0f"
SPARC_CODE = b"\x80\xa0\x40\x02\x85\xc2\x60\x08\x85\xe8\x20\x01\x81\xe8\x00\x00\x90\x10\x20\x01\xd5\xf6\x10\x16\x21\x00\x00\x0a\x86\x00\x40\x02\x01\x00\x00\x00\x12\xbf\xff\xff\x10\xbf\xff\xff\xa0\x02\x00\x09\x0d\xbf\xff\xff\xd4\x20\x60\x00\xd4\x4e\x00\x16\x2a\xc2\x80\x03"
SPARCV9_CODE = b"\x81\xa8\x0a\x24\x89\xa0\x10\x20\x89\xa0\x1a\x60\x89\xa0\x00\xe0"
SYSZ_CODE = b"\xed\x00\x00\x00\x00\x1a\x5a\x0f\x1f\xff\xc2\x09\x80\x00\x00\x00\x07\xf7\xeb\x2a\xff\xff\x7f\x57\xe3\x01\xff\xff\x7f\x57\xeb\x00\xf0\x00\x00\x24\xb2\x4f\x00\x78"
XCORE_CODE = b"\xfe\x0f\xfe\x17\x13\x17\xc6\xfe\xec\x17\x97\xf8\xec\x4f\x1f\xfd\xec\x37\x07\xf2\x45\x5b\xf9\xfa\x02\x06\x1b\x10"
M68K_CODE = b"\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75"
TMS320C64X_CODE = b"\x01\xac\x88\x40\x81\xac\x88\x43\x00\x00\x00\x00\x02\x90\x32\x96\x02\x80\x46\x9e\x05\x3c\x83\xe6\x0b\x0c\x8b\x24"
M680X_CODE = b"\x06\x10\x19\x1a\x55\x1e\x01\x23\xe9\x31\x06\x34\x55\xa6\x81\xa7\x89\x7f\xff\xa6\x9d\x10\x00\xa7\x91\xa6\x9f\x10\x00\x11\xac\x99\x10\x00\x39"
EVM_CODE = b"\x60\x61"
WASM_CODE = b"\x20\x00\x20\x01\x41\x20\x10\xc9\x01\x45\x0b"
MOS65XX_CODE = b"\x0d\x34\x12\x00\x81\x65\x6c\x01\x00\x85\xFF\x10\x00\x19\x42\x42\x00\x49\x42"
EBPF_CODE = b"\x97\x09\x00\x00\x37\x13\x03\x00\xdc\x02\x00\x00\x20\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\xdb\x3a\x00\x01\x00\x00\x00\x00\x84\x02\x00\x00\x00\x00\x00\x00\x6d\x33\x17\x02\x00\x00\x00\x00"
RISCV_CODE32 = b"\x37\x34\x00\x00\x97\x82\x00\x00\xef\x00\x80\x00\xef\xf0\x1f\xff\xe7\x00\x45\x00\xe7\x00\xc0\xff\x63\x05\x41\x00\xe3\x9d\x61\xfe\x63\xca\x93\x00\x63\x53\xb5\x00\x63\x65\xd6\x00\x63\x76\xf7\x00\x03\x88\x18\x00\x03\x99\x49\x00\x03\xaa\x6a\x00\x03\xcb\x2b\x01\x03\xdc\x8c\x01\x23\x86\xad\x03\x23\x9a\xce\x03\x23\x8f\xef\x01\x93\x00\xe0\x00\x13\xa1\x01\x01\x13\xb2\x02\x7d\x13\xc3\x03\xdd\x13\xe4\xc4\x12\x13\xf5\x85\x0c\x13\x96\xe6\x01\x13\xd7\x97\x01\x13\xd8\xf8\x40\x33\x89\x49\x01\xb3\x0a\x7b\x41\x33\xac\xac\x01\xb3\x3d\xde\x01\x33\xd2\x62\x40\xb3\x43\x94\x00\x33\xe5\xc5\x00\xb3\x76\xf7\x00\xb3\x54\x39\x01\xb3\x50\x31\x00\x33\x9f\x0f\x00"
RISCV_CODE64 = b"\x13\x04\xa8\x7a"
ALPHA_CODE = b'\x02\x00\xbb\x27\x50\x7a\xbd\x23\xd0\xff\xde\x23\x00\x00\x5e\xb7'
ALPHA_CODE_BE = b'\x27\xbb\x00\x02\x23\xbd\x7a\x50\x23\xde\xff\xd0\xb7\x5e\x00\x00'
HPPA_20_CODE_BE = b'\x00\x20\x50\xa2\x00\x01\x58\x20\x00\x00\x44\xa1\x00\x41\x18\x40\x00\x20\x08\xa2\x01\x60\x48\xa1\x01\x61\x18\xc0\x00\x00\x14\xa1\x00\x0f\x0d\x61\x00\x0f\x0e\x61\x00\x01\x18\x60\x00\x00\x0c\x00\x00\x00\x0c\xa0\x03\xff\xc0\x1f\x00\x00\x04\x00\x00\x10\x04\x00\x04\x22\x51\x83\x04\x22\x51\xc3\x04\x22\x51\x83\x04\x2f\x71\x83\x04\x2f\x71\xc3\x04\x2f\x71\x83\x04\x41\x53\x43\x04\x41\x53\x63\x04\x41\x53\x03\x04\x41\x12\x00\x04\x41\x16\x00\x04\x41\x16\x20\x04\x41\x42\x00\x04\x41\x46\x00\x04\x41\x46\x20\x04\x41\x12\x40\x04\x41\x12\x60\x04\x41\x42\x40\x04\x41\x42\x60\x04\x41\x18\x00\x04\x41\x08\x00\x04\x41\x13\x80\x04\x41\x13\xa0\x04\x41\x52\x80\x04\x41\x52\xa0\x04\x5e\x72\x80\x04\x41\x42\x80\x04\x41\x52\xc0\x04\x41\x52\xe0\x04\x41\x42\xc0\x04\x41\x42\xe0\x14\x00\xde\xad'
HPPA_20_CODE = b'\xa2\x50\x20\x00\x20\x58\x01\x00\xa1\x44\x00\x00\x40\x18\x41\x00\xa2\x08\x20\x00\xa1\x48\x60\x01\xc0\x18\x61\x01\xa1\x14\x00\x00\x61\x0d\x0f\x00\x61\x0e\x0f\x00\x60\x18\x01\x00\x00\x0c\x00\x00\xa0\x0c\x00\x00\x1f\xc0\xff\x03\x00\x04\x00\x00\x00\x04\x10\x00\x83\x51\x22\x04\xc3\x51\x22\x04\x83\x51\x22\x04\x83\x71\x2f\x04\xc3\x71\x2f\x04\x83\x71\x2f\x04\x43\x53\x41\x04\x63\x53\x41\x04\x03\x53\x41\x04\x00\x12\x41\x04\x00\x16\x41\x04\x20\x16\x41\x04\x00\x42\x41\x04\x00\x46\x41\x04\x20\x46\x41\x04\x40\x12\x41\x04\x60\x12\x41\x04\x40\x42\x41\x04\x60\x42\x41\x04\x00\x18\x41\x04\x00\x08\x41\x04\x80\x13\x41\x04\xa0\x13\x41\x04\x80\x52\x41\x04\xa0\x52\x41\x04\x80\x72\x5e\x04\x80\x42\x41\x04\xc0\x52\x41\x04\xe0\x52\x41\x04\xc0\x42\x41\x04\xe0\x42\x41\x04\xad\xde\x00\x14'
HPPA_11_CODE_BE = b'\x24\x41\x40\xc3\x24\x41\x60\xc3\x24\x41\x40\xe3\x24\x41\x60\xe3\x24\x41\x68\xe3\x2c\x41\x40\xc3\x2c\x41\x60\xc3\x2c\x41\x40\xe3\x2c\x41\x60\xe3\x2c\x41\x68\xe3\x24\x62\x42\xc1\x24\x62\x62\xc1\x24\x62\x42\xe1\x24\x62\x46\xe1\x24\x62\x62\xe1\x24\x62\x6a\xe1\x2c\x62\x42\xc1\x2c\x62\x62\xc1\x2c\x62\x42\xe1\x2c\x62\x46\xe1\x2c\x62\x62\xe1\x2c\x62\x6a\xe1\x24\x3e\x50\xc2\x24\x3e\x50\xe2\x24\x3e\x70\xe2\x24\x3e\x78\xe2\x2c\x3e\x50\xc2\x2c\x3e\x50\xe2\x2c\x3e\x70\xe2\x2c\x3e\x78\xe2\x24\x5e\x52\xc1\x24\x5e\x52\xe1\x24\x5e\x56\xe1\x24\x5e\x72\xe1\x24\x5e\x7a\xe1\x2c\x5e\x52\xc1\x2c\x5e\x52\xe1\x2c\x5e\x56\xe1\x2c\x5e\x72\xe1\x2c\x5e\x7a\xe1'
HPPA_11_CODE = b'\xc3\x40\x41\x24\xc3\x60\x41\x24\xe3\x40\x41\x24\xe3\x60\x41\x24\xe3\x68\x41\x24\xc3\x40\x41\x2c\xc3\x60\x41\x2c\xe3\x40\x41\x2c\xe3\x60\x41\x2c\xe3\x68\x41\x2c\xc1\x42\x62\x24\xc1\x62\x62\x24\xe1\x42\x62\x24\xe1\x46\x62\x24\xe1\x62\x62\x24\xe1\x6a\x62\x24\xc1\x42\x62\x2c\xc1\x62\x62\x2c\xe1\x42\x62\x2c\xe1\x46\x62\x2c\xe1\x62\x62\x2c\xe1\x6a\x62\x2c\xc2\x50\x3e\x24\xe2\x50\x3e\x24\xe2\x70\x3e\x24\xe2\x78\x3e\x24\xc2\x50\x3e\x2c\xe2\x50\x3e\x2c\xe2\x70\x3e\x2c\xe2\x78\x3e\x2c\xc1\x52\x5e\x24\xe1\x52\x5e\x24\xe1\x56\x5e\x24\xe1\x72\x5e\x24\xe1\x7a\x5e\x24\xc1\x52\x5e\x2c\xe1\x52\x5e\x2c\xe1\x56\x5e\x2c\xe1\x72\x5e\x2c\xe1\x7a\x5e\x2c'
all_tests = (
(CS_ARCH_X86, CS_MODE_16, X86_CODE16, "X86 16bit (Intel syntax)", None),
(CS_ARCH_X86, CS_MODE_32, X86_CODE32, "X86 32bit (ATT syntax)", CS_OPT_SYNTAX_ATT),
(CS_ARCH_X86, CS_MODE_32, X86_CODE32, "X86 32 (Intel syntax)", None),
(CS_ARCH_X86, CS_MODE_32, X86_CODE32, "X86 32 (MASM syntax)", CS_OPT_SYNTAX_MASM),
(CS_ARCH_X86, CS_MODE_64, X86_CODE64, "X86 64 (Intel syntax)", None),
(CS_ARCH_ARM, CS_MODE_ARM, ARM_CODE, "ARM", None),
(CS_ARCH_ARM, CS_MODE_THUMB, THUMB_CODE2, "THUMB-2", None),
(CS_ARCH_ARM, CS_MODE_ARM, ARM_CODE2, "ARM: Cortex-A15 + NEON", None),
(CS_ARCH_ARM, CS_MODE_THUMB, THUMB_CODE, "THUMB", None),
(CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_MCLASS, THUMB_MCLASS, "Thumb-MClass", None),
(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_V8, ARMV8, "Arm-V8", None),
(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN, MIPS_CODE, "MIPS-32 (Big-endian)", None),
(CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_LITTLE_ENDIAN, MIPS_CODE2, "MIPS-64-EL (Little-endian)", None),
(CS_ARCH_MIPS, CS_MODE_MIPS32R6 + CS_MODE_MICRO + CS_MODE_BIG_ENDIAN, MIPS_32R6M, "MIPS-32R6 | Micro (Big-endian)", None),
(CS_ARCH_MIPS, CS_MODE_MIPS32R6 + CS_MODE_BIG_ENDIAN, MIPS_32R6, "MIPS-32R6 (Big-endian)", None),
(CS_ARCH_AARCH64, CS_MODE_ARM, AARCH64_CODE, "AARCH64", None),
(CS_ARCH_PPC, CS_MODE_BIG_ENDIAN, PPC_CODE, "PPC-64", None),
(CS_ARCH_PPC, CS_MODE_BIG_ENDIAN, PPC_CODE, "PPC-64, print register with number only", CS_OPT_SYNTAX_NOREGNAME),
(CS_ARCH_PPC, CS_MODE_BIG_ENDIAN + CS_MODE_QPX, PPC_CODE2, "PPC-64 + QPX", None),
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, SPARC_CODE, "Sparc", None),
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN + CS_MODE_V9, SPARCV9_CODE, "SparcV9", None),
(CS_ARCH_SYSZ, 0, SYSZ_CODE, "SystemZ", None),
(CS_ARCH_XCORE, 0, XCORE_CODE, "XCore", None),
(CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K", None),
(CS_ARCH_TMS320C64X, 0, TMS320C64X_CODE, "TMS320C64x", None),
(CS_ARCH_M680X, CS_MODE_M680X_6809, M680X_CODE, "M680X_M6809", None),
(CS_ARCH_EVM, 0, EVM_CODE, "EVM", None),
(CS_ARCH_WASM, 0, WASM_CODE, "WASM", None),
(CS_ARCH_MOS65XX, 0, MOS65XX_CODE, "MOS65XX", None),
(CS_ARCH_BPF, CS_MODE_LITTLE_ENDIAN | CS_MODE_BPF_EXTENDED, EBPF_CODE, "eBPF", None),
(CS_ARCH_RISCV, CS_MODE_RISCV32, RISCV_CODE32, "RISCV32", None),
(CS_ARCH_RISCV, CS_MODE_RISCV64, RISCV_CODE64, "RISCV64", None),
(CS_ARCH_ALPHA, CS_MODE_LITTLE_ENDIAN, ALPHA_CODE, "Alpha (Little-endian)", None),
(CS_ARCH_ALPHA, CS_MODE_BIG_ENDIAN, ALPHA_CODE_BE, "Alpha (Big-endian)", None),
(CS_ARCH_HPPA, CS_MODE_BIG_ENDIAN | CS_MODE_HPPA_20, HPPA_20_CODE_BE, "HPPA 2.0 (Big-endian)", None),
(CS_ARCH_HPPA, CS_MODE_LITTLE_ENDIAN | CS_MODE_HPPA_20, HPPA_20_CODE, "HPPA 2.0 (Little-endian)", None),
(CS_ARCH_HPPA, CS_MODE_BIG_ENDIAN | CS_MODE_HPPA_11, HPPA_11_CODE_BE, "HPPA 1.1 (Big-endian)", None),
(CS_ARCH_HPPA, CS_MODE_LITTLE_ENDIAN | CS_MODE_HPPA_11, HPPA_11_CODE, "HPPA 1.1 (Little-endian)", None),
)
# ## Test cs_disasm_quick()
def test_cs_disasm_quick():
for arch, mode, code, comment, syntax in all_tests:
print('*' * 40)
print("Platform: %s" % comment)
print("Disasm:")
print(to_hex(code))
for insn in cs_disasm_quick(arch, mode, code, 0x1000):
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
print()
def test_different_data_formats():
data = bytes.fromhex('4831C948F7E1043B48BB0A2F62696E2F2F736852530A545F5257545E0F05')
mnemonics = ['xor', 'mul', 'add', 'movabs', 'push', 'pop', 'push', 'push', 'push', 'pop', 'syscall']
disassembler = Cs(CS_ARCH_X86, CS_MODE_64)
for name, code in (
('bytearray', bytearray(data)),
('memoryview of bytearray', memoryview(bytearray(data))),
('memoryview of data', memoryview(data)),
('raw data', data)
):
if mnemonics != [op for _, _, op, _ in disassembler.disasm_lite(code, 0)]:
print('failure in disassemble-lite for %s.' % name)
if mnemonics != [instruction.mnemonic for instruction in disassembler.disasm(code, 0)]:
print('failure in disassemble-full for %s.' % name)
# ## Test class Cs
def test_class():
for arch, mode, code, comment, syntax in all_tests:
print('*' * 16)
print("Platform: %s" % comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
if syntax is not None:
md.syntax = syntax
for insn in md.disasm(code, 0x1000):
# bytes = binascii.hexlify(insn.bytes)
# print("0x%x:\t%s\t%s\t// hex-code: %s" %(insn.address, insn.mnemonic, insn.op_str, bytes))
print("0x%x:\t%s\t\t%s" % (insn.address, insn.mnemonic, insn.op_str))
print("0x%x:" % (insn.address + insn.size))
print()
except CsError as e:
print("ERROR: %s" % e)
# test_cs_disasm_quick()
# print ("*" * 40)
if __name__ == '__main__':
test_class()
test_different_data_formats()

View File

@ -1,91 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings
# BPF tests by david942j <david942j@gmail.com>, 2019
from capstone import *
from capstone.bpf import *
from xprint import to_hex, to_x, to_x_32
CBPF_CODE = b"\x94\x09\x00\x00\x37\x13\x03\x00\x87\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00"
EBPF_CODE = b"\x97\x09\x00\x00\x37\x13\x03\x00\xdc\x02\x00\x00\x20\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\xdb\x3a\x00\x01\x00\x00\x00\x00\x84\x02\x00\x00\x00\x00\x00\x00\x6d\x33\x17\x02\x00\x00\x00\x00"
all_tests = (
(CS_ARCH_BPF, CS_MODE_LITTLE_ENDIAN | CS_MODE_BPF_CLASSIC, CBPF_CODE, "cBPF Le", None),
(CS_ARCH_BPF, CS_MODE_LITTLE_ENDIAN | CS_MODE_BPF_EXTENDED, EBPF_CODE, "eBPF Le", None),
)
ext_name = {}
ext_name[BPF_EXT_LEN] = '#len'
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.groups) > 0:
print('\tGroups: ' + ' '.join(map(lambda g: insn.group_name(g), insn.groups)))
print("\tOperand count: %u" % len(insn.operands))
for c, op in enumerate(insn.operands):
print("\t\toperands[%u].type: " % c, end='')
if op.type == BPF_OP_REG:
print("REG = " + insn.reg_name(op.reg))
elif op.type == BPF_OP_IMM:
print("IMM = 0x" + to_x(op.imm))
elif op.type == BPF_OP_OFF:
print("OFF = +0x" + to_x_32(op.off))
elif op.type == BPF_OP_MEM:
print("MEM")
if op.mem.base != 0:
print("\t\t\toperands[%u].mem.base: REG = %s" \
% (c, insn.reg_name(op.mem.base)))
print("\t\t\toperands[%u].mem.disp: 0x%s" \
% (c, to_x_32(op.mem.disp)))
elif op.type == BPF_OP_MMEM:
print("MMEM = 0x" + to_x_32(op.mmem))
elif op.type == BPF_OP_MSH:
print("MSH = 4*([0x%s]&0xf)" % to_x_32(op.msh))
elif op.type == BPF_OP_EXT:
print("EXT = " + ext_name[op.ext])
(regs_read, regs_write) = insn.regs_access()
if len(regs_read) > 0:
print("\tRegisters read:", end="")
for r in regs_read:
print(" %s" % insn.reg_name(r), end="")
print("")
if len(regs_write) > 0:
print("\tRegisters modified:", end="")
for r in regs_write:
print(" %s" % insn.reg_name(r), end="")
print("")
def test_class():
for (arch, mode, code, comment, syntax) in all_tests:
print("*" * 16)
print("Platform: %s" % comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
if syntax is not None:
md.syntax = syntax
md.detail = True
for insn in md.disasm(code, 0x0):
print_insn_detail(insn)
print ()
except CsError as e:
print("ERROR: %s" % e)
if __name__ == '__main__':
test_class()

View File

@ -1,126 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
from capstone import *
from xprint import to_hex
X86_CODE16 = b"\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00"
X86_CODE32 = b"\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00"
X86_CODE64 = b"\x55\x48\x8b\x05\xb8\x13\x00\x00"
ARM_CODE = b"\xED\xFF\xFF\xEB\x04\xe0\x2d\xe5\x00\x00\x00\x00\xe0\x83\x22\xe5\xf1\x02\x03\x0e\x00\x00\xa0\xe3\x02\x30\xc1\xe7\x00\x00\x53\xe3"
ARM_CODE2 = b"\x10\xf1\x10\xe7\x11\xf2\x31\xe7\xdc\xa1\x2e\xf3\xe8\x4e\x62\xf3"
THUMB_CODE = b"\x70\x47\xeb\x46\x83\xb0\xc9\x68"
THUMB_CODE2 = b"\x4f\xf0\x00\x01\xbd\xe8\x00\x88\xd1\xe8\x00\xf0"
THUMB_MCLASS = b"\xef\xf3\x02\x80"
ARMV8 = b"\xe0\x3b\xb2\xee\x42\x00\x01\xe1\x51\xf0\x7f\xf5"
MIPS_CODE = b"\x0C\x10\x00\x97\x00\x00\x00\x00\x24\x02\x00\x0c\x8f\xa2\x00\x00\x34\x21\x34\x56\x00\x80\x04\x08"
MIPS_CODE2 = b"\x56\x34\x21\x34\xc2\x17\x01\x00"
MIPS_32R6M = b"\x00\x07\x00\x07\x00\x11\x93\x7c\x01\x8c\x8b\x7c\x00\xc7\x48\xd0"
MIPS_32R6 = b"\xec\x80\x00\x19\x7c\x43\x22\xa0"
AARCH64_CODE = b"\x09\x00\x38\xd5\xbf\x40\x00\xd5\x0c\x05\x13\xd5\x20\x50\x02\x0e\x20\xe4\x3d\x0f\x00\x18\xa0\x5f\xa2\x00\xae\x9e\x9f\x37\x03\xd5\xbf\x33\x03\xd5\xdf\x3f\x03\xd5\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x20\x04\x81\xda\x20\x08\x02\x8b\x10\x5b\xe8\x3c"
PPC_CODE = b"\x80\x20\x00\x00\x80\x3f\x00\x00\x10\x43\x23\x0e\xd0\x44\x00\x80\x4c\x43\x22\x02\x2d\x03\x00\x80\x7c\x43\x20\x14\x7c\x43\x20\x93\x4f\x20\x00\x21\x4c\xc8\x00\x21\x40\x82\x00\x14"
PPC_CODE2 = b"\x10\x60\x2a\x10\x10\x64\x28\x88\x7c\x4a\x5d\x0f"
SPARC_CODE = b"\x80\xa0\x40\x02\x85\xc2\x60\x08\x85\xe8\x20\x01\x81\xe8\x00\x00\x90\x10\x20\x01\xd5\xf6\x10\x16\x21\x00\x00\x0a\x86\x00\x40\x02\x01\x00\x00\x00\x12\xbf\xff\xff\x10\xbf\xff\xff\xa0\x02\x00\x09\x0d\xbf\xff\xff\xd4\x20\x60\x00\xd4\x4e\x00\x16\x2a\xc2\x80\x03"
SPARCV9_CODE = b"\x81\xa8\x0a\x24\x89\xa0\x10\x20\x89\xa0\x1a\x60\x89\xa0\x00\xe0"
SYSZ_CODE = b"\xed\x00\x00\x00\x00\x1a\x5a\x0f\x1f\xff\xc2\x09\x80\x00\x00\x00\x07\xf7\xeb\x2a\xff\xff\x7f\x57\xe3\x01\xff\xff\x7f\x57\xeb\x00\xf0\x00\x00\x24\xb2\x4f\x00\x78"
XCORE_CODE = b"\xfe\x0f\xfe\x17\x13\x17\xc6\xfe\xec\x17\x97\xf8\xec\x4f\x1f\xfd\xec\x37\x07\xf2\x45\x5b\xf9\xfa\x02\x06\x1b\x10"
M68K_CODE = b"\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75"
M680X_CODE = b"\x06\x10\x19\x1a\x55\x1e\x01\x23\xe9\x31\x06\x34\x55\xa6\x81\xa7\x89\x7f\xff\xa6\x9d\x10\x00\xa7\x91\xa6\x9f\x10\x00\x11\xac\x99\x10\x00\x39"
MOS65XX_CODE = b"\x0A\x00\xFE\x34\x12\xD0\xFF\xEA\x19\x56\x34\x46\x80"
EBPF_CODE = b"\x97\x09\x00\x00\x37\x13\x03\x00\xdc\x02\x00\x00\x20\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\xdb\x3a\x00\x01\x00\x00\x00\x00\x84\x02\x00\x00\x00\x00\x00\x00\x6d\x33\x17\x02\x00\x00\x00\x00"
ALPHA_CODE = b'\x02\x00\xbb\x27\x50\x7a\xbd\x23\xd0\xff\xde\x23\x00\x00\x5e\xb7'
ALPHA_CODE_BE = b'\x27\xbb\x00\x02\x23\xbd\x7a\x50\x23\xde\xff\xd0\xb7\x5e\x00\x00'
HPPA_20_CODE_BE = b'\x00\x20\x50\xa2\x00\x01\x58\x20\x00\x00\x44\xa1\x00\x41\x18\x40\x00\x20\x08\xa2\x01\x60\x48\xa1\x01\x61\x18\xc0\x00\x00\x14\xa1\x00\x0f\x0d\x61\x00\x0f\x0e\x61\x00\x01\x18\x60\x00\x00\x0c\x00\x00\x00\x0c\xa0\x03\xff\xc0\x1f\x00\x00\x04\x00\x00\x10\x04\x00\x04\x22\x51\x83\x04\x22\x51\xc3\x04\x22\x51\x83\x04\x2f\x71\x83\x04\x2f\x71\xc3\x04\x2f\x71\x83\x04\x41\x53\x43\x04\x41\x53\x63\x04\x41\x53\x03\x04\x41\x12\x00\x04\x41\x16\x00\x04\x41\x16\x20\x04\x41\x42\x00\x04\x41\x46\x00\x04\x41\x46\x20\x04\x41\x12\x40\x04\x41\x12\x60\x04\x41\x42\x40\x04\x41\x42\x60\x04\x41\x18\x00\x04\x41\x08\x00\x04\x41\x13\x80\x04\x41\x13\xa0\x04\x41\x52\x80\x04\x41\x52\xa0\x04\x5e\x72\x80\x04\x41\x42\x80\x04\x41\x52\xc0\x04\x41\x52\xe0\x04\x41\x42\xc0\x04\x41\x42\xe0\x14\x00\xde\xad'
HPPA_20_CODE = b'\xa2\x50\x20\x00\x20\x58\x01\x00\xa1\x44\x00\x00\x40\x18\x41\x00\xa2\x08\x20\x00\xa1\x48\x60\x01\xc0\x18\x61\x01\xa1\x14\x00\x00\x61\x0d\x0f\x00\x61\x0e\x0f\x00\x60\x18\x01\x00\x00\x0c\x00\x00\xa0\x0c\x00\x00\x1f\xc0\xff\x03\x00\x04\x00\x00\x00\x04\x10\x00\x83\x51\x22\x04\xc3\x51\x22\x04\x83\x51\x22\x04\x83\x71\x2f\x04\xc3\x71\x2f\x04\x83\x71\x2f\x04\x43\x53\x41\x04\x63\x53\x41\x04\x03\x53\x41\x04\x00\x12\x41\x04\x00\x16\x41\x04\x20\x16\x41\x04\x00\x42\x41\x04\x00\x46\x41\x04\x20\x46\x41\x04\x40\x12\x41\x04\x60\x12\x41\x04\x40\x42\x41\x04\x60\x42\x41\x04\x00\x18\x41\x04\x00\x08\x41\x04\x80\x13\x41\x04\xa0\x13\x41\x04\x80\x52\x41\x04\xa0\x52\x41\x04\x80\x72\x5e\x04\x80\x42\x41\x04\xc0\x52\x41\x04\xe0\x52\x41\x04\xc0\x42\x41\x04\xe0\x42\x41\x04\xad\xde\x00\x14'
HPPA_11_CODE_BE = b'\x24\x41\x40\xc3\x24\x41\x60\xc3\x24\x41\x40\xe3\x24\x41\x60\xe3\x24\x41\x68\xe3\x2c\x41\x40\xc3\x2c\x41\x60\xc3\x2c\x41\x40\xe3\x2c\x41\x60\xe3\x2c\x41\x68\xe3\x24\x62\x42\xc1\x24\x62\x62\xc1\x24\x62\x42\xe1\x24\x62\x46\xe1\x24\x62\x62\xe1\x24\x62\x6a\xe1\x2c\x62\x42\xc1\x2c\x62\x62\xc1\x2c\x62\x42\xe1\x2c\x62\x46\xe1\x2c\x62\x62\xe1\x2c\x62\x6a\xe1\x24\x3e\x50\xc2\x24\x3e\x50\xe2\x24\x3e\x70\xe2\x24\x3e\x78\xe2\x2c\x3e\x50\xc2\x2c\x3e\x50\xe2\x2c\x3e\x70\xe2\x2c\x3e\x78\xe2\x24\x5e\x52\xc1\x24\x5e\x52\xe1\x24\x5e\x56\xe1\x24\x5e\x72\xe1\x24\x5e\x7a\xe1\x2c\x5e\x52\xc1\x2c\x5e\x52\xe1\x2c\x5e\x56\xe1\x2c\x5e\x72\xe1\x2c\x5e\x7a\xe1'
HPPA_11_CODE = b'\xc3\x40\x41\x24\xc3\x60\x41\x24\xe3\x40\x41\x24\xe3\x60\x41\x24\xe3\x68\x41\x24\xc3\x40\x41\x2c\xc3\x60\x41\x2c\xe3\x40\x41\x2c\xe3\x60\x41\x2c\xe3\x68\x41\x2c\xc1\x42\x62\x24\xc1\x62\x62\x24\xe1\x42\x62\x24\xe1\x46\x62\x24\xe1\x62\x62\x24\xe1\x6a\x62\x24\xc1\x42\x62\x2c\xc1\x62\x62\x2c\xe1\x42\x62\x2c\xe1\x46\x62\x2c\xe1\x62\x62\x2c\xe1\x6a\x62\x2c\xc2\x50\x3e\x24\xe2\x50\x3e\x24\xe2\x70\x3e\x24\xe2\x78\x3e\x24\xc2\x50\x3e\x2c\xe2\x50\x3e\x2c\xe2\x70\x3e\x2c\xe2\x78\x3e\x2c\xc1\x52\x5e\x24\xe1\x52\x5e\x24\xe1\x56\x5e\x24\xe1\x72\x5e\x24\xe1\x7a\x5e\x24\xc1\x52\x5e\x2c\xe1\x52\x5e\x2c\xe1\x56\x5e\x2c\xe1\x72\x5e\x2c\xe1\x7a\x5e\x2c'
all_tests = (
(CS_ARCH_X86, CS_MODE_16, X86_CODE16, "X86 16bit (Intel syntax)", None),
(CS_ARCH_X86, CS_MODE_32, X86_CODE32, "X86 32bit (ATT syntax)", CS_OPT_SYNTAX_ATT),
(CS_ARCH_X86, CS_MODE_32, X86_CODE32, "X86 32 (Intel syntax)", None),
(CS_ARCH_X86, CS_MODE_64, X86_CODE64, "X86 64 (Intel syntax)", None),
(CS_ARCH_ARM, CS_MODE_ARM, ARM_CODE, "ARM", None),
(CS_ARCH_ARM, CS_MODE_ARM, ARM_CODE2, "ARM: Cortex-A15 + NEON", None),
(CS_ARCH_ARM, CS_MODE_THUMB, THUMB_CODE, "THUMB", None),
(CS_ARCH_ARM, CS_MODE_THUMB, THUMB_CODE2, "THUMB-2", None),
(CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_MCLASS, THUMB_MCLASS, "Thumb-MClass", None),
(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_V8, ARMV8, "Arm-V8", None),
(CS_ARCH_AARCH64, CS_MODE_ARM, AARCH64_CODE, "AARCH64", None),
(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN, MIPS_CODE, "MIPS-32 (Big-endian)", None),
(CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_LITTLE_ENDIAN, MIPS_CODE2, "MIPS-64-EL (Little-endian)", None),
(CS_ARCH_MIPS, CS_MODE_MIPS32R6 + CS_MODE_MICRO + CS_MODE_BIG_ENDIAN, MIPS_32R6M, "MIPS-32R6 | Micro (Big-endian)", None),
(CS_ARCH_MIPS, CS_MODE_MIPS32R6 + CS_MODE_BIG_ENDIAN, MIPS_32R6, "MIPS-32R6 (Big-endian)", None),
(CS_ARCH_PPC, CS_MODE_BIG_ENDIAN, PPC_CODE, "PPC-64", None),
(CS_ARCH_PPC, CS_MODE_BIG_ENDIAN + CS_MODE_QPX, PPC_CODE2, "PPC-64 + QPX", None),
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, SPARC_CODE, "Sparc", None),
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN + CS_MODE_V9, SPARCV9_CODE, "SparcV9", None),
(CS_ARCH_SYSZ, 0, SYSZ_CODE, "SystemZ", None),
(CS_ARCH_XCORE, 0, XCORE_CODE, "XCore", None),
(CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K", None),
(CS_ARCH_M680X, CS_MODE_M680X_6809, M680X_CODE, "M680X_M6809", None),
(CS_ARCH_MOS65XX, 0, MOS65XX_CODE, "MOS65XX", None),
(CS_ARCH_BPF, CS_MODE_LITTLE_ENDIAN | CS_MODE_BPF_EXTENDED, EBPF_CODE, "eBPF", None),
(CS_ARCH_ALPHA, CS_MODE_LITTLE_ENDIAN, ALPHA_CODE, "Alpha (Little-endian)", None),
(CS_ARCH_ALPHA, CS_MODE_BIG_ENDIAN, ALPHA_CODE_BE, "Alpha (Big-endian)", None),
(CS_ARCH_HPPA, CS_MODE_BIG_ENDIAN | CS_MODE_HPPA_20, HPPA_20_CODE_BE, "HPPA 2.0 (Big-endian)", None),
(CS_ARCH_HPPA, CS_MODE_LITTLE_ENDIAN | CS_MODE_HPPA_20, HPPA_20_CODE, "HPPA 2.0 (Little-endian)", None),
(CS_ARCH_HPPA, CS_MODE_BIG_ENDIAN | CS_MODE_HPPA_11, HPPA_11_CODE_BE, "HPPA 1.1 (Big-endian)", None),
(CS_ARCH_HPPA, CS_MODE_LITTLE_ENDIAN | CS_MODE_HPPA_11, HPPA_11_CODE, "HPPA 1.1 (Little-endian)", None),
)
def print_detail(insn):
print("0x%x:\t%s\t%s // insn-ID: %u, insn-mnem: %s" \
% (insn.address, insn.mnemonic, insn.op_str, insn.id, \
insn.insn_name()))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.regs_read) > 0:
print("\tImplicit registers read: ", end='')
for m in insn.regs_read:
print("%s " % insn.reg_name(m), end='')
print()
if len(insn.regs_write) > 0:
print("\tImplicit registers modified: ", end='')
for m in insn.regs_write:
print("%s " % insn.reg_name(m), end='')
print()
if len(insn.groups) > 0:
print("\tThis instruction belongs to groups: ", end='')
for m in insn.groups:
print("%s " % insn.group_name(m), end='')
print()
# ## Test class Cs
def test_class():
for (arch, mode, code, comment, syntax) in all_tests:
print('*' * 16)
print("Platform: %s" % comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
if syntax is not None:
md.syntax = syntax
for insn in md.disasm(code, 0x1000):
print_detail(insn)
print("0x%x:" % (insn.address + insn.size))
print()
except CsError as e:
print("ERROR: %s" % e)
if __name__ == '__main__':
test_class()

View File

@ -1,48 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
from capstone import *
from xprint import to_hex
EVM_CODE = b"\x60\x61\x50"
all_tests = (
(CS_ARCH_EVM, 0, EVM_CODE, "EVM"),
)
def test_class():
address = 0x80001000
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" % comment)
print("Code: %s " % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
for i in md.disasm(code, address):
print("0x%x:\t%s\t%s" %(i.address, i.mnemonic, i.op_str))
if i.pop > 0:
print("\tPop: %u" %i.pop)
if i.push > 0:
print("\tPush: %u" %i.push)
if i.fee > 0:
print("\tGas fee: %u" %i.fee)
if len(i.groups) > 0:
print("\tGroups: ", end=''),
for m in i.groups:
print("%s " % i.group_name(m), end=''),
print()
print ("0x%x:\n" % (i.address + i.size))
except CsError as e:
print("ERROR: %s" % e.__str__())
if __name__ == '__main__':
test_class()

View File

@ -1,74 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Dmitry Sibirtsev <sibirtsev_dl@gmail.com>
from capstone import *
from capstone.hppa import *
from xprint import to_x, to_hex
HPPA_20_CODE_BE = b'\x00\x20\x50\xa2\x00\x01\x58\x20\x00\x00\x44\xa1\x00\x41\x18\x40\x00\x20\x08\xa2\x01\x60\x48\xa1\x01\x61\x18\xc0\x00\x00\x14\xa1\x00\x0f\x0d\x61\x00\x0f\x0e\x61\x00\x01\x18\x60\x00\x00\x0c\x00\x00\x00\x0c\xa0\x03\xff\xc0\x1f\x00\x00\x04\x00\x00\x10\x04\x00\x04\x22\x51\x83\x04\x22\x51\xc3\x04\x22\x51\x83\x04\x2f\x71\x83\x04\x2f\x71\xc3\x04\x2f\x71\x83\x04\x41\x53\x43\x04\x41\x53\x63\x04\x41\x53\x03\x04\x41\x12\x00\x04\x41\x16\x00\x04\x41\x16\x20\x04\x41\x42\x00\x04\x41\x46\x00\x04\x41\x46\x20\x04\x41\x12\x40\x04\x41\x12\x60\x04\x41\x42\x40\x04\x41\x42\x60\x04\x41\x18\x00\x04\x41\x08\x00\x04\x41\x13\x80\x04\x41\x13\xa0\x04\x41\x52\x80\x04\x41\x52\xa0\x04\x5e\x72\x80\x04\x41\x42\x80\x04\x41\x52\xc0\x04\x41\x52\xe0\x04\x41\x42\xc0\x04\x41\x42\xe0\x14\x00\xde\xad'
HPPA_20_CODE = b'\xa2\x50\x20\x00\x20\x58\x01\x00\xa1\x44\x00\x00\x40\x18\x41\x00\xa2\x08\x20\x00\xa1\x48\x60\x01\xc0\x18\x61\x01\xa1\x14\x00\x00\x61\x0d\x0f\x00\x61\x0e\x0f\x00\x60\x18\x01\x00\x00\x0c\x00\x00\xa0\x0c\x00\x00\x1f\xc0\xff\x03\x00\x04\x00\x00\x00\x04\x10\x00\x83\x51\x22\x04\xc3\x51\x22\x04\x83\x51\x22\x04\x83\x71\x2f\x04\xc3\x71\x2f\x04\x83\x71\x2f\x04\x43\x53\x41\x04\x63\x53\x41\x04\x03\x53\x41\x04\x00\x12\x41\x04\x00\x16\x41\x04\x20\x16\x41\x04\x00\x42\x41\x04\x00\x46\x41\x04\x20\x46\x41\x04\x40\x12\x41\x04\x60\x12\x41\x04\x40\x42\x41\x04\x60\x42\x41\x04\x00\x18\x41\x04\x00\x08\x41\x04\x80\x13\x41\x04\xa0\x13\x41\x04\x80\x52\x41\x04\xa0\x52\x41\x04\x80\x72\x5e\x04\x80\x42\x41\x04\xc0\x52\x41\x04\xe0\x52\x41\x04\xc0\x42\x41\x04\xe0\x42\x41\x04\xad\xde\x00\x14'
HPPA_11_CODE_BE = b'\x24\x41\x40\xc3\x24\x41\x60\xc3\x24\x41\x40\xe3\x24\x41\x60\xe3\x24\x41\x68\xe3\x2c\x41\x40\xc3\x2c\x41\x60\xc3\x2c\x41\x40\xe3\x2c\x41\x60\xe3\x2c\x41\x68\xe3\x24\x62\x42\xc1\x24\x62\x62\xc1\x24\x62\x42\xe1\x24\x62\x46\xe1\x24\x62\x62\xe1\x24\x62\x6a\xe1\x2c\x62\x42\xc1\x2c\x62\x62\xc1\x2c\x62\x42\xe1\x2c\x62\x46\xe1\x2c\x62\x62\xe1\x2c\x62\x6a\xe1\x24\x3e\x50\xc2\x24\x3e\x50\xe2\x24\x3e\x70\xe2\x24\x3e\x78\xe2\x2c\x3e\x50\xc2\x2c\x3e\x50\xe2\x2c\x3e\x70\xe2\x2c\x3e\x78\xe2\x24\x5e\x52\xc1\x24\x5e\x52\xe1\x24\x5e\x56\xe1\x24\x5e\x72\xe1\x24\x5e\x7a\xe1\x2c\x5e\x52\xc1\x2c\x5e\x52\xe1\x2c\x5e\x56\xe1\x2c\x5e\x72\xe1\x2c\x5e\x7a\xe1'
HPPA_11_CODE = b'\xc3\x40\x41\x24\xc3\x60\x41\x24\xe3\x40\x41\x24\xe3\x60\x41\x24\xe3\x68\x41\x24\xc3\x40\x41\x2c\xc3\x60\x41\x2c\xe3\x40\x41\x2c\xe3\x60\x41\x2c\xe3\x68\x41\x2c\xc1\x42\x62\x24\xc1\x62\x62\x24\xe1\x42\x62\x24\xe1\x46\x62\x24\xe1\x62\x62\x24\xe1\x6a\x62\x24\xc1\x42\x62\x2c\xc1\x62\x62\x2c\xe1\x42\x62\x2c\xe1\x46\x62\x2c\xe1\x62\x62\x2c\xe1\x6a\x62\x2c\xc2\x50\x3e\x24\xe2\x50\x3e\x24\xe2\x70\x3e\x24\xe2\x78\x3e\x24\xc2\x50\x3e\x2c\xe2\x50\x3e\x2c\xe2\x70\x3e\x2c\xe2\x78\x3e\x2c\xc1\x52\x5e\x24\xe1\x52\x5e\x24\xe1\x56\x5e\x24\xe1\x72\x5e\x24\xe1\x7a\x5e\x24\xc1\x52\x5e\x2c\xe1\x52\x5e\x2c\xe1\x56\x5e\x2c\xe1\x72\x5e\x2c\xe1\x7a\x5e\x2c'
all_tests = (
(CS_ARCH_HPPA, CS_MODE_BIG_ENDIAN | CS_MODE_HPPA_20, HPPA_20_CODE_BE, "HPPA 2.0 (Big-endian)"),
(CS_ARCH_HPPA, CS_MODE_LITTLE_ENDIAN | CS_MODE_HPPA_20, HPPA_20_CODE, "HPPA 2.0 (Little-endian)"),
(CS_ARCH_HPPA, CS_MODE_BIG_ENDIAN | CS_MODE_HPPA_11, HPPA_11_CODE_BE, "HPPA 1.1 (Big-endian)"),
(CS_ARCH_HPPA, CS_MODE_LITTLE_ENDIAN | CS_MODE_HPPA_11, HPPA_11_CODE, "HPPA 1.1 (Little-endian)"),
)
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = 0
for i in insn.operands:
if i.type == HPPA_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
if i.type == HPPA_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm)))
if i.type == HPPA_OP_IDX_REG:
print("\t\toperands[%u].type: IDX_REG = %s" % (c, insn.reg_name(i.reg)))
if i.type == HPPA_OP_DISP:
print("\t\toperands[%u].type: DISP = 0x%s" % (c, to_x(i.imm)))
if i.type == HPPA_OP_MEM:
print("\t\toperands[%u].type: MEM" % c)
if i.mem.space != HPPA_REG_INVALID:
print("\t\t\toperands[%u].mem.space: REG = %s" % (c, insn.reg_name(i.mem.space)))
print("\t\t\toperands[%u].mem.base: REG = %s" % (c, insn.reg_name(i.mem.base)))
if i.type == HPPA_OP_TARGET:
if i.imm >= 0x8000000000000000:
print("TARGET = -0x%lx" % i.imm)
else:
print("TARGET = 0x%lx" % i.imm)
c += 1
# ## Test class Cs
def test_class():
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" % comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
for insn in md.disasm(code, 0x1000):
print_insn_detail(insn)
print()
print("0x%x:\n" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" % e)
if __name__ == '__main__':
test_class()

View File

@ -1,153 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net>
from capstone import *
from capstone.m680x import *
s_access = (
"UNCHANGED", "READ", "WRITE", "READ | WRITE",
)
M6800_CODE = b"\x01\x09\x36\x64\x7f\x74\x10\x00\x90\x10\xA4\x10\xb6\x10\x00\x39"
M6801_CODE = b"\x04\x05\x3c\x3d\x38\x93\x10\xec\x10\xed\x10\x39"
M6805_CODE = b"\x04\x7f\x00\x17\x22\x28\x00\x2e\x00\x40\x42\x5a\x70\x8e\x97\x9c\xa0\x15\xad\x00\xc3\x10\x00\xda\x12\x34\xe5\x7f\xfe"
M6808_CODE = b"\x31\x22\x00\x35\x22\x45\x10\x00\x4b\x00\x51\x10\x52\x5e\x22\x62\x65\x12\x34\x72\x84\x85\x86\x87\x8a\x8b\x8c\x94\x95\xa7\x10\xaf\x10\x9e\x60\x7f\x9e\x6b\x7f\x00\x9e\xd6\x10\x00\x9e\xe6\x7f"
HCS08_CODE = b"\x32\x10\x00\x9e\xae\x9e\xce\x7f\x9e\xbe\x10\x00\x9e\xfe\x7f\x3e\x10\x00\x9e\xf3\x7f\x96\x10\x00\x9e\xff\x7f\x82"
HD6301_CODE = b"\x6b\x10\x00\x71\x10\x00\x72\x10\x10\x39"
M6809_CODE = b"\x06\x10\x19\x1a\x55\x1e\x01\x23\xe9\x31\x06\x34\x55\xa6\x81\xa7\x89\x7f\xff\xa6\x9d\x10\x00\xa7\x91\xa6\x9f\x10\x00\x11\xac\x99\x10\x00\x39\xA6\x07\xA6\x27\xA6\x47\xA6\x67\xA6\x0F\xA6\x10\xA6\x80\xA6\x81\xA6\x82\xA6\x83\xA6\x84\xA6\x85\xA6\x86\xA6\x88\x7F\xA6\x88\x80\xA6\x89\x7F\xFF\xA6\x89\x80\x00\xA6\x8B\xA6\x8C\x10\xA6\x8D\x10\x00\xA6\x91\xA6\x93\xA6\x94\xA6\x95\xA6\x96\xA6\x98\x7F\xA6\x98\x80\xA6\x99\x7F\xFF\xA6\x99\x80\x00\xA6\x9B\xA6\x9C\x10\xA6\x9D\x10\x00\xA6\x9F\x10\x00"
M6811_CODE = b"\x02\x03\x12\x7f\x10\x00\x13\x99\x08\x00\x14\x7f\x02\x15\x7f\x01\x1e\x7f\x20\x00\x8f\xcf\x18\x08\x18\x30\x18\x3c\x18\x67\x18\x8c\x10\x00\x18\x8f\x18\xce\x10\x00\x18\xff\x10\x00\x1a\xa3\x7f\x1a\xac\x1a\xee\x7f\x1a\xef\x7f\xcd\xac\x7f"
CPU12_CODE = b"\x00\x04\x01\x00\x0c\x00\x80\x0e\x00\x80\x00\x11\x1e\x10\x00\x80\x00\x3b\x4a\x10\x00\x04\x4b\x01\x04\x4f\x7f\x80\x00\x8f\x10\x00\xb7\x52\xb7\xb1\xa6\x67\xa6\xfe\xa6\xf7\x18\x02\xe2\x30\x39\xe2\x10\x00\x18\x0c\x30\x39\x10\x00\x18\x11\x18\x12\x10\x00\x18\x19\x00\x18\x1e\x00\x18\x3e\x18\x3f\x00"
HD6309_CODE = b"\x01\x10\x10\x62\x10\x10\x7b\x10\x10\x00\xcd\x49\x96\x02\xd2\x10\x30\x23\x10\x38\x10\x3b\x10\x53\x10\x5d\x11\x30\x43\x10\x11\x37\x25\x10\x11\x38\x12\x11\x39\x23\x11\x3b\x34\x11\x8e\x10\x00\x11\xaf\x10\x11\xab\x10\x11\xf6\x80\x00"
all_tests = (
(CS_ARCH_M680X, CS_MODE_M680X_6301, HD6301_CODE, "M680X_HD6301", None),
(CS_ARCH_M680X, CS_MODE_M680X_6309, HD6309_CODE, "M680X_HD6309", None),
(CS_ARCH_M680X, CS_MODE_M680X_6800, M6800_CODE, "M680X_M6800", None),
(CS_ARCH_M680X, CS_MODE_M680X_6801, M6801_CODE, "M680X_M6801", None),
(CS_ARCH_M680X, CS_MODE_M680X_6805, M6805_CODE, "M680X_M68HC05", None),
(CS_ARCH_M680X, CS_MODE_M680X_6808, M6808_CODE, "M680X_M68HC08", None),
(CS_ARCH_M680X, CS_MODE_M680X_6809, M6809_CODE, "M680X_M6809", None),
(CS_ARCH_M680X, CS_MODE_M680X_6811, M6811_CODE, "M680X_M68HC11", None),
(CS_ARCH_M680X, CS_MODE_M680X_CPU12, CPU12_CODE, "M680X_CPU12", None),
(CS_ARCH_M680X, CS_MODE_M680X_HCS08, HCS08_CODE, "M680X_HCS08", None),
)
# print hex dump from string all upper case
def to_hex_uc(string):
return " ".join("0x%02x" % c for c in string)
# print short hex dump from byte array all upper case
def to_hex_short_uc(byte_array):
return "".join("%02x" % b for b in byte_array)
def print_insn_detail(insn):
# print address, mnemonic and operands
#print("0x%x:\t%s\t%s\t%s" % (insn.address, binascii.hexlify(bytearray(insn.bytes)), \
print("0x%04x: %s\t%s\t%s" % (insn.address, to_hex_short_uc(insn.bytes), \
insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = 0
for i in insn.operands:
if i.type == M680X_OP_REGISTER:
comment = "";
if (((c == 0) and (insn.flags & M680X_FIRST_OP_IN_MNEM)) or
((c == 1) and (insn.flags & M680X_SECOND_OP_IN_MNEM))):
comment = " (in mnemonic)";
print("\t\toperands[%u].type: REGISTER = %s%s" % (c,
insn.reg_name(i.reg), comment))
if i.type == M680X_OP_CONSTANT:
print("\t\toperands[%u].type: CONSTANT = %u" % (c, i.const_val))
if i.type == M680X_OP_IMMEDIATE:
print("\t\toperands[%u].type: IMMEDIATE = #%d" % (c, i.imm))
if i.type == M680X_OP_DIRECT:
print("\t\toperands[%u].type: DIRECT = 0x%02x" % (c, i.direct_addr))
if i.type == M680X_OP_EXTENDED:
if i.ext.indirect:
indirect = "INDIRECT"
else:
indirect = ""
print("\t\toperands[%u].type: EXTENDED %s = 0x%04x" % (c, indirect, i.ext.address))
if i.type == M680X_OP_RELATIVE:
print("\t\toperands[%u].type: RELATIVE = 0x%04x" % (c, i.rel.address))
if i.type == M680X_OP_INDEXED:
if (i.idx.flags & M680X_IDX_INDIRECT):
indirect = " INDIRECT"
else:
indirect = ""
print("\t\toperands[%u].type: INDEXED%s" % (c, indirect))
if i.idx.base_reg != M680X_REG_INVALID:
print("\t\t\tbase register: %s" % insn.reg_name(i.idx.base_reg))
if i.idx.offset_reg != M680X_REG_INVALID:
print("\t\t\toffset register: %s" % insn.reg_name(i.idx.offset_reg))
if (i.idx.offset_bits != 0) and (i.idx.offset_reg == M680X_REG_INVALID) and (i.idx.inc_dec == 0):
print("\t\t\toffset: %u" % i.idx.offset)
if i.idx.base_reg == M680X_REG_PC:
print("\t\t\toffset address: 0x%04x" % i.idx.offset_addr)
print("\t\t\toffset bits: %u" % i.idx.offset_bits)
if i.idx.inc_dec != 0:
if i.idx.flags & M680X_IDX_POST_INC_DEC:
s_post_pre = "post"
else:
s_post_pre = "pre"
if i.idx.inc_dec > 0:
s_inc_dec = "increment"
else:
s_inc_dec = "decrement"
print("\t\t\t%s %s: %d" %
(s_post_pre, s_inc_dec, abs(i.idx.inc_dec)))
if (i.size != 0):
print("\t\t\tsize: %d" % i.size)
if (i.access != CS_AC_INVALID):
print("\t\t\taccess: %s" % s_access[i.access])
c += 1
(regs_read, regs_write) = insn.regs_access()
if len(regs_read) > 0:
print("\tRegisters read:", end="")
for r in regs_read:
print(" %s" %(insn.reg_name(r)), end="")
print("")
if len(regs_write) > 0:
print("\tRegisters modified:", end="")
for r in regs_write:
print(" %s" %(insn.reg_name(r)), end="")
print("")
if len(insn.groups) > 0:
print("\tgroups_count: %u" % len(insn.groups))
# ## Test class Cs
def test_class():
for (arch, mode, code, comment, syntax) in all_tests:
print("*" * 20)
print("Platform: %s" % comment)
print("Code: %s" % to_hex_uc(code))
print("Disasm:")
try:
md = Cs(arch, mode)
if syntax is not None:
md.syntax = syntax
md.detail = True
for insn in md.disasm(code, 0x1000):
print_insn_detail(insn)
print ()
except CsError as e:
print("ERROR: %s" % e)
if __name__ == '__main__':
test_class()

View File

@ -1,123 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Nicolas PLANEL <nplanel@gmail.com>
from capstone import *
from capstone.m68k import *
from xprint import to_hex
M68K_CODE = b"\xf0\x10\xf0\x00\x48\xaf\xff\xff\x7f\xff\x11\xb0\x01\x37\x7f\xff\xff\xff\x12\x34\x56\x78\x01\x33\x10\x10\x10\x10\x32\x32\x32\x32\x4C\x00\x54\x04\x48\xe7\xe0\x30\x4C\xDF\x0C\x07\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75"
all_tests = (
(CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K"),
)
s_addressing_modes = {
0: "<invalid mode>",
1: "Register Direct - Data",
2: "Register Direct - Address",
3: "Register Indirect - Address",
4: "Register Indirect - Address with Postincrement",
5: "Register Indirect - Address with Predecrement",
6: "Register Indirect - Address with Displacement",
7: "Address Register Indirect With Index - 8-bit displacement",
8: "Address Register Indirect With Index - Base displacement",
9: "Memory indirect - Postindex",
10: "Memory indirect - Preindex",
11: "Program Counter Indirect - with Displacement",
12: "Program Counter Indirect with Index - with 8-Bit Displacement",
13: "Program Counter Indirect with Index - with Base Displacement",
14: "Program Counter Memory Indirect - Postindexed",
15: "Program Counter Memory Indirect - Preindexed",
16: "Absolute Data Addressing - Short",
17: "Absolute Data Addressing - Long",
18: "Immediate value",
19: "Branch Displacement",
}
def print_read_write_regs(insn):
for m in insn.regs_read:
print("\treading from reg: %s" % insn.reg_name(m))
for m in insn.regs_write:
print("\twriting to reg: %s" % insn.reg_name(m))
def print_insn_detail(insn):
if len(insn.operands) > 0:
print("\top_count: %u" % (len(insn.operands)))
print_read_write_regs(insn)
print("\tgroups_count: %u" % len(insn.groups))
for i, op in enumerate(insn.operands):
if op.type == M68K_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (i, insn.reg_name(op.reg)))
elif op.type == M68K_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%x" % (i, op.imm & 0xffffffff))
elif op.type == M68K_OP_MEM:
print("\t\toperands[%u].type: MEM" % (i))
if op.mem.base_reg != M68K_REG_INVALID:
print("\t\t\toperands[%u].mem.base: REG = %s" % (i, insn.reg_name(op.mem.base_reg)))
if op.mem.index_reg != M68K_REG_INVALID:
print("\t\t\toperands[%u].mem.index: REG = %s" % (i, insn.reg_name(op.mem.index_reg)))
mem_index_str = "w"
if op.mem.index_size > 0:
mem_index_str = "l"
print("\t\t\toperands[%u].mem.index: size = %s" % (i, mem_index_str))
if op.mem.disp != 0:
print("\t\t\toperands[%u].mem.disp: 0x%x" % (i, op.mem.disp))
if op.mem.scale != 0:
print("\t\t\toperands[%u].mem.scale: %d" % (i, op.mem.scale))
print("\t\taddress mode: %s" % (s_addressing_modes[op.address_mode]))
elif op.type == M68K_OP_FP_SINGLE:
print("\t\toperands[%u].type: FP_SINGLE" % i)
print("\t\toperands[%u].simm: %f" % (i, op.simm))
elif op.type == M68K_OP_FP_DOUBLE:
print("\t\toperands[%u].type: FP_DOUBLE" % i)
print("\t\toperands[%u].dimm: %lf" % (i, op.dimm))
elif op.type == M68K_OP_REG_BITS:
print("\t\toperands[%u].type: REG_BITS = $%x" % (i, op.register_bits))
elif op.type == M68K_OP_REG_PAIR:
print("\t\toperands[%u].type: REG_PAIR = (%s, %s)" % (i, insn.reg_name(op.reg_pair.reg_0), insn.reg_name(op.reg_pair.reg_1)))
elif op.type == M68K_OP_BR_DISP:
print("\t\toperands[%u].br_disp.disp: 0x%x" % (i, op.br_disp.disp))
print("\t\toperands[%u].br_disp.disp_size: %d" % (i, op.br_disp.disp_size))
print()
# ## Test class Cs
def test_class():
address = 0x01000
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" % comment)
print("Code: %s " % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
last_address = 0
for insn in md.disasm(code, address):
last_address = insn.address + insn.size
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
print_insn_detail(insn)
print("0x%x:\n" % (last_address))
except CsError as e:
print("ERROR: %s" % e.__str__())
if __name__ == '__main__':
test_class()

View File

@ -1,73 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
from capstone import *
from capstone.mips import *
from xprint import to_hex, to_x
MIPS_CODE = b"\x0C\x10\x00\x97\x00\x00\x00\x00\x24\x02\x00\x0c\x8f\xa2\x00\x00\x34\x21\x34\x56"
MIPS_CODE2 = b"\x56\x34\x21\x34\xc2\x17\x01\x00"
MIPS_32R6M = b"\x00\x07\x00\x07\x00\x11\x93\x7c\x01\x8c\x8b\x7c\x00\xc7\x48\xd0"
MIPS_32R6 = b"\xec\x80\x00\x19\x7c\x43\x22\xa0"
MIPS_64SD = b"\x70\x00\xb2\xff"
all_tests = (
(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN, MIPS_CODE, "MIPS-32 (Big-endian)"),
(CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_LITTLE_ENDIAN, MIPS_CODE2, "MIPS-64-EL (Little-endian)"),
(CS_ARCH_MIPS, CS_MODE_MIPS32R6 + CS_MODE_MICRO + CS_MODE_BIG_ENDIAN, MIPS_32R6M, "MIPS-32R6 | Micro (Big-endian)"),
(CS_ARCH_MIPS, CS_MODE_MIPS32R6 + CS_MODE_BIG_ENDIAN, MIPS_32R6, "MIPS-32R6 (Big-endian)"),
(CS_ARCH_MIPS, CS_MODE_MIPS64 | CS_MODE_MIPS2 | CS_MODE_LITTLE_ENDIAN, MIPS_64SD, "MIPS-64-EL + Mips II (Little-endian)"),
(CS_ARCH_MIPS, CS_MODE_MIPS64 | CS_MODE_LITTLE_ENDIAN, MIPS_64SD, "MIPS-64-EL (Little-endian)"),
)
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = -1
for i in insn.operands:
c += 1
if i.type == MIPS_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
if i.type == MIPS_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm)))
if i.type == MIPS_OP_MEM:
print("\t\toperands[%u].type: MEM" % c)
if i.mem.base != 0:
print("\t\t\toperands[%u].mem.base: REG = %s" \
% (c, insn.reg_name(i.mem.base)))
if i.mem.disp != 0:
print("\t\t\toperands[%u].mem.disp: 0x%s" \
% (c, to_x(i.mem.disp)))
# ## Test class Cs
def test_class():
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" % comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
for insn in md.disasm(code, 0x1000):
print_insn_detail(insn)
print()
print("0x%x:\n" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" % e)
if __name__ == '__main__':
test_class()

View File

@ -1,94 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Sebastian Macke <Sebastian Macke>
from capstone import *
from capstone.mos65xx import *
from xprint import to_hex, to_x
M6502_CODE = b"\xa1\x12\xa5\x12\xa9\x12\xad\x34\x12\xb1\x12\xb5\x12\xb9\x34\x12\xbd\x34\x12\x0d\x34\x12\x00\x81\x87\x6c\x01\x00\x85\xFF\x10\x00\x19\x42\x42\x00\x49\x42"
M65C02_CODE = b"\x1a\x3a\x02\x12\x03\x5c\x34\x12"
MW65C02_CODE = b"\x07\x12\x27\x12\x47\x12\x67\x12\x87\x12\xa7\x12\xc7\x12\xe7\x12\x10\xfe\x0f\x12\xfd\x4f\x12\xfd\x8f\x12\xfd\xcf\x12\xfd"
M65816_CODE = b"\xa9\x34\x12\xad\x34\x12\xbd\x34\x12\xb9\x34\x12\xaf\x56\x34\x12\xbf\x56\x34\x12\xa5\x12\xb5\x12\xb2\x12\xa1\x12\xb1\x12\xa7\x12\xb7\x12\xa3\x12\xb3\x12\xc2\x00\xe2\x00\x54\x34\x12\x44\x34\x12\x02\x12"
all_tests = (
(CS_ARCH_MOS65XX, CS_MODE_MOS65XX_6502, M6502_CODE, "MOS65XX_6502"),
(CS_ARCH_MOS65XX, CS_MODE_MOS65XX_65C02, M65C02_CODE, "MOS65XX_65C02"),
(CS_ARCH_MOS65XX, CS_MODE_MOS65XX_W65C02, MW65C02_CODE, "MOS65XX_W65C02"),
(CS_ARCH_MOS65XX, CS_MODE_MOS65XX_65816_LONG_MX, M65816_CODE, "MOS65XX_65816 (long m/x)"),
)
address_modes=[
"No address mode",
"implied",
"accumulator",
"immediate value",
"relative",
"interrupt signature",
"block move",
"zero page",
"zero page indexed with x",
"zero page indexed with y",
"relative bit branch",
"zero page indirect",
"zero page indexed with x indirect",
"zero page indirect indexed with y",
"zero page indirect long",
"zero page indirect long indexed with y",
"absolute",
"absolute indexed with x",
"absolute indexed with y",
"absolute indirect",
"absolute indexed with x indirect",
"absolute indirect long",
"absolute long",
"absolute long indexed with x",
"stack relative",
"stack relative indirect indexed with y",
]
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
print("\taddress mode: %s" % (address_modes[insn.am]))
print("\tmodifies flags: %s" % ('true' if insn.modifies_flags != 0 else 'false'))
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = -1
for i in insn.operands:
c += 1
if i.type == MOS65XX_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
if i.type == MOS65XX_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm)))
if i.type == MOS65XX_OP_MEM:
print("\t\toperands[%u].type: MEM = 0x%s" % (c, to_x(i.mem)))
# ## Test class Cs
def test_class():
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" % comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
md.syntax = CS_OPT_SYNTAX_MOTOROLA
for insn in md.disasm(code, 0x1000):
print_insn_detail(insn)
print()
print("0x%x:\n" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" % e)
if __name__ == '__main__':
test_class()

View File

@ -1,93 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
from capstone import *
from capstone.ppc import *
from xprint import to_hex, to_x, to_x_32
PPC_CODE = b"\x43\x20\x0c\x07\x41\x56\xff\x17\x80\x20\x00\x00\x80\x3f\x00\x00\x10\x43\x23\x0e\xd0\x44\x00\x80\x4c\x43\x22\x02\x2d\x03\x00\x80\x7c\x43\x20\x14\x7c\x43\x20\x93\x4f\x20\x00\x21\x4c\xc8\x00\x21\x40\x82\x00\x14"
PPC_CODE2 = b"\x10\x60\x2a\x10\x10\x64\x28\x88\x7c\x4a\x5d\x0f"
PPC_CODE3 = b"\x10\x00\x1f\xec\xe0\x6d\x80\x04\xe4\x6d\x80\x04\x10\x60\x1c\x4c\x10\x60\x1c\x0c\xf0\x6d\x80\x04\xf4\x6d\x80\x04\x10\x60\x1c\x4e\x10\x60\x1c\x0e\x10\x60\x1a\x10\x10\x60\x1a\x11\x10\x63\x20\x2a\x10\x63\x20\x2b\x10\x83\x20\x40\x10\x83\x20\xC0\x10\x83\x20\x00\x10\x83\x20\x80\x10\x63\x20\x24\x10\x63\x20\x25\x10\x63\x29\x3a\x10\x63\x29\x3b\x10\x63\x29\x1c\x10\x63\x29\x1d\x10\x63\x29\x1e\x10\x63\x29\x1f\x10\x63\x24\x20\x10\x63\x24\x21\x10\x63\x24\x60\x10\x63\x24\x61\x10\x63\x24\xA0\x10\x63\x24\xA1\x10\x63\x24\xE0\x10\x63\x24\xE1\x10\x60\x20\x90\x10\x60\x20\x91\x10\x63\x29\x38\x10\x63\x29\x39\x10\x63\x01\x32\x10\x63\x01\x33\x10\x63\x01\x18\x10\x63\x01\x19\x10\x63\x01\x1A\x10\x63\x01\x1B\x10\x60\x19\x10\x10\x60\x19\x11\x10\x60\x18\x50\x10\x60\x18\x51\x10\x63\x29\x3e\x10\x63\x29\x3f\x10\x63\x29\x3c\x10\x63\x29\x3d\x10\x60\x18\x30\x10\x60\x18\x31\x10\x60\x18\x34\x10\x60\x18\x35\x10\x63\x29\x2e\x10\x63\x29\x2f\x10\x63\x20\x28\x10\x63\x20\x29\x10\x63\x29\x14\x10\x63\x29\x15\x10\x63\x29\x16\x10\x63\x29\x17"
all_tests = (
(CS_ARCH_PPC, CS_MODE_BIG_ENDIAN, PPC_CODE, "PPC-64"),
(CS_ARCH_PPC, CS_MODE_BIG_ENDIAN + CS_MODE_QPX, PPC_CODE2, "PPC-64 + QPX"),
(CS_ARCH_PPC, CS_MODE_BIG_ENDIAN + CS_MODE_32 + CS_MODE_PS, PPC_CODE3, "PPC + PS"),
)
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = 0
for i in insn.operands:
if i.type == PPC_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
if i.type == PPC_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm)))
if i.type == PPC_OP_MEM:
print("\t\toperands[%u].type: MEM" % c)
if i.mem.base != PPC_REG_INVALID:
print("\t\t\toperands[%u].mem.base: REG = %s" \
% (c, insn.reg_name(i.mem.base)))
if i.mem.offset != 0:
print("\t\t\toperands[%u].mem.offset: REG = %s" \
% (c, insn.reg_name(i.mem.offset)))
if i.mem.disp != 0:
print("\t\t\toperands[%u].mem.disp: 0x%s" \
% (c, to_x_32(i.mem.disp)))
if i.access == CS_AC_READ:
print("\t\toperands[%u].access: READ" % (c))
elif i.access == CS_AC_WRITE:
print("\t\toperands[%u].access: WRITE" % (c))
elif i.access == CS_AC_READ | CS_AC_WRITE:
print("\t\toperands[%u].access: READ | WRITE" % (c))
c += 1
if insn.bc.pred_cr != PPC_PRED_INVALID or \
insn.bc.pred_ctr != PPC_PRED_INVALID:
print("\tBranch:")
print("\t\tbi: %u" % insn.bc.bi)
print("\t\tbo: %u" % insn.bc.bo)
if insn.bc.bh != PPC_BH_INVALID:
print("\t\tbh: %u" %insn.bc.bh)
if insn.bc.pred_cr != PPC_PRED_INVALID:
print("\t\tcrX: %s" % insn.reg_name(insn.bc.crX))
print("\t\tpred CR-bit: %u" % insn.bc.pred_cr)
if insn.bc.pred_ctr != PPC_PRED_INVALID:
print("\t\tpred CTR: %u" % insn.bc.pred_ctr)
if insn.bc.hint != PPC_BR_NOT_GIVEN:
print("\t\thint: %u" % insn.bc.hint)
if insn.update_cr0:
print("\tUpdate-CR0: True")
# ## Test class Cs
def test_class():
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" % comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
for insn in md.disasm(code, 0x1000):
print_insn_detail(insn)
print ()
print("0x%x:\n" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" % e)
if __name__ == '__main__':
test_class()

View File

@ -1,79 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
from capstone import *
from capstone.riscv import *
from xprint import to_x, to_hex
RISCV_CODE32 = b"\x37\x34\x00\x00\x97\x82\x00\x00\xef\x00\x80\x00\xef\xf0\x1f\xff\xe7\x00\x45\x00\xe7\x00\xc0\xff\x63\x05\x41\x00\xe3\x9d\x61\xfe\x63\xca\x93\x00\x63\x53\xb5\x00\x63\x65\xd6\x00\x63\x76\xf7\x00\x03\x88\x18\x00\x03\x99\x49\x00\x03\xaa\x6a\x00\x03\xcb\x2b\x01\x03\xdc\x8c\x01\x23\x86\xad\x03\x23\x9a\xce\x03\x23\x8f\xef\x01\x93\x00\xe0\x00\x13\xa1\x01\x01\x13\xb2\x02\x7d\x13\xc3\x03\xdd\x13\xe4\xc4\x12\x13\xf5\x85\x0c\x13\x96\xe6\x01\x13\xd7\x97\x01\x13\xd8\xf8\x40\x33\x89\x49\x01\xb3\x0a\x7b\x41\x33\xac\xac\x01\xb3\x3d\xde\x01\x33\xd2\x62\x40\xb3\x43\x94\x00\x33\xe5\xc5\x00\xb3\x76\xf7\x00\xb3\x54\x39\x01\xb3\x50\x31\x00\x33\x9f\x0f\x00\x73\x15\x04\xb0\xf3\x56\x00\x10\x33\x05\x7b\x03\xb3\x45\x9c\x03\x33\x66\xbd\x03\x2f\xa4\x02\x10\xaf\x23\x65\x18\x2f\x27\x2f\x01\x43\xf0\x20\x18\xd3\x72\x73\x00\x53\xf4\x04\x58\x53\x85\xc5\x28\x53\x2e\xde\xa1\xd3\x84\x05\xf0\x53\x06\x05\xe0\x53\x75\x00\xc0\xd3\xf0\x05\xd0\xd3\x15\x08\xe0\x87\xaa\x75\x00\x27\x27\x66\x01\x43\xf0\x20\x1a\xd3\x72\x73\x02\x53\xf4\x04\x5a\x53\x85\xc5\x2a\x53\x2e\xde\xa3"
RISCV_CODE64 = b"\x13\x04\xa8\x7a\xbb\x07\x9c\x02\xbb\x40\x5d\x02\x3b\x63\xb7\x03\x2f\xb4\x02\x10\xaf\x33\x65\x18\x2f\x37\x2f\x01\x53\x75\x20\xc0\xd3\xf0\x25\xd0\xd3\x84\x05\xf2\x53\x06\x05\xe2\x53\x75\x00\xc2\xd3\x80\x05\xd2\xd3\x15\x08\xe2\x87\xba\x75\x00\x27\x37\x66\x01"
RISCV_CODEC = b"\xe8\x1f\x7d\x61\x80\x25\x00\x46\x88\xa2\x04\xcb\x55\x13\xf2\x93\x5d\x45\x19\x80\x15\x68\x2a\xa4\x62\x24\xa6\xff\x2a\x65\x76\x86\x65\xdd\x01\x00\xfd\xaf\x82\x82\x11\x20\x82\x94"
all_tests = (
(CS_ARCH_RISCV, CS_MODE_RISCV32, RISCV_CODE32, "riscv32"),
(CS_ARCH_RISCV, CS_MODE_RISCV64, RISCV_CODE64, "riscv64"),
(CS_ARCH_RISCV, CS_MODE_RISCVC, RISCV_CODEC, "riscvc"),
)
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = 0
for i in insn.operands:
if i.type == RISCV_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
if i.type == RISCV_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm)))
if i.type == RISCV_OP_MEM:
print("\t\toperands[%u].type: MEM" % c)
if i.mem.base != 0:
print("\t\t\toperands[%u].mem.base: REG = %s" \
% (c, insn.reg_name(i.mem.base)))
if i.mem.disp != 0:
print("\t\t\toperands[%u].mem.disp: 0x%s" \
% (c, to_x(i.mem.disp)))
if i.access == CS_AC_READ:
print("\t\toperands[%u].access: READ" % (c))
elif i.access == CS_AC_WRITE:
print("\t\toperands[%u].access: WRITE" % (c))
elif i.access == CS_AC_READ | CS_AC_WRITE:
print("\t\toperands[%u].access: READ | WRITE" % (c))
c += 1
if len(insn.groups) > 0:
print('\tgroups: ' + ' '.join(map(lambda g: insn.group_name(g), insn.groups)))
# ## Test class Cs
def test_class():
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" %comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
for insn in md.disasm(code, 0x1000):
print_insn_detail(insn)
print ()
print("0x%x:\n" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" %e)
if __name__ == '__main__':
test_class()

View File

@ -1,96 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Peace-Maker <peacemakerctf@gmail.com>
from capstone import *
from capstone.sh import *
from xprint import to_x, to_hex
SH4A_CODE = b"\x0c\x31\x10\x20\x22\x21\x36\x64\x46\x25\x12\x12\x1c\x02\x08\xc1\x05\xc7\x0c\x71\x1f\x02\x22\xcf\x06\x89\x23\x00\x2b\x41\x0b\x00\x0e\x40\x32\x00\x0a\xf1\x09\x00"
SH2A_CODE = b"\x32\x11\x92\x00\x32\x49\x31\x00"
all_tests = (
(CS_ARCH_SH, CS_MODE_SH4A | CS_MODE_SHFPU, SH4A_CODE, "SH_SH4A"),
(CS_ARCH_SH, CS_MODE_SH2A | CS_MODE_SHFPU | CS_MODE_BIG_ENDIAN, SH2A_CODE, "SH_SH2A"),
)
reg_address_msg = [
"Register indirect",
"Register indirect with predecrement",
"Register indirect with postincrement",
]
def print_read_write_regs(insn):
if len(insn.regs_read) > 0:
print("\tRegisters read: %s" % " ".join(insn.reg_name(m) for m in insn.regs_read))
if len(insn.regs_write) > 0:
print("\tRegisters modified: %s" % " ".join(insn.reg_name(m) for m in insn.regs_write))
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = 0
for i in insn.operands:
if i.type == SH_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
elif i.type == SH_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm)))
elif i.type == SH_OP_MEM:
print("\t\toperands[%u].type: MEM " % c)
if i.mem.address in [SH_OP_MEM_REG_IND, SH_OP_MEM_REG_POST, SH_OP_MEM_REG_PRE]:
print("%s REG %s" % (reg_address_msg[i.mem.address - SH_OP_MEM_REG_IND], insn.reg_name(i.mem.reg)))
elif i.mem.address == SH_OP_MEM_REG_DISP:
print("Register indirect with displacement REG %s, DISP %d" % (insn.reg_name(i.mem.reg), i.mem.disp))
elif i.mem.address == SH_OP_MEM_REG_R0:
print("R0 indexed")
elif i.mem.address == SH_OP_MEM_GBR_DISP:
print("GBR base with displacement DISP %d" % i.mem.disp)
elif i.mem.address == SH_OP_MEM_GBR_R0:
print("GBR base with R0 indexed")
elif i.mem.address == SH_OP_MEM_PCR:
print("PC relative Address=0x%08x" % i.mem.disp)
elif i.mem.address == SH_OP_MEM_TBR_DISP:
print("TBR base with displacement DISP %d", i.mem.disp)
else:
print("Unknown addressing mode %x" % i.mem.address)
if i.sh_size != 0:
print("\t\t\tsh_size: %u" % i.sh_size)
c += 1
print_read_write_regs(insn)
if len(insn.groups) > 0:
print('\tgroups: ' + ' '.join(map(lambda g: insn.group_name(g), insn.groups)))
# ## Test class Cs
def test_class():
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" %comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
for insn in md.disasm(code, 0x80000000):
print_insn_detail(insn)
print()
print("0x%x:" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" %e)
if __name__ == '__main__':
test_class()

View File

@ -1,74 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
from capstone import *
from capstone.sparc import *
from xprint import to_hex, to_x_32
SPARC_CODE = b"\x80\xa0\x40\x02\x85\xc2\x60\x08\x85\xe8\x20\x01\x81\xe8\x00\x00\x90\x10\x20\x01\xd5\xf6\x10\x16\x21\x00\x00\x0a\x86\x00\x40\x02\x01\x00\x00\x00\x12\xbf\xff\xff\x10\xbf\xff\xff\xa0\x02\x00\x09\x0d\xbf\xff\xff\xd4\x20\x60\x00\xd4\x4e\x00\x16\x2a\xc2\x80\x03"
SPARCV9_CODE = b"\x81\xa8\x0a\x24\x89\xa0\x10\x20\x89\xa0\x1a\x60\x89\xa0\x00\xe0"
all_tests = (
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, SPARC_CODE, "Sparc"),
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN+CS_MODE_V9, SPARCV9_CODE, "SparcV9"),
)
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = 0
for i in insn.operands:
if i.type == SPARC_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
if i.type == SPARC_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x_32(i.imm)))
if i.type == SPARC_OP_MEM:
print("\t\toperands[%u].type: MEM" % c)
if i.mem.base != 0:
print("\t\t\toperands[%u].mem.base: REG = %s" \
% (c, insn.reg_name(i.mem.base)))
if i.mem.index != 0:
print("\t\t\toperands[%u].mem.index: REG = %s" \
% (c, insn.reg_name(i.mem.index)))
if i.mem.disp != 0:
print("\t\t\toperands[%u].mem.disp: 0x%s" \
% (c, to_x_32(i.mem.disp)))
c += 1
if insn.cc:
print("\tCode condition: %u" % insn.cc)
if insn.hint:
print("\tHint code: %u" % insn.hint)
# ## Test class Cs
def test_class():
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" % comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
for insn in md.disasm(code, 0x1000):
print_insn_detail(insn)
print ()
print("0x%x:\n" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" %e)
if __name__ == '__main__':
test_class()

View File

@ -1,76 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
from capstone import *
from capstone.systemz import *
from xprint import to_x, to_hex
SYSZ_CODE = b"\xed\x00\x00\x00\x00\x1a\x5a\x0f\x1f\xff\xc2\x09\x80\x00\x00\x00\x07\xf7\xeb\x2a\xff\xff\x7f\x57\xe3\x01\xff\xff\x7f\x57\xeb\x00\xf0\x00\x00\x24\xb2\x4f\x00\x78\xec\x18\x00\x00\xc1\x7f"
all_tests = (
(CS_ARCH_SYSZ, 0, SYSZ_CODE, "SystemZ"),
)
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = 0
for i in insn.operands:
if i.type == SYSZ_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
if i.type == SYSZ_OP_ACREG:
print("\t\toperands[%u].type: ACREG = %u" % (c, i.reg))
if i.type == SYSZ_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm)))
if i.type == SYSZ_OP_MEM:
print("\t\toperands[%u].type: MEM" % c)
if i.mem.base != 0:
print("\t\t\toperands[%u].mem.base: REG = %s" \
% (c, insn.reg_name(i.mem.base)))
if i.mem.index != 0:
print("\t\t\toperands[%u].mem.index: REG = %s" \
% (c, insn.reg_name(i.mem.index)))
if i.mem.length != 0:
print("\t\t\toperands[%u].mem.length: 0x%s" \
% (c, to_x(i.mem.length)))
if i.mem.disp != 0:
print("\t\t\toperands[%u].mem.disp: 0x%s" \
% (c, to_x(i.mem.disp)))
c += 1
if insn.cc:
print("\tConditional code: %u" % insn.cc)
# ## Test class Cs
def test_class():
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" %comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
for insn in md.disasm(code, 0x1000):
print_insn_detail(insn)
print ()
print("0x%x:\n" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" %e)
if __name__ == '__main__':
test_class()

View File

@ -1,113 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Fotis Loukos <me@fotisl.com>
from capstone import *
from capstone.tms320c64x import *
from xprint import to_x, to_hex, to_x_32
TMS320C64X_CODE = b"\x01\xac\x88\x40\x81\xac\x88\x43\x00\x00\x00\x00\x02\x90\x32\x96\x02\x80\x46\x9e\x05\x3c\x83\xe6\x0b\x0c\x8b\x24"
all_tests = (
(CS_ARCH_TMS320C64X, 0, TMS320C64X_CODE, "TMS320C64x"),
)
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = 0
for i in insn.operands:
if i.type == TMS320C64X_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
if i.type == TMS320C64X_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm)))
if i.type == TMS320C64X_OP_MEM:
print("\t\toperands[%u].type: MEM" % c)
if i.mem.base != 0:
print("\t\t\toperands[%u].mem.base: REG = %s" \
% (c, insn.reg_name(i.mem.base)))
if i.mem.disptype == TMS320C64X_MEM_DISP_INVALID:
print("\t\t\toperands[%u].mem.disptype: Invalid" % (c))
print("\t\t\toperands[%u].mem.disp: 0x%s" \
% (c, to_x(i.mem.disp)))
if i.mem.disptype == TMS320C64X_MEM_DISP_CONSTANT:
print("\t\t\toperands[%u].mem.disptype: Constant" % (c))
print("\t\t\toperands[%u].mem.disp: 0x%s" \
% (c, to_x(i.mem.disp)))
if i.mem.disptype == TMS320C64X_MEM_DISP_REGISTER:
print("\t\t\toperands[%u].mem.disptype: Register" % (c))
print("\t\t\toperands[%u].mem.disp: %s" \
% (c, insn.reg_name(i.mem.disp)))
print("\t\t\toperands[%u].mem.unit: %u" % (c, i.mem.unit))
if i.mem.direction == TMS320C64X_MEM_DIR_INVALID:
print("\t\t\toperands[%u].mem.direction: Invalid" % (c))
if i.mem.direction == TMS320C64X_MEM_DIR_FW:
print("\t\t\toperands[%u].mem.direction: Forward" % (c))
if i.mem.direction == TMS320C64X_MEM_DIR_BW:
print("\t\t\toperands[%u].mem.direction: Backward" % (c))
if i.mem.modify == TMS320C64X_MEM_MOD_INVALID:
print("\t\t\toperands[%u].mem.modify: Invalid" % (c))
if i.mem.modify == TMS320C64X_MEM_MOD_NO:
print("\t\t\toperands[%u].mem.modify: No" % (c))
if i.mem.modify == TMS320C64X_MEM_MOD_PRE:
print("\t\t\toperands[%u].mem.modify: Pre" % (c))
if i.mem.modify == TMS320C64X_MEM_MOD_POST:
print("\t\t\toperands[%u].mem.modify: Post" % (c))
print("\t\t\toperands[%u].mem.scaled: %u" % (c, i.mem.scaled))
if i.type == TMS320C64X_OP_REGPAIR:
print("\t\toperands[%u].type: REGPAIR = %s:%s" % (c, insn.reg_name(i.reg + 1), insn.reg_name(i.reg)))
c += 1
print("\tFunctional unit: ", end="")
if insn.funit.unit == TMS320C64X_FUNIT_D:
print("D%u" % insn.funit.side)
elif insn.funit.unit == TMS320C64X_FUNIT_L:
print("L%u" % insn.funit.side)
elif insn.funit.unit == TMS320C64X_FUNIT_M:
print("M%u" % insn.funit.side)
elif insn.funit.unit == TMS320C64X_FUNIT_S:
print("S%u" % insn.funit.side)
elif insn.funit.unit == TMS320C64X_FUNIT_NO:
print("No Functional Unit")
else:
print("Unknown (Unit %u, Side %u)" % (insn.funit.unit, insn.funit.side))
if insn.funit.crosspath == 1:
print("\tCrosspath: 1")
if insn.condition.reg != TMS320C64X_REG_INVALID:
print("\tCondition: [%c%s]" % ("!" if insn.condition.zero == 1 else " ", insn.reg_name(insn.condition.reg)))
print("\tParallel: %s" % ("true" if insn.parallel == 1 else "false"))
print()
# ## Test class Cs
def test_class():
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" %comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
for insn in md.disasm(code, 0x1000):
print_insn_detail(insn)
print("0x%x:\n" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" %e)
if __name__ == '__main__':
test_class()

View File

@ -1,63 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
from capstone import *
from capstone.tricore import *
from xprint import to_hex, to_x
TRICORE_CODE = b"\x09\xcf\xbc\xf5\x09\xf4\x01\x00\x89\xfb\x8f\x74\x89\xfe\x48\x01\x29\x00\x19\x25\x29\x03\x09\xf4\x85\xf9\x68\x0f\x16\x01"
all_tests = (
(CS_ARCH_TRICORE, CS_MODE_TRICORE_162, TRICORE_CODE, "TriCore"),
)
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = 0
for i in insn.operands:
if i.type == TRICORE_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
if i.type == TRICORE_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm)))
if i.type == TRICORE_OP_MEM:
print("\t\toperands[%u].type: MEM" % c)
if i.mem.base != 0:
print("\t\t\toperands[%u].mem.base: REG = %s" \
% (c, insn.reg_name(i.mem.base)))
if i.mem.disp != 0:
print("\t\t\toperands[%u].mem.disp: 0x%s" \
% (c, to_x(i.mem.disp)))
c += 1
print()
# ## Test class Cs
def test_class():
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" % comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
for insn in md.disasm(code, 0x1000):
print_insn_detail(insn)
print("0x%x:" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" % e)
if __name__ == '__main__':
test_class()

View File

@ -1,80 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Peace-Maker <peacemakerctf@gmail.com>
from capstone import *
from capstone.wasm import *
from xprint import to_hex
WASM_CODE = b"\x20\x00\x20\x01\x41\x20\x10\xc9\x01\x45\x0b"
all_tests = (
(CS_ARCH_WASM, 0, WASM_CODE, "WASM"),
)
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.groups) > 0:
print("\tGroups: ", end="")
for group in insn.groups:
print("%s " % insn.group_name(group), end="")
print()
if len(insn.operands) > 0:
print("\tOperand count: %u" % len(insn.operands))
c = 0
for i in insn.operands:
if i.type == WASM_OP_INT7:
print("\t\tOperand[%u] type: int7" % c)
print("\t\tOperand[%u] value: %d" % (c, i.int7))
elif i.type == WASM_OP_VARUINT32:
print("\t\tOperand[%u] type: varuint32" % c)
print("\t\tOperand[%u] value: %#x" % (c, i.varuint32))
elif i.type == WASM_OP_VARUINT64:
print("\t\tOperand[%u] type: varuint64" % c)
print("\t\tOperand[%u] value: %#x" % (c, i.varuint64))
elif i.type == WASM_OP_UINT32:
print("\t\tOperand[%u] type: uint32" % c)
print("\t\tOperand[%u] value: %#x" % (c, i.uint32))
elif i.type == WASM_OP_UINT64:
print("\t\tOperand[%u] type: uint64" % c)
print("\t\tOperand[%u] value: %#x" % (c, i.uint64))
elif i.type == WASM_OP_IMM:
print("\t\tOperand[%u] type: imm" % c)
print("\t\tOperand[%u] value: %#x %#x" % (c, i.immediate[0], i.immediate[1]))
elif i.type == WASM_OP_BRTABLE:
print("\t\tOperand[%u] type: brtable" % c)
print("\t\tOperand[%u] value: length=%#x, address=%#x, default_target=%#x" % (c, i.brtable.length, i.brtable.address, i.brtable.default_target))
print("\t\tOperand[%u] size: %u" % (c, i.size))
c += 1
# ## Test class Cs
def test_class():
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" % comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
for insn in md.disasm(code, 0xffff):
print_insn_detail(insn)
print()
print("0x%x:\n" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" % e)
if __name__ == '__main__':
test_class()

View File

@ -1,344 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
from capstone import *
from capstone.x86 import *
from xprint import to_hex, to_x
X86_CODE64 = b"\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\xea\xbe\xad\xde\xff\x25\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff"
X86_CODE16 = b"\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00\x05\x23\x01\x00\x00\x36\x8b\x84\x91\x23\x01\x00\x00\x41\x8d\x84\x39\x89\x67\x00\x00\x8d\x87\x89\x67\x00\x00\xb4\xc6\x66\xe9\xb8\x00\x00\x00\x67\xff\xa0\x23\x01\x00\x00\x66\xe8\xcb\x00\x00\x00\x74\xfc"
X86_CODE32 = b"\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00\x05\x23\x01\x00\x00\x36\x8b\x84\x91\x23\x01\x00\x00\x41\x8d\x84\x39\x89\x67\x00\x00\x8d\x87\x89\x67\x00\x00\xb4\xc6\xe9\xea\xbe\xad\xde\xff\xa0\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff"
all_tests = (
(CS_ARCH_X86, CS_MODE_16, X86_CODE16, "X86 16bit (Intel syntax)", None),
(CS_ARCH_X86, CS_MODE_32, X86_CODE32, "X86 32 (AT&T syntax)", CS_OPT_SYNTAX_ATT),
(CS_ARCH_X86, CS_MODE_32, X86_CODE32, "X86 32 (Intel syntax)", None),
(CS_ARCH_X86, CS_MODE_64, X86_CODE64, "X86 64 (Intel syntax)", None),
)
def get_eflag_name(eflag):
if eflag == X86_EFLAGS_UNDEFINED_OF:
return "UNDEF_OF"
elif eflag == X86_EFLAGS_UNDEFINED_SF:
return "UNDEF_SF"
elif eflag == X86_EFLAGS_UNDEFINED_ZF:
return "UNDEF_ZF"
elif eflag == X86_EFLAGS_MODIFY_AF:
return "MOD_AF"
elif eflag == X86_EFLAGS_UNDEFINED_PF:
return "UNDEF_PF"
elif eflag == X86_EFLAGS_MODIFY_CF:
return "MOD_CF"
elif eflag == X86_EFLAGS_MODIFY_SF:
return "MOD_SF"
elif eflag == X86_EFLAGS_MODIFY_ZF:
return "MOD_ZF"
elif eflag == X86_EFLAGS_UNDEFINED_AF:
return "UNDEF_AF"
elif eflag == X86_EFLAGS_MODIFY_PF:
return "MOD_PF"
elif eflag == X86_EFLAGS_UNDEFINED_CF:
return "UNDEF_CF"
elif eflag == X86_EFLAGS_MODIFY_OF:
return "MOD_OF"
elif eflag == X86_EFLAGS_RESET_OF:
return "RESET_OF"
elif eflag == X86_EFLAGS_RESET_CF:
return "RESET_CF"
elif eflag == X86_EFLAGS_RESET_DF:
return "RESET_DF"
elif eflag == X86_EFLAGS_RESET_IF:
return "RESET_IF"
elif eflag == X86_EFLAGS_TEST_OF:
return "TEST_OF"
elif eflag == X86_EFLAGS_TEST_SF:
return "TEST_SF"
elif eflag == X86_EFLAGS_TEST_ZF:
return "TEST_ZF"
elif eflag == X86_EFLAGS_TEST_PF:
return "TEST_PF"
elif eflag == X86_EFLAGS_TEST_CF:
return "TEST_CF"
elif eflag == X86_EFLAGS_RESET_SF:
return "RESET_SF"
elif eflag == X86_EFLAGS_RESET_AF:
return "RESET_AF"
elif eflag == X86_EFLAGS_RESET_TF:
return "RESET_TF"
elif eflag == X86_EFLAGS_RESET_NT:
return "RESET_NT"
elif eflag == X86_EFLAGS_PRIOR_OF:
return "PRIOR_OF"
elif eflag == X86_EFLAGS_PRIOR_SF:
return "PRIOR_SF"
elif eflag == X86_EFLAGS_PRIOR_ZF:
return "PRIOR_ZF"
elif eflag == X86_EFLAGS_PRIOR_AF:
return "PRIOR_AF"
elif eflag == X86_EFLAGS_PRIOR_PF:
return "PRIOR_PF"
elif eflag == X86_EFLAGS_PRIOR_CF:
return "PRIOR_CF"
elif eflag == X86_EFLAGS_PRIOR_TF:
return "PRIOR_TF"
elif eflag == X86_EFLAGS_PRIOR_IF:
return "PRIOR_IF"
elif eflag == X86_EFLAGS_PRIOR_DF:
return "PRIOR_DF"
elif eflag == X86_EFLAGS_TEST_NT:
return "TEST_NT"
elif eflag == X86_EFLAGS_TEST_DF:
return "TEST_DF"
elif eflag == X86_EFLAGS_RESET_PF:
return "RESET_PF"
elif eflag == X86_EFLAGS_PRIOR_NT:
return "PRIOR_NT"
elif eflag == X86_EFLAGS_MODIFY_TF:
return "MOD_TF"
elif eflag == X86_EFLAGS_MODIFY_IF:
return "MOD_IF"
elif eflag == X86_EFLAGS_MODIFY_DF:
return "MOD_DF"
elif eflag == X86_EFLAGS_MODIFY_NT:
return "MOD_NT"
elif eflag == X86_EFLAGS_MODIFY_RF:
return "MOD_RF"
elif eflag == X86_EFLAGS_SET_CF:
return "SET_CF"
elif eflag == X86_EFLAGS_SET_DF:
return "SET_DF"
elif eflag == X86_EFLAGS_SET_IF:
return "SET_IF"
else:
return None
def get_fpu_flag_name(flag):
if flag == X86_FPU_FLAGS_MODIFY_C0:
return "MOD_C0"
elif flag == X86_FPU_FLAGS_MODIFY_C1:
return "MOD_C1"
elif flag == X86_FPU_FLAGS_MODIFY_C2:
return "MOD_C2"
elif flag == X86_FPU_FLAGS_MODIFY_C3:
return "MOD_C3"
elif flag == X86_FPU_FLAGS_RESET_C0:
return "RESET_C0"
elif flag == X86_FPU_FLAGS_RESET_C1:
return "RESET_C1"
elif flag == X86_FPU_FLAGS_RESET_C2:
return "RESET_C2"
elif flag == X86_FPU_FLAGS_RESET_C3:
return "RESET_C3"
elif flag == X86_FPU_FLAGS_SET_C0:
return "SET_C0"
elif flag == X86_FPU_FLAGS_SET_C1:
return "SET_C1"
elif flag == X86_FPU_FLAGS_SET_C2:
return "SET_C2"
elif flag == X86_FPU_FLAGS_SET_C3:
return "SET_C3"
elif flag == X86_FPU_FLAGS_UNDEFINED_C0:
return "UNDEF_C0"
elif flag == X86_FPU_FLAGS_UNDEFINED_C1:
return "UNDEF_C1"
elif flag == X86_FPU_FLAGS_UNDEFINED_C2:
return "UNDEF_C2"
elif flag == X86_FPU_FLAGS_UNDEFINED_C3:
return "UNDEF_C3"
elif flag == X86_FPU_FLAGS_TEST_C0:
return "TEST_C0"
elif flag == X86_FPU_FLAGS_TEST_C1:
return "TEST_C1"
elif flag == X86_FPU_FLAGS_TEST_C2:
return "TEST_C2"
elif flag == X86_FPU_FLAGS_TEST_C3:
return "TEST_C3"
else:
return None
def print_insn_detail(mode, insn):
def print_string_hex(comment, str):
print(comment, end=' '),
for c in str:
print("0x%02x " % c, end=''),
print()
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
# print instruction prefix
print_string_hex("\tPrefix:", insn.prefix)
# print instruction's opcode
print_string_hex("\tOpcode:", insn.opcode)
# print operand's REX prefix (non-zero value is relevant for x86_64 instructions)
print("\trex: 0x%x" % (insn.rex))
# print operand's address size
print("\taddr_size: %u" % (insn.addr_size))
# print modRM byte
print("\tmodrm: 0x%x" % (insn.modrm))
# print modRM offset
if insn.encoding.modrm_offset != 0:
print("\tmodrm_offset: 0x%x" % (insn.encoding.modrm_offset))
# print displacement value
print("\tdisp: 0x%s" % to_x(insn.disp))
# print displacement offset (offset into instruction bytes)
if insn.encoding.disp_offset != 0:
print("\tdisp_offset: 0x%x" % (insn.encoding.disp_offset))
# print displacement size
if insn.encoding.disp_size != 0:
print("\tdisp_size: 0x%x" % (insn.encoding.disp_size))
# SIB is not available in 16-bit mode
if (mode & CS_MODE_16 == 0):
# print SIB byte
print("\tsib: 0x%x" % (insn.sib))
if (insn.sib):
if insn.sib_base != 0:
print("\t\tsib_base: %s" % (insn.reg_name(insn.sib_base)))
if insn.sib_index != 0:
print("\t\tsib_index: %s" % (insn.reg_name(insn.sib_index)))
if insn.sib_scale != 0:
print("\t\tsib_scale: %d" % (insn.sib_scale))
# XOP CC type
if insn.xop_cc != X86_XOP_CC_INVALID:
print("\txop_cc: %u" % (insn.xop_cc))
# SSE CC type
if insn.sse_cc != X86_SSE_CC_INVALID:
print("\tsse_cc: %u" % (insn.sse_cc))
# AVX CC type
if insn.avx_cc != X86_AVX_CC_INVALID:
print("\tavx_cc: %u" % (insn.avx_cc))
# AVX Suppress All Exception
if insn.avx_sae:
print("\tavx_sae: TRUE")
# AVX Rounding Mode type
if insn.avx_rm != X86_AVX_RM_INVALID:
print("\tavx_rm: %u" % (insn.avx_rm))
count = insn.op_count(X86_OP_IMM)
if count > 0:
print("\timm_count: %u" % count)
for i in range(count):
op = insn.op_find(X86_OP_IMM, i + 1)
print("\t\timms[%u]: 0x%s" % (i + 1, to_x(op.imm)))
if insn.encoding.imm_offset != 0:
print("\timm_offset: 0x%x" % (insn.encoding.imm_offset))
if insn.encoding.imm_size != 0:
print("\timm_size: 0x%x" % (insn.encoding.imm_size))
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = -1
for i in insn.operands:
c += 1
if i.type == X86_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
if i.type == X86_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm)))
if i.type == X86_OP_MEM:
print("\t\toperands[%u].type: MEM" % c)
if i.mem.segment != 0:
print("\t\t\toperands[%u].mem.segment: REG = %s" % (c, insn.reg_name(i.mem.segment)))
if i.mem.base != 0:
print("\t\t\toperands[%u].mem.base: REG = %s" % (c, insn.reg_name(i.mem.base)))
if i.mem.index != 0:
print("\t\t\toperands[%u].mem.index: REG = %s" % (c, insn.reg_name(i.mem.index)))
if i.mem.scale != 1:
print("\t\t\toperands[%u].mem.scale: %u" % (c, i.mem.scale))
if i.mem.disp != 0:
print("\t\t\toperands[%u].mem.disp: 0x%s" % (c, to_x(i.mem.disp)))
# AVX broadcast type
if i.avx_bcast != X86_AVX_BCAST_INVALID:
print("\t\toperands[%u].avx_bcast: %u" % (c, i.avx_bcast))
# AVX zero opmask {z}
if i.avx_zero_opmask:
print("\t\toperands[%u].avx_zero_opmask: TRUE" % (c))
print("\t\toperands[%u].size: %u" % (c, i.size))
if i.access == CS_AC_READ:
print("\t\toperands[%u].access: READ" % (c))
elif i.access == CS_AC_WRITE:
print("\t\toperands[%u].access: WRITE" % (c))
elif i.access == CS_AC_READ | CS_AC_WRITE:
print("\t\toperands[%u].access: READ | WRITE" % (c))
(regs_read, regs_write) = insn.regs_access()
if len(regs_read) > 0:
print("\tRegisters read:", end="")
for r in regs_read:
print(" %s" %(insn.reg_name(r)), end="")
print("")
if len(regs_write) > 0:
print("\tRegisters modified:", end="")
for r in regs_write:
print(" %s" %(insn.reg_name(r)), end="")
print("")
if insn.eflags or insn.fpu_flags:
updated_flags = []
for group in insn.groups:
if group == X86_GRP_FPU:
for i in range(64):
if insn.fpu_flags & (1 << i):
updated_flags.append(get_fpu_flag_name(1 << i))
print("\tFPU_FLAGS: %s" % (' '.join(p for p in updated_flags)))
break
if not updated_flags:
for i in range(64):
if insn.eflags & (1 << i):
updated_flags.append(get_eflag_name(1 << i))
print("\tEFLAGS: %s" % (' '.join(p for p in updated_flags)))
# ## Test class Cs
def test_class():
for (arch, mode, code, comment, syntax) in all_tests:
print("*" * 16)
print("Platform: %s" % comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
if syntax is not None:
md.syntax = syntax
for insn in md.disasm(code, 0x1000):
print_insn_detail(mode, insn)
print ()
print ("0x%x:\n" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" % e)
if __name__ == '__main__':
test_class()

View File

@ -1,70 +0,0 @@
#!/usr/bin/env python3
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
from capstone import *
from capstone.xcore import *
from xprint import to_x, to_hex
XCORE_CODE = b"\xfe\x0f\xfe\x17\x13\x17\xc6\xfe\xec\x17\x97\xf8\xec\x4f\x1f\xfd\xec\x37\x07\xf2\x45\x5b\xf9\xfa\x02\x06\x1b\x10\x09\xfd\xec\xa7"
all_tests = (
(CS_ARCH_XCORE, 0, XCORE_CODE, "XCore"),
)
def print_insn_detail(insn):
# print address, mnemonic and operands
print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == 0:
return
if len(insn.operands) > 0:
print("\top_count: %u" % len(insn.operands))
c = 0
for i in insn.operands:
if i.type == XCORE_OP_REG:
print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
if i.type == XCORE_OP_IMM:
print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm)))
if i.type == XCORE_OP_MEM:
print("\t\toperands[%u].type: MEM" % c)
if i.mem.base != 0:
print("\t\t\toperands[%u].mem.base: REG = %s" \
% (c, insn.reg_name(i.mem.base)))
if i.mem.index != 0:
print("\t\t\toperands[%u].mem.index: REG = %s" \
% (c, insn.reg_name(i.mem.index)))
if i.mem.disp != 0:
print("\t\t\toperands[%u].mem.disp: 0x%s" \
% (c, to_x(i.mem.disp)))
if i.mem.direct != 1:
print("\t\t\toperands[%u].mem.direct: -1" % c)
c += 1
# ## Test class Cs
def test_class():
for (arch, mode, code, comment) in all_tests:
print("*" * 16)
print("Platform: %s" %comment)
print("Code: %s" % to_hex(code))
print("Disasm:")
try:
md = Cs(arch, mode)
md.detail = True
for insn in md.disasm(code, 0x1000):
print_insn_detail(insn)
print ()
print("0x%x:\n" % (insn.address + insn.size))
except CsError as e:
print("ERROR: %s" %e)
if __name__ == '__main__':
test_class()

View File

@ -1,5 +1,5 @@
# This file contains all customized compile options for Capstone. # This file contains all customized compile options for Capstone.
# Consult COMPILE.TXT & docs/README for details. # Consult COMPILE_MAKE.TXT & docs/README for details.
################################################################################ ################################################################################
# Specify which archs you want to compile in. By default, we build all archs. # Specify which archs you want to compile in. By default, we build all archs.

5
cs.c
View File

@ -1110,9 +1110,8 @@ cs_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value)
} }
break; break;
case CS_OPT_NO_BRANCH_OFFSET: case CS_OPT_NO_BRANCH_OFFSET:
if (handle->PrintBranchImmNotAsAddress) handle->PrintBranchImmNotAsAddress = value == CS_OPT_ON ? true : false;
return CS_ERR_OK; return CS_ERR_OK;
break;
} }
if (!arch_configs[handle->arch].arch_option) if (!arch_configs[handle->arch].arch_option)

View File

@ -66,14 +66,14 @@ void print_insn_detail_aarch64(csh handle, cs_insn *ins)
printf("\t\toperands[%u].sme.tile: %s\n", i, cs_reg_name(handle, op->sme.tile)); printf("\t\toperands[%u].sme.tile: %s\n", i, cs_reg_name(handle, op->sme.tile));
if (op->sme.slice_reg != AARCH64_REG_INVALID) if (op->sme.slice_reg != AARCH64_REG_INVALID)
printf("\t\toperands[%u].sme.slice_reg: %s\n", i, cs_reg_name(handle, op->sme.slice_reg)); printf("\t\toperands[%u].sme.slice_reg: %s\n", i, cs_reg_name(handle, op->sme.slice_reg));
if (op->sme.slice_offset.imm != -1 || op->sme.slice_offset.imm_range.first != -1) { if (op->sme.slice_offset.imm != AARCH64_SLICE_IMM_INVALID || op->sme.slice_offset.imm_range.first != AARCH64_SLICE_IMM_RANGE_INVALID) {
printf("\t\toperands[%u].sme.slice_offset: ", i); printf("\t\toperands[%u].sme.slice_offset: ", i);
if (op->sme.has_range_offset) if (op->sme.has_range_offset)
printf("%hhd:%hhd\n", op->sme.slice_offset.imm_range.first, op->sme.slice_offset.imm_range.offset); printf("%hhd:%hhd\n", op->sme.slice_offset.imm_range.first, op->sme.slice_offset.imm_range.offset);
else else
printf("%d\n", op->sme.slice_offset.imm); printf("%d\n", op->sme.slice_offset.imm);
} }
if (op->sme.slice_reg != AARCH64_REG_INVALID || op->sme.slice_offset.imm != -1) if (op->sme.slice_reg != AARCH64_REG_INVALID || op->sme.slice_offset.imm != AARCH64_SLICE_IMM_INVALID)
printf("\t\toperands[%u].sme.is_vertical: %s\n", i, (op->sme.is_vertical ? "true" : "false")); printf("\t\toperands[%u].sme.is_vertical: %s\n", i, (op->sme.is_vertical ? "true" : "false"));
break; break;
case AARCH64_OP_PRED: case AARCH64_OP_PRED:

View File

@ -1965,7 +1965,7 @@ typedef enum {
// clang-format on // clang-format on
// generated content <AArch64GenCSSystemOperandsEnum.inc:GET_ENUM_VALUES_TSB> end // generated content <AArch64GenCSSystemOperandsEnum.inc:GET_ENUM_VALUES_TSB> end
AArch64_TSB_ENDING, AARCH64_TSB_ENDING,
} aarch64_tsb; } aarch64_tsb;
typedef union { typedef union {
@ -2788,9 +2788,12 @@ typedef enum {
AARCH64_SME_OP_TILE_VEC, ///< SME operand is a tile indexed by a register and/or immediate AARCH64_SME_OP_TILE_VEC, ///< SME operand is a tile indexed by a register and/or immediate
} aarch64_sme_op_type; } aarch64_sme_op_type;
#define AARCH64_SLICE_IMM_INVALID UINT16_MAX
#define AARCH64_SLICE_IMM_RANGE_INVALID UINT8_MAX
typedef struct { typedef struct {
int8_t first; uint8_t first;
int8_t offset; uint8_t offset;
} aarch64_imm_range; } aarch64_imm_range;
/// SME Instruction's matrix operand /// SME Instruction's matrix operand
@ -2799,9 +2802,9 @@ typedef struct {
aarch64_reg tile; ///< Matrix tile register aarch64_reg tile; ///< Matrix tile register
aarch64_reg slice_reg; ///< slice index reg aarch64_reg slice_reg; ///< slice index reg
union { union {
int8_t imm; uint16_t imm; ///< Invalid if equal to AARCH64_SLICE_IMM_INVALID
aarch64_imm_range imm_range; aarch64_imm_range imm_range; ///< Members are set to AARCH64_SLICE_IMM_RANGE_INVALID if invalid.
} slice_offset; ///< slice index offset. Is set to -1 if invalid. } slice_offset; ///< slice index offset.
bool has_range_offset; ///< If true, the offset is a range. bool has_range_offset; ///< If true, the offset is a range.
bool is_vertical; ///< Flag if slice is vertical or horizontal bool is_vertical; ///< Flag if slice is vertical or horizontal
} aarch64_op_sme; } aarch64_op_sme;

View File

@ -299,4 +299,4 @@ typedef enum alpha_insn_group {
} }
#endif #endif
#endif #endif

View File

@ -903,7 +903,7 @@ typedef struct cs_arm {
ARMVCC_VPTCodes vcc; ///< Vector conditional code for this instruction. ARMVCC_VPTCodes vcc; ///< Vector conditional code for this instruction.
bool update_flags; ///< does this insn update flags? bool update_flags; ///< does this insn update flags?
bool post_index; ///< only set if writeback is 'True', if 'False' pre-index, otherwise post. bool post_index; ///< only set if writeback is 'True', if 'False' pre-index, otherwise post.
int /* arm_mem_bo_opt */ mem_barrier; ///< Option for some memory barrier instructions arm_mem_bo_opt mem_barrier; ///< Option for some memory barrier instructions
// Check ARM_PredBlockMask for encoding details. // Check ARM_PredBlockMask for encoding details.
uint8_t /* ARM_PredBlockMask */ pred_mask; ///< Used by IT/VPT block instructions. uint8_t /* ARM_PredBlockMask */ pred_mask; ///< Used by IT/VPT block instructions.
/// Number of operands of this instruction, /// Number of operands of this instruction,

View File

@ -1863,7 +1863,7 @@ typedef enum {
ARM64_TSB_CSYNC = AARCH64_TSB_CSYNC, ARM64_TSB_CSYNC = AARCH64_TSB_CSYNC,
ARM64_TSB_ENDING = AArch64_TSB_ENDING, ARM64_TSB_ENDING = AARCH64_TSB_ENDING,
} arm64_tsb; } arm64_tsb;
typedef aarch64_sysop_reg arm64_sysop_reg; typedef aarch64_sysop_reg arm64_sysop_reg;

View File

@ -284,7 +284,7 @@ typedef enum cs_opt_type {
CS_OPT_SKIPDATA_SETUP, ///< Setup user-defined function for SKIPDATA option CS_OPT_SKIPDATA_SETUP, ///< Setup user-defined function for SKIPDATA option
CS_OPT_MNEMONIC, ///< Customize instruction mnemonic CS_OPT_MNEMONIC, ///< Customize instruction mnemonic
CS_OPT_UNSIGNED, ///< print immediate operands in unsigned form CS_OPT_UNSIGNED, ///< print immediate operands in unsigned form
CS_OPT_NO_BRANCH_OFFSET, ///< ARM, prints branch immediates without offset. CS_OPT_NO_BRANCH_OFFSET, ///< ARM, PPC, AArch64, prints branch immediates without offset.
} cs_opt_type; } cs_opt_type;
/// Runtime option value (associated with option type above) /// Runtime option value (associated with option type above)
@ -302,6 +302,12 @@ typedef enum cs_opt_value {
CS_OPT_DETAIL_REAL = 1 << 1, ///< If enabled, always sets the real instruction detail. Even if the instruction is an alias. CS_OPT_DETAIL_REAL = 1 << 1, ///< If enabled, always sets the real instruction detail. Even if the instruction is an alias.
} cs_opt_value; } cs_opt_value;
/// An option
typedef struct {
cs_opt_type type; ///< The option type
cs_opt_value val; ///< The option value to set.
} cs_opt;
/// Common instruction groups - to be consistent across all architectures. /// Common instruction groups - to be consistent across all architectures.
typedef enum cs_group_type { typedef enum cs_group_type {
CS_GRP_INVALID = 0, ///< uninitialized/invalid group. CS_GRP_INVALID = 0, ///< uninitialized/invalid group.

View File

@ -540,4 +540,4 @@ typedef enum hppa_insn_group {
} }
#endif #endif
#endif #endif

View File

@ -3280,6 +3280,8 @@ typedef enum ppc_insn_group {
/// PPC instruction formats. To get details about them please /// PPC instruction formats. To get details about them please
/// refer to `PPCInstrFormats.td` in LLVM. /// refer to `PPCInstrFormats.td` in LLVM.
typedef enum { typedef enum {
PPC_INSN_FORM_INVALID = 0,
// generated content <PPCGenCSInsnFormatsEnum.inc> begin // generated content <PPCGenCSInsnFormatsEnum.inc> begin
// clang-format off // clang-format off

View File

@ -64,6 +64,8 @@ typedef enum sparc_hint {
SPARC_HINT_A = 1 << 0, ///< annul delay slot instruction SPARC_HINT_A = 1 << 0, ///< annul delay slot instruction
SPARC_HINT_PT = 1 << 1, ///< branch taken SPARC_HINT_PT = 1 << 1, ///< branch taken
SPARC_HINT_PN = 1 << 2, ///< branch NOT taken SPARC_HINT_PN = 1 << 2, ///< branch NOT taken
SPARC_HINT_A_PN = SPARC_HINT_A | SPARC_HINT_PN,
SPARC_HINT_A_PT = SPARC_HINT_A | SPARC_HINT_PT,
} sparc_hint; } sparc_hint;
/// Operand type for instruction's operands /// Operand type for instruction's operands

View File

@ -246,6 +246,7 @@ typedef enum x86_avx_rm {
/// Instruction prefixes - to be used in cs_x86.prefix[] /// Instruction prefixes - to be used in cs_x86.prefix[]
typedef enum x86_prefix { typedef enum x86_prefix {
X86_PREFIX_0 = 0x0,
X86_PREFIX_LOCK = 0xf0, ///< lock (cs_x86.prefix[0] X86_PREFIX_LOCK = 0xf0, ///< lock (cs_x86.prefix[0]
X86_PREFIX_REP = 0xf3, ///< rep (cs_x86.prefix[0] X86_PREFIX_REP = 0xf3, ///< rep (cs_x86.prefix[0]
X86_PREFIX_REPE = 0xf3, ///< repe/repz (cs_x86.prefix[0] X86_PREFIX_REPE = 0xf3, ///< repe/repz (cs_x86.prefix[0]

View File

@ -18,10 +18,12 @@ BUILD_PATH="$1"
check_list="clang-analyzer-*,-clang-analyzer-cplusplus*,-clang-analyzer-optin.performance.Padding" check_list="clang-analyzer-*,-clang-analyzer-cplusplus*,-clang-analyzer-optin.performance.Padding"
if $(hash clang-tidy-15); then if $(hash clang-tidy-18); then
clang-tidy-15 $(find ./arch ./*.c -type f -iregex ".*\.[c]") -p "$BUILD_PATH" -checks="$check_list" > ct-warnings.txt echo -e "#############\nProduced by\n$(clang-tidy-18 --version)\n#############\n\n" > ct-warnings.txt
clang-tidy-18 $(find ./arch ./*.c -type f -iregex ".*\.[c]") -p "$BUILD_PATH" -checks="$check_list" >> ct-warnings.txt
else else
clang-tidy $(find ./arch ./*.c -type f -iregex ".*\.[c]") -p "$BUILD_PATH" -checks="$check_list" > ct-warnings.txt echo -e "#############\nProduced by\n$(clang-tidy --version)\n#############\n\n" > ct-warnings.txt
clang-tidy $(find ./arch ./*.c -type f -iregex ".*\.[c]") -p "$BUILD_PATH" -checks="$check_list" >> ct-warnings.txt
fi fi
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then

View File

@ -1,47 +0,0 @@
## Input files for testing Capstone engine.
Input files used to test instructions of architectures and modes.
The test cases are taken from `llvm/test/MC`. Note that most of the LLVM tests
are for **encoding** of instructions (`asm_string -> bytes`).
We test the decoding (`bytes -> asm_string`).
A few tests might decode to a different asm string than
used to encode the instruction (because the behavior
of instructions can be equivalent).
Fix the obvious broken tests first and test the rest
against `llvm-objdump`.
### Update test files
Check `suite/auto-sync/README.md`
### Test file formatting
**Format of input files:**
```
# ARCH, MODE, OPTION
hexcode = assembly
```
**Example**
```
# CS_ARCH_ARM, CS_MODE_ARM+CS_MODE_V8, None
0xa0,0x0b,0x71,0xee = vadd.f64 d16, d17, d16
...
```
**Format of issue file:**
```
!# ARCH, MODE, OPTION
hexcode = assembly | regs_read | regs_read_count | regs_write | regs_write_count | groups | groups_count
```
**Example**
```
!# CS_ARCH_ARM64, CS_MODE_ARM, CS_OPT_DETAIL
0xc0,0x1e,0x0c,0x4e == mov v0.s[1], w22 ; operands[0].vas: 0xb ; operands[0].vector_index: 1
...
```

19
suite/MC/README.md Normal file
View File

@ -0,0 +1,19 @@
# Input files for fuzzing input
These files were the legacy test files but replaced.
No it only is consumed by `test_corpus3.py` to generate input cases for the fuzzer.
### Test file formatting
**Format of input files:**
```
# ARCH, MODE, OPTION
<hexcode> = <assembly-text>
```
**Example**
```
# CS_ARCH_ARM, CS_MODE_ARM+CS_MODE_V8, None
0xa0,0x0b,0x71,0xee = vadd.f64 d16, d17, d16
...
```

View File

@ -2,20 +2,9 @@ This directory contains some tools used by developers of Capstone project.
Average users should ignore all the contents here. Average users should ignore all the contents here.
- arm/
Test some ARM's special input.
- MC/
Input used to test various architectures & modes.
- benchmark.py - benchmark.py
This script benchmarks Python binding by disassembling some random code. This script benchmarks Python binding by disassembling some random code.
- test_*.sh
Run all the tests and send the output to external file to be compared later.
This is useful when we want to verify if a commit (wrongly) changes
the disassemble result.
- compile_all.sh - compile_all.sh
Compile Capstone for all platforms (*nix32, clang, cygwin, cross-compile) & Compile Capstone for all platforms (*nix32, clang, cygwin, cross-compile) &
report the result as pass or fail. report the result as pass or fail.
@ -24,10 +13,6 @@ Average users should ignore all the contents here.
This simple script disassembles random code for all archs (or selected arch) This simple script disassembles random code for all archs (or selected arch)
in order to find segfaults. in order to find segfaults.
- test_mc.sh
This script compares the output of Capstone with LLVM's llvm-mc with the
input coming from MC/. This relies on test_mc.py to do all the hard works.
- x86odd.py - x86odd.py
Test some tricky X86 instructions. Test some tricky X86 instructions.

View File

@ -1,12 +0,0 @@
# Sample Makefile for Capstone Disassembly Engine
LIBNAME = capstone
test_arm_regression: test_arm_regression.o
${CC} $< -O3 -Wall -l$(LIBNAME) -o $@
%.o: %.c
${CC} -c -I../../include $< -o $@
clean:
rm -rf *.o test_arm_regression

View File

@ -1,391 +0,0 @@
/* Capstone Disassembler Engine */
/* By David Hogarty, 2014 */
// the following must precede stdio (woo, thanks msft)
#if defined(_MSC_VER) && _MSC_VER < 1900
#define _CRT_SECURE_NO_WARNINGS
#define snprintf _snprintf
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <capstone/platform.h>
#include <capstone/capstone.h>
static csh handle;
struct platform {
cs_arch arch;
cs_mode mode;
unsigned char *code;
size_t size;
char *comment;
int syntax;
};
static char *hex_string(unsigned char *str, size_t len)
{
// returns a malloced string that has the hex version of the string in it
// null if failed to malloc
char *hex_out;
size_t i;
hex_out = (char *) malloc(len*2 + 1); // two ascii characters per input character, plus trailing null
if (!hex_out) { goto Exit; }
for (i = 0; i < len; ++i) {
snprintf(hex_out + (i * 2), 3, "%02x", str[i]);
}
hex_out[len*2] = 0; // trailing null
Exit:
return hex_out;
}
static void snprint_insn_detail(char * buf, size_t * cur, size_t * left, cs_insn *ins)
{
#define _this_printf(...) \
{ \
size_t used = 0; \
used = snprintf(buf + *cur, *left, __VA_ARGS__); \
*left -= used; \
*cur += used; \
}
cs_arm *arm;
int i;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
arm = &(ins->detail->arm);
if (arm->op_count)
_this_printf("\top_count: %u\n", arm->op_count);
for (i = 0; i < arm->op_count; i++) {
cs_arm_op *op = &(arm->operands[i]);
switch((int)op->type) {
default:
break;
case ARM_OP_REG:
_this_printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
break;
case ARM_OP_IMM:
_this_printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
break;
case ARM_OP_FP:
_this_printf("\t\toperands[%u].type: FP = %f\n", i, op->fp);
break;
case ARM_OP_MEM:
_this_printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.base != ARM_REG_INVALID)
_this_printf("\t\t\toperands[%u].mem.base: REG = %s\n",
i, cs_reg_name(handle, op->mem.base));
if (op->mem.index != ARM_REG_INVALID)
_this_printf("\t\t\toperands[%u].mem.index: REG = %s\n",
i, cs_reg_name(handle, op->mem.index));
if (op->mem.scale != 1)
_this_printf("\t\t\toperands[%u].mem.scale: %u\n", i, op->mem.scale);
if (op->mem.disp != 0)
_this_printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
break;
case ARM_OP_PIMM:
_this_printf("\t\toperands[%u].type: P-IMM = %" PRIu64 "\n", i, op->imm);
break;
case ARM_OP_CIMM:
_this_printf("\t\toperands[%u].type: C-IMM = %" PRIu64 "\n", i, op->imm);
break;
}
if (op->shift.type != ARM_SFT_INVALID && op->shift.value) {
if (op->shift.type < ARM_SFT_ASR_REG) {
// shift with constant value
_this_printf("\t\t\tShift: %u = %u\n", op->shift.type, op->shift.value);
} else {
// shift with register
_this_printf("\t\t\tShift: %u = %s\n", op->shift.type,
cs_reg_name(handle, op->shift.value));
}
}
}
if (arm->cc != ARMCC_AL && arm->cc != ARMCC_UNDEF) {
_this_printf("\tCode condition: %u\n", arm->cc);
}
if (arm->update_flags) {
_this_printf("\tUpdate-flags: True\n");
}
if (ins->detail->writeback) {
_this_printf("\tWrite-back: True\n");
}
#undef _this_printf
}
static void print_insn_detail(cs_insn *ins)
{
char a_buf[2048];
size_t cur=0, left=2048;
snprint_insn_detail(a_buf, &cur, &left, ins);
printf("%s\n", a_buf);
}
struct invalid_code {
unsigned char *code;
size_t size;
char *comment;
};
#define MAX_INVALID_CODES 16
struct invalid_instructions {
cs_arch arch;
cs_mode mode;
char *platform_comment;
int num_invalid_codes;
struct invalid_code invalid_codes[MAX_INVALID_CODES];
};
static void test_invalids()
{
struct invalid_instructions invalids[] = {{
CS_ARCH_ARM,
CS_MODE_THUMB,
"Thumb",
1,
{{
(unsigned char *)"\xbd\xe8\x1e\xff",
4,
"invalid thumb2 pop because sp used and because both pc and lr are "
"present at the same time"
}},
}};
struct invalid_instructions * invalid = NULL;
uint64_t address = 0x1000;
cs_insn *insn;
int i;
int j;
size_t count;
printf("\nShould be invalid\n"
"-----------------\n");
for (i = 0; i < sizeof(invalids)/sizeof(invalids[0]); i++) {
cs_err err;
invalid = invalids + i;
err = cs_open(invalid->arch, invalid->mode, &handle);
if (err) {
printf("Failed on cs_open() with error returned: %u\n", err);
continue;
}
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME);
for (j = 0; j < invalid->num_invalid_codes; ++j) {
struct invalid_code *invalid_code = NULL;
char *hex_str = NULL;
invalid_code = invalid->invalid_codes + j;
hex_str = hex_string(invalid_code->code, invalid_code->size);
printf("%s %s: %s\n", invalid->platform_comment, hex_str, invalid_code->comment);
free(hex_str);
count = cs_disasm(handle,
invalid_code->code, invalid_code->size, address, 0, &insn
);
if (count) {
size_t k;
printf(" ERROR:\n");
for (k = 0; k < count; k++) {
printf(" 0x%"PRIx64":\t%s\t%s\n",
insn[k].address, insn[k].mnemonic, insn[k].op_str);
print_insn_detail(&insn[k]);
}
cs_free(insn, count);
} else {
printf(" SUCCESS: invalid\n");
}
}
cs_close(&handle);
}
}
struct valid_code {
unsigned char *code;
size_t size;
uint32_t start_addr;
char *expected_out;
char *comment;
};
#define MAX_VALID_CODES 16
struct valid_instructions {
cs_arch arch;
cs_mode mode;
char *platform_comment;
int num_valid_codes;
struct valid_code valid_codes[MAX_VALID_CODES];
};
static void test_valids()
{
struct valid_instructions valids[] = {{
CS_ARCH_ARM,
CS_MODE_THUMB,
"Thumb",
3,
{{ (unsigned char *)"\x00\xf0\x26\xe8", 4, 0x352,
"0x352:\tblx\t#0x3a0\n"
"\top_count: 1\n"
"\t\toperands[0].type: IMM = 0x3a0\n",
"thumb2 blx with misaligned immediate"
}, { (unsigned char *)"\x05\xdd", 2, 0x1f0,
"0x1f0:\tble\t#0x1fe\n"
"\top_count: 1\n"
"\t\toperands[0].type: IMM = 0x1fe\n"
"\tCode condition: 14\n",
"thumb b cc with thumb-aligned target"
}, { (unsigned char *)"\xbd\xe8\xf0\x8f", 4, 0,
"0x0:\tpop.w\t{r4, r5, r6, r7, r8, r9, r10, r11, pc}\n"
"\top_count: 9\n"
"\t\toperands[0].type: REG = r4\n"
"\t\toperands[1].type: REG = r5\n"
"\t\toperands[2].type: REG = r6\n"
"\t\toperands[3].type: REG = r7\n"
"\t\toperands[4].type: REG = r8\n"
"\t\toperands[5].type: REG = r9\n"
"\t\toperands[6].type: REG = r10\n"
"\t\toperands[7].type: REG = r11\n"
"\t\toperands[8].type: REG = pc\n",
"thumb2 pop that should be valid"
},
}
}};
struct valid_instructions *valid = NULL;
cs_insn *insn;
int i;
int j;
size_t count;
for (i = 0; i < sizeof(valids)/sizeof(valids[0]); i++) {
cs_err err;
valid = valids + i;
err = cs_open(valid->arch, valid->mode, &handle);
if (err) {
printf("Failed on cs_open() with error returned: %u\n", err);
continue;
}
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME);
#define _this_printf(...) \
{ \
size_t used = 0; \
used = snprintf(tmp_buf + cur, left, __VA_ARGS__); \
left -= used; \
cur += used; \
}
printf("\nShould be valid\n"
"---------------\n");
for (j = 0; j < valid->num_valid_codes; ++j) {
char tmp_buf[2048];
size_t left = 2048;
size_t cur = 0;
char * hex_str = NULL;
struct valid_code * valid_code = NULL;
valid_code = valid->valid_codes + j;
hex_str = hex_string(valid_code->code, valid_code->size);
printf("%s %s @ 0x%04x: %s\n %s",
valid->platform_comment, hex_str, valid_code->start_addr,
valid_code->comment, valid_code->expected_out);
free(hex_str);
count = cs_disasm(handle,
valid_code->code, valid_code->size,
valid_code->start_addr, 0, &insn
);
if (count) {
size_t k;
size_t max_len = 0;
size_t tmp_len = 0;
for (k = 0; k < count; k++) {
_this_printf(
"0x%"PRIx64":\t%s\t%s\n",
insn[k].address, insn[k].mnemonic,
insn[k].op_str
);
snprint_insn_detail(tmp_buf, &cur, &left, &insn[k]);
}
max_len = strlen(tmp_buf);
tmp_len = strlen(valid_code->expected_out);
if (tmp_len > max_len) {
max_len = tmp_len;
}
if (memcmp(tmp_buf, valid_code->expected_out, max_len)) {
printf(
" ERROR: '''\n%s''' does not match"
" expected '''\n%s'''\n",
tmp_buf, valid_code->expected_out
);
} else {
printf(" SUCCESS: valid\n");
}
cs_free(insn, count);
} else {
printf("ERROR: invalid\n");
}
}
cs_close(&handle);
}
#undef _this_prinf
}
int main()
{
test_invalids();
test_valids();
return 0;
}

View File

@ -4,4 +4,9 @@ vendor/llvm_root
src/auto-sync/config.json src/auto-sync/config.json
src/autosync/cpptranslator/Tests/Differ/test_saved_patches.json src/autosync/cpptranslator/Tests/Differ/test_saved_patches.json
src/autosync.egg-info src/autosync.egg-info
src/autosync/Tests/MCUpdaterTests/ARCH/Output
src/autosync/Tests/MCUpdaterTests/Disassembler/ARCH/Output
src/autosync/lit_config/test_dir_*
src/autosync/lit_config/.lit_test_times.txt
src/autosync/Tests/MCUpdaterTests/test_output
src/autosync/Tests/MCUpdaterTests/ARCH/Output

View File

@ -15,7 +15,7 @@ Please refer to [intro.md](intro.md) for an introduction about this tool.
## Install ## Install
Setup Python environment and Tree-sitter #### Setup Python environment and Tree-sitter
``` ```
cd <root-dir-Capstone> cd <root-dir-Capstone>
@ -26,13 +26,35 @@ python3 -m venv ./.venv
source ./.venv/bin/activate source ./.venv/bin/activate
``` ```
Install Auto-Sync framework #### Install Auto-Sync framework
``` ```
cd suite/auto-sync/ cd suite/auto-sync/
pip install -e . pip install -e .
``` ```
#### Clone Capstones LLVM fork and build `llvm-tblgen`
```bash
git clone https://github.com/capstone-engine/llvm-capstone vendor/llvm_root/
cd llvm-capstone
git checkout auto-sync
mkdir build
cd build
# You can also build the "Release" version
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ../llvm
cmake --build . --target llvm-tblgen --config Debug
cd ../../
```
#### Install `llvm-mc` and `FileCheck`
Additionally, we need `llvm-mc` and `FileCheck` to generate our regression tests.
You can build it, but it will take a lot of space on your hard drive.
You can also get the binaries [here](https://releases.llvm.org/download.html) or
install it with your package manager (usually something like `llvm-18-dev`).
Just ensure it is in your `PATH` as `llvm-mc` and `FileCheck` (not as `llvm-mc-18` or similar though!).
## Architecture ## Architecture
Please read [ARCHITECTURE.md](https://github.com/capstone-engine/capstone/blob/next/docs/ARCHITECTURE.md) to understand how Auto-Sync works. Please read [ARCHITECTURE.md](https://github.com/capstone-engine/capstone/blob/next/docs/ARCHITECTURE.md) to understand how Auto-Sync works.
@ -50,20 +72,6 @@ Check if your architecture is supported.
./src/autosync/ASUpdater.py -h ./src/autosync/ASUpdater.py -h
``` ```
Clone Capstones LLVM fork and build `llvm-tblgen`
```
git clone https://github.com/capstone-engine/llvm-capstone vendor/llvm_root/
cd llvm-capstone
git checkout auto-sync
mkdir build
cd build
# You can also build the "Release" version
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ../llvm
cmake --build . --target llvm-tblgen --config Debug
cd ../../
```
Run the updater Run the updater
``` ```

View File

@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.15)
set(AUTO_SYNC_C_TEST_SRC_DIR ${AUTO_SYNC_C_TEST_DIR}/src)
set(AUTO_SYNC_C_TEST_INC_DIR ${AUTO_SYNC_C_TEST_DIR}/include)
include_directories(${AUTO_SYNC_C_TEST_INC_DIR} ${PROJECT_SOURCE_DIR}/include)
file(GLOB AUTO_SYNC_C_SRC ${AUTO_SYNC_C_TEST_SRC_DIR}/*.c)
add_executable(compat_header_build_test ${AUTO_SYNC_C_SRC})
add_dependencies(compat_header_build_test capstone)
target_link_libraries(compat_header_build_test PUBLIC capstone)
add_test(NAME ASCompatibilityHeaderTest
COMMAND compat_header_build_test
WORKING_DIRECTORY ${AUTO_SYNC_C_TEST_DIR}
)

View File

@ -12,7 +12,7 @@ int main(void)
csh handle; csh handle;
if (cs_open(CS_ARCH_ARM64, CS_MODE_BIG_ENDIAN, &handle) != CS_ERR_OK) { if (cs_open(CS_ARCH_ARM64, CS_MODE_BIG_ENDIAN, &handle) != CS_ERR_OK) {
printf("cs_open failed\n"); fprintf(stderr, "cs_open failed\n");
return -1; return -1;
} }
@ -20,21 +20,48 @@ int main(void)
cs_insn *insn; cs_insn *insn;
uint8_t bytes[] = "0x1a,0x48,0xa0,0xf8"; uint8_t bytes[] = "0x1a,0x48,0xa0,0xf8";
size_t count = cs_disasm(handle, bytes, sizeof(bytes), 0x1000, 1, &insn); size_t count =
if (count > 0) { cs_disasm(handle, bytes, sizeof(bytes), 0x1000, 1, &insn);
printf("0x%" PRIx64 ":\t%s\t\t%s\n", insn[0].address, if (count != 1) {
insn[0].mnemonic, insn[0].op_str); fprintf(stderr, "Failed to disassemble code.\n");
printf("A register = %s\n", cs_reg_name(handle, insn[0].detail->arm64.operands[0].reg)); goto err;
printf("An imm = 0x%" PRIx64 "\n", insn[0].detail->arm64.operands[1].imm); }
printf("0x%" PRIx64 ":\t%s\t\t%s\n", insn[0].address, insn[0].mnemonic,
insn[0].op_str);
printf("A register = %s\n",
cs_reg_name(handle, insn[0].detail->arm64.operands[0].reg));
printf("An imm = 0x%" PRIx64 "\n",
insn[0].detail->arm64.operands[1].imm);
cs_free(insn, count); if (insn[0].address != 0x1000) {
} else { fprintf(stderr, "Address wrong.\n");
printf("ERROR: Failed to disassemble given code!\n"); goto err;
cs_close(&handle); }
return -1; if (strcmp(insn[0].mnemonic, "adr") != 0) {
fprintf(stderr, "Mnemonic wrong.\n");
goto err;
}
if (strcmp(insn[0].op_str, "x1, 0xf162d") != 0) {
fprintf(stderr, "op_str wrong.\n");
goto err;
}
if (strcmp(cs_reg_name(handle, insn[0].detail->arm64.operands[0].reg),
"x1") != 0) {
fprintf(stderr, "register wrong.\n");
goto err;
}
if (insn[0].detail->arm64.operands[1].imm != 0xf162d) {
fprintf(stderr, "Immediate wrong.\n");
goto err;
} }
cs_free(insn, count);
cs_close(&handle); cs_close(&handle);
return 0; return 0;
err:
printf("ERROR: Failed to disassemble given code corrcetly!\n");
cs_free(insn, count);
cs_close(&handle);
return -1;
} }

View File

@ -1,3 +1,3 @@
#!/usr/bin/bash #!/usr/bin/bash
python3.11 -m black src/autosync python3 -m black src/autosync

View File

@ -7,15 +7,15 @@ name = "autosync"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"termcolor >= 2.3.0", "termcolor >= 2.3.0",
"tree_sitter >= 0.21.3", "tree_sitter == 0.22.3",
"tree-sitter-cpp >=0.22.0", "tree-sitter-cpp >=0.22.0",
"black >= 24.3.0", "black >= 24.3.0",
"usort >= 1.0.8", "usort >= 1.0.8",
"setuptools >= 69.2.0", "setuptools >= 69.2.0",
"ninja >= 1.11.1.1", "ninja >= 1.11.1.1",
"cmake >= 3.28.3",
"reuse >= 3.0.1", "reuse >= 3.0.1",
"clang-format >= 18.1.1", "clang-format >= 18.1.1",
"lit >= 18.1.8",
] ]
requires-python = ">= 3.11" requires-python = ">= 3.11"

View File

@ -73,7 +73,11 @@ class ASUpdater:
self.inc_list, self.inc_list,
) )
self.mc_updater = MCUpdater( self.mc_updater = MCUpdater(
self.arch, get_path("{LLVM_MC_TEST_DIR}"), None, None self.arch,
get_path("{LLVM_MC_TEST_DIR}"),
None,
None,
True if self.arch == "ARM" else False,
) )
def clean_build_dir(self) -> None: def clean_build_dir(self) -> None:
@ -192,6 +196,7 @@ class ASUpdater:
log.info(f"Copied {i} files") log.info(f"Copied {i} files")
# MC tests # MC tests
i = 0
mc_dir = get_path("{MC_DIR}").joinpath(self.arch) mc_dir = get_path("{MC_DIR}").joinpath(self.arch)
log.info(f"Copy MC test files to {mc_dir}") log.info(f"Copy MC test files to {mc_dir}")
for file in get_path("{MCUPDATER_OUT_DIR}").iterdir(): for file in get_path("{MCUPDATER_OUT_DIR}").iterdir():

View File

@ -34,8 +34,8 @@ def find_id_by_type(node: Node, node_types: [str], type_must_match: bool) -> byt
""" """
Recursively searches for a node sequence with given node types. Recursively searches for a node sequence with given node types.
A valid sequence is a path from !\f$node_n\f$ to !\f$node_{(n + |node\_types|-1)}\f$ where A valid sequence is a path from node_n to node_{(n + |node_types|-1)} where
!\f$\forall i \in \{0, ..., |node\_types|-1\}: type(node_{(n + i)}) = node\_types_i\f$. forall i in {0, ..., |node_types|-1}: type(node_{(n + i)}) = node_types_i.
If a node sequence is found, this functions returns the text associated with the If a node sequence is found, this functions returns the text associated with the
last node in the sequence. last node in the sequence.
@ -159,6 +159,11 @@ def get_path(config_path: str) -> Path:
return PathVarHandler().complete_path(config_path) return PathVarHandler().complete_path(config_path)
def test_only_overwrite_path_var(var_name: str, new_path: Path):
"""Don't use outside of testing."""
return PathVarHandler().test_only_overwrite_var(var_name, new_path)
def fail_exit(msg: str) -> None: def fail_exit(msg: str) -> None:
"""Logs a fatal message and exits with error code 1.""" """Logs a fatal message and exits with error code 1."""
log.fatal(msg) log.fatal(msg)

Some files were not shown because too many files have changed in this diff Show More