Python binding setup refactoring + cibuildwheel workflow (#2026)
* Python bindings: Make the test scripts handy for pytest * Python bindings: Update MANIFEST.in with new paths * Update .gitignore to exclude PyCharm-related files/folders * Python bindings: Update CMakeLists.txt in order to set CMAKE_OSX_ARCHITECTURES var * Python bindings: - Moved project package settings to the new TOML format - Refactored setup.py to cleanup/improve the code and make it ready for cibuildwheel - Updated README.md with the package long description part - Removed setup.cfg since universal wheel building will be deprecated soon * Python bindings: - Replaced old PyPI-publishing.yml workflow with brand-new one based on cibuildwheel - Removed old building scripts * Replaced macos-12 runner with macos-13 since it will be removed soon * Python bindings: Specify SYSTEM_VERSION_COMPAT=0 env var for macos-13 x86_64 runner as per cibuildwheel warning message * Python bindings: Enable i686 for debugging * Python bindings: Enable DEBUG flag according to the presence of tag release * Python bindings: Added matrix to cover i686 manylinux/musllinux builds * Python bindings: - Replaced macos-14 runner with macos-latest - Bumped cibuildwheel GitHub action to 2.21.3 version * Python bindings: - Adapt test_uc_ctl_tb_cache test to the recent changes - Fixed typos - PEP8 fixes * GitHub Action Workflow: Introduce BUILD_TYPE env var to select build type according to the presence of tag release --------- Co-authored-by: mio <mio@lazym.io>
This commit is contained in:
167
.github/workflows/PyPI-publishing.yml
vendored
167
.github/workflows/PyPI-publishing.yml
vendored
@@ -1,167 +0,0 @@
|
||||
name: PyPI 📦 Distribution
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- ".gitignore"
|
||||
- "docs/**"
|
||||
- "README"
|
||||
- "CREDITS.TXT"
|
||||
- "COPYING_GLIB"
|
||||
- "COPYING.LGPL2"
|
||||
- "AUTHORS.TXT"
|
||||
- "CHANGELOG"
|
||||
- "COPYING"
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
name: ${{ matrix.config.name }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- {
|
||||
os: windows-2019,
|
||||
arch: x64,
|
||||
python-ver: '3.8',
|
||||
name: 'win_amd64'
|
||||
}
|
||||
- {
|
||||
os: windows-2019,
|
||||
arch: x32,
|
||||
python-ver: '3.8',
|
||||
name: 'win32'
|
||||
}
|
||||
- {
|
||||
os: ubuntu-latest,
|
||||
arch: x64,
|
||||
python-ver: '3.8',
|
||||
name: 'musllinux'
|
||||
}
|
||||
- {
|
||||
os: ubuntu-latest,
|
||||
arch: x64,
|
||||
python-ver: '3.8',
|
||||
name: 'manylinux2014_x86_64'
|
||||
}
|
||||
- {
|
||||
os: ubuntu-latest,
|
||||
arch: x32,
|
||||
python-ver: '3.8',
|
||||
name: 'manylinux2014_i686'
|
||||
}
|
||||
- {
|
||||
os: ubuntu-latest,
|
||||
arch: aarch64,
|
||||
python-ver: '3.8',
|
||||
name: 'manylinux2014_aarch64'
|
||||
}
|
||||
- {
|
||||
os: ubuntu-latest,
|
||||
arch: x64,
|
||||
python-ver: '3.8',
|
||||
name: 'sdist'
|
||||
}
|
||||
- {
|
||||
os: macos-12,
|
||||
arch: x86_64,
|
||||
python-ver: '3.8',
|
||||
name: 'macos_x86_64'
|
||||
}
|
||||
- {
|
||||
os: macos-14,
|
||||
arch: arm64,
|
||||
python-ver: '3.10',
|
||||
name: 'macos_arm64'
|
||||
}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: '🛠️ Set up Python'
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.config.python-ver }}
|
||||
|
||||
- name: '🛠️ Add msbuild to PATH'
|
||||
if: contains(matrix.config.name, 'win')
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
with:
|
||||
vs-version: '16.5'
|
||||
|
||||
- name: '🛠️ Win MSVC 32 dev cmd setup'
|
||||
if: contains(matrix.config.name, 'win32')
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: x86
|
||||
|
||||
- name: '🛠️ Win MSVC 64 dev cmd setup'
|
||||
if: contains(matrix.config.name, 'win_amd64')
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: x64
|
||||
|
||||
- name: '🛠️ Win build dependencies'
|
||||
if: contains(matrix.config.name, 'win')
|
||||
shell: bash
|
||||
run: |
|
||||
choco install ninja cmake
|
||||
|
||||
- name: '🛠️ macOS dependencies'
|
||||
if: contains(matrix.config.name, 'macos')
|
||||
run: |
|
||||
brew install ninja
|
||||
|
||||
- name: '🛠️ pip dependencies'
|
||||
run: |
|
||||
pip install --upgrade setuptools wheel
|
||||
|
||||
- name: '🚧 Build distribution'
|
||||
shell: bash
|
||||
run: |
|
||||
if [ ${{ matrix.config.name }} == 'win32' ]; then
|
||||
cd bindings/python && python setup.py build -p win32 sdist bdist_wheel -p win32
|
||||
rm dist/*.tar.gz
|
||||
elif [ ${{ matrix.config.name }} == 'manylinux2014_i686' ]; then
|
||||
docker run --rm -v `pwd`/:/work dockcross/manylinux2014-x86 > ./dockcross
|
||||
chmod +x ./dockcross
|
||||
./dockcross bindings/python/build_wheel.sh
|
||||
elif [ ${{ matrix.config.name }} == 'manylinux2014_aarch64' ]; then
|
||||
docker run --rm -v `pwd`/:/work dockcross/manylinux2014-aarch64 > ./dockcross
|
||||
chmod +x ./dockcross
|
||||
./dockcross bindings/python/build_wheel.sh --plat-name manylinux2014_aarch64
|
||||
elif [ ${{ matrix.config.name }} == 'manylinux2014_x86_64' ]; then
|
||||
docker run --rm -v `pwd`/:/work dockcross/manylinux2014-x64 > ./dockcross
|
||||
chmod +x ./dockcross
|
||||
./dockcross bindings/python/build_wheel.sh
|
||||
elif [ ${{ matrix.config.name }} == 'musllinux' ]; then
|
||||
docker run --rm -v `pwd`:/work -w /work python:3.7-alpine sh /work/bindings/python/musl_wheel.sh
|
||||
elif [ ${{ matrix.config.name }} == 'sdist' ]; then
|
||||
cd bindings/python && python setup.py sdist
|
||||
elif [ ${{ matrix.config.name }} == 'macos_arm64' ]; then
|
||||
cd bindings/python && _PYTHON_HOST_PLATFORM="macosx-11.0-arm64" ARCHFLAGS="-arch arm64" python setup.py bdist_wheel
|
||||
else
|
||||
cd bindings/python && python setup.py bdist_wheel
|
||||
fi
|
||||
- name: '📤 Upload artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.config.name }}
|
||||
path: ${{ github.workspace }}/bindings/python/dist/*
|
||||
|
||||
publish:
|
||||
needs: [build]
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
merge-multiple: true
|
||||
path: dist
|
||||
|
||||
- name: '📦 Publish distribution to PyPI'
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.pypi_pass }}
|
||||
84
.github/workflows/build-uc2.yml
vendored
84
.github/workflows/build-uc2.yml
vendored
@@ -4,18 +4,19 @@ on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- ".gitignore"
|
||||
- "docs/**"
|
||||
- "README"
|
||||
- "CREDITS.TXT"
|
||||
- "COPYING_GLIB"
|
||||
- "COPYING.LGPL2"
|
||||
- "AUTHORS.TXT"
|
||||
- "CHANGELOG"
|
||||
- "COPYING"
|
||||
- "COPYING.LGPL2"
|
||||
- "COPYING_GLIB"
|
||||
- "CREDITS.TXT"
|
||||
- "ChangeLog"
|
||||
- "README.md"
|
||||
- "docs/**"
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
CI: true
|
||||
# Build Debug mode if not tag release
|
||||
BUILD_TYPE: ${{ startsWith(github.ref, 'refs/tags') && 'Release' || 'Debug' }}
|
||||
|
||||
jobs:
|
||||
Windows:
|
||||
@@ -35,7 +36,6 @@ jobs:
|
||||
mingw: MINGW64,
|
||||
mingw-arch: x86_64,
|
||||
artifact: 'windows_mingw64-shared.7z',
|
||||
build_type: 'Debug',
|
||||
archiver: '7z a',
|
||||
generators: 'Ninja'
|
||||
}
|
||||
@@ -49,7 +49,6 @@ jobs:
|
||||
mingw: MINGW64,
|
||||
mingw-arch: x86_64,
|
||||
artifact: 'windows_mingw64-static.7z',
|
||||
build_type: 'Debug',
|
||||
archiver: '7z a',
|
||||
generators: 'Ninja'
|
||||
}
|
||||
@@ -63,7 +62,6 @@ jobs:
|
||||
# mingw: MINGW32,
|
||||
# mingw-arch: i686,
|
||||
# artifact: 'windows_mingw32.7z',
|
||||
# build_type: 'Debug',
|
||||
# archiver: '7z a',
|
||||
# generators: 'Ninja'
|
||||
# }
|
||||
@@ -77,7 +75,6 @@ jobs:
|
||||
# mingw: MINGW32,
|
||||
# mingw-arch: i686,
|
||||
# artifact: 'windows_mingw32.7z',
|
||||
# build_type: 'Debug',
|
||||
# archiver: '7z a',
|
||||
# generators: 'Ninja'
|
||||
# }
|
||||
@@ -90,7 +87,6 @@ jobs:
|
||||
msvc-arch: x64,
|
||||
artifact: 'windows_msvc64_shared.7z',
|
||||
shared: 'yes',
|
||||
build_type: 'Debug',
|
||||
archiver: '7z a',
|
||||
generators: 'Visual Studio 16 2019'
|
||||
}
|
||||
@@ -103,7 +99,6 @@ jobs:
|
||||
msvc-arch: x86,
|
||||
artifact: 'windows_msvc32_shared.7z',
|
||||
shared: 'yes',
|
||||
build_type: 'Debug',
|
||||
archiver: '7z a',
|
||||
generators: 'Visual Studio 16 2019'
|
||||
}
|
||||
@@ -116,7 +111,6 @@ jobs:
|
||||
msvc-arch: x64,
|
||||
artifact: 'windows_msvc64_static.7z',
|
||||
shared: 'no',
|
||||
build_type: 'Debug',
|
||||
archiver: '7z a',
|
||||
generators: 'Visual Studio 16 2019'
|
||||
}
|
||||
@@ -129,7 +123,6 @@ jobs:
|
||||
msvc-arch: x86,
|
||||
artifact: 'windows_msvc32_static.7z',
|
||||
shared: 'no',
|
||||
build_type: 'Debug',
|
||||
archiver: '7z a',
|
||||
generators: 'Visual Studio 16 2019'
|
||||
}
|
||||
@@ -171,13 +164,13 @@ jobs:
|
||||
cmake \
|
||||
-S . \
|
||||
-B . \
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
|
||||
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||
-G "${{ matrix.config.generators }}" \
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=instdir \
|
||||
-DBUILD_SHARED_LIBS=${{ matrix.config.shared }}
|
||||
cmake --build . --config ${{ matrix.config.build_type }}
|
||||
cmake --install . --strip --config ${{ matrix.config.build_type }}
|
||||
ctest -VV -C ${{ matrix.config.build_type }}
|
||||
cmake --build . --config ${{ env.BUILD_TYPE }}
|
||||
cmake --install . --strip --config ${{ env.BUILD_TYPE }}
|
||||
ctest -VV -C ${{ env.BUILD_TYPE }}
|
||||
mv Debug instdir
|
||||
|
||||
- name: '🛠️ Win MSVC 32 setup'
|
||||
@@ -198,13 +191,13 @@ jobs:
|
||||
-S . \
|
||||
-B . \
|
||||
-A "win32" \
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
|
||||
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||
-G "${{ matrix.config.generators }}" \
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=instdir \
|
||||
-DBUILD_SHARED_LIBS=${{ matrix.config.shared }}
|
||||
cmake --build . --config ${{ matrix.config.build_type }}
|
||||
cmake --install . --strip --config ${{ matrix.config.build_type }}
|
||||
ctest -VV -C ${{ matrix.config.build_type }}
|
||||
cmake --build . --config ${{ env.BUILD_TYPE }}
|
||||
cmake --install . --strip --config ${{ env.BUILD_TYPE }}
|
||||
ctest -VV -C ${{ env.BUILD_TYPE }}
|
||||
mv Debug instdir
|
||||
|
||||
- name: '🚧 Win MINGW build'
|
||||
@@ -226,14 +219,14 @@ jobs:
|
||||
cmake \
|
||||
-S . \
|
||||
-B . \
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
|
||||
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||
-G "${{ matrix.config.generators }}" \
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=instdir \
|
||||
-DCMAKE_C_FLAGS:STRING="-static" \
|
||||
-DBUILD_SHARED_LIBS=${{ matrix.config.shared }}
|
||||
cmake --build . --config ${{ matrix.config.build_type }}
|
||||
cmake --build . --config ${{ env.BUILD_TYPE }}
|
||||
cmake --install . --strip
|
||||
ctest -VV -C ${{ matrix.config.build_type }}
|
||||
ctest -VV -C ${{ env.BUILD_TYPE }}
|
||||
|
||||
- name: '📦 Pack artifact'
|
||||
if: always()
|
||||
@@ -258,26 +251,24 @@ jobs:
|
||||
matrix:
|
||||
config:
|
||||
- {
|
||||
os: macos-12, # x64
|
||||
os: macos-13, # x64
|
||||
arch: x64,
|
||||
python-arch: x64,
|
||||
python-ver: '3.8',
|
||||
name: 'macos-x64 cmake shared',
|
||||
shared: 'yes',
|
||||
artifact: 'macos-x64-cmake-shared-x64.7z',
|
||||
build_type: 'Debug',
|
||||
archiver: '7za a',
|
||||
generators: 'Ninja'
|
||||
}
|
||||
- {
|
||||
os: macos-12,
|
||||
os: macos-13,
|
||||
arch: x64,
|
||||
python-arch: x64,
|
||||
python-ver: '3.8',
|
||||
name: 'macos-x64 cmake static',
|
||||
shared: 'no',
|
||||
artifact: 'macos-x64-cmake-static-x64.7z',
|
||||
build_type: 'Debug',
|
||||
archiver: '7za a',
|
||||
generators: 'Ninja'
|
||||
}
|
||||
@@ -289,7 +280,6 @@ jobs:
|
||||
name: 'macos-arm64 cmake shared',
|
||||
shared: 'yes',
|
||||
artifact: 'macos-arm64-cmake-shared-x64.7z',
|
||||
build_type: 'Debug',
|
||||
archiver: '7za a',
|
||||
generators: 'Ninja'
|
||||
}
|
||||
@@ -301,18 +291,16 @@ jobs:
|
||||
name: 'macos-arm64 cmake static',
|
||||
shared: 'no',
|
||||
artifact: 'macos-arm64-cmake-static-x64.7z',
|
||||
build_type: 'Debug',
|
||||
archiver: '7za a',
|
||||
generators: 'Ninja'
|
||||
}
|
||||
- {
|
||||
os: macos-12,
|
||||
os: macos-13,
|
||||
arch: x86_64,
|
||||
python-arch: x86_64,
|
||||
python-ver: '3.8',
|
||||
name: 'android cmake',
|
||||
artifact: 'Android-x86_64.7z',
|
||||
build_type: 'Debug',
|
||||
archiver: '7za a',
|
||||
generators: 'Ninja'
|
||||
}
|
||||
@@ -337,13 +325,13 @@ jobs:
|
||||
cmake \
|
||||
-S . \
|
||||
-B . \
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
|
||||
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||
-G "${{ matrix.config.generators }}" \
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=instdir \
|
||||
-DBUILD_SHARED_LIBS=${{ matrix.config.shared }}
|
||||
cmake --build . --config ${{ matrix.config.build_type }}
|
||||
cmake --build . --config ${{ env.BUILD_TYPE }}
|
||||
cmake --install . --strip
|
||||
ctest -VV -C ${{ matrix.config.build_type }}
|
||||
ctest -VV -C ${{ env.BUILD_TYPE }}
|
||||
|
||||
# - name: Setup tmate session
|
||||
# if: ${{ failure() }}
|
||||
@@ -364,10 +352,10 @@ jobs:
|
||||
-DOLP_SDK_BUILD_EXAMPLES=ON \
|
||||
-S . \
|
||||
-B . \
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
|
||||
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||
-G "${{ matrix.config.generators }}" \
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=instdir
|
||||
cmake --build . --config ${{ matrix.config.build_type }}
|
||||
cmake --build . --config ${{ env.BUILD_TYPE }}
|
||||
cmake --install . --strip
|
||||
|
||||
- name: '🚧 AVD Cache'
|
||||
@@ -436,7 +424,6 @@ jobs:
|
||||
name: 'ubuntu-x64 cmake shared',
|
||||
shared: 'yes',
|
||||
artifact: 'ubuntu-cmake-shared-x64.7z',
|
||||
build_type: 'Debug',
|
||||
archiver: '7z a',
|
||||
generators: 'Ninja'
|
||||
}
|
||||
@@ -448,7 +435,6 @@ jobs:
|
||||
name: 'ubuntu-x86 cmake shared',
|
||||
shared: 'yes',
|
||||
artifact: 'ubuntu-cmake-shared-x86.7z',
|
||||
build_type: 'Debug',
|
||||
archiver: '7z a',
|
||||
generators: 'Ninja'
|
||||
}
|
||||
@@ -460,7 +446,6 @@ jobs:
|
||||
name: 'ubuntu-x64 cmake static',
|
||||
shared: 'no',
|
||||
artifact: 'ubuntu-cmake-static-x64.7z',
|
||||
build_type: 'Debug',
|
||||
archiver: '7z a',
|
||||
generators: 'Ninja'
|
||||
}
|
||||
@@ -472,7 +457,6 @@ jobs:
|
||||
name: 'ubuntu-x86 cmake static',
|
||||
shared: 'no',
|
||||
artifact: 'ubuntu-cmake-static-x86.7z',
|
||||
build_type: 'Debug',
|
||||
archiver: '7z a',
|
||||
generators: 'Ninja'
|
||||
}
|
||||
@@ -483,7 +467,6 @@ jobs:
|
||||
python-ver: '3.8',
|
||||
name: 'ubuntu-aarch64 cmake',
|
||||
artifact: 'ubuntu-cmake-aarch64.7z',
|
||||
build_type: 'Debug',
|
||||
archiver: '7z a',
|
||||
generators: 'Ninja',
|
||||
distro: ubuntu20.04
|
||||
@@ -495,7 +478,6 @@ jobs:
|
||||
python-ver: '3.8',
|
||||
name: 'ubuntu-ppc64le cmake',
|
||||
artifact: 'ubuntu-cmake-ppc64le.7z',
|
||||
build_type: 'Debug',
|
||||
archiver: '7z a',
|
||||
generators: 'Ninja',
|
||||
distro: ubuntu20.04
|
||||
@@ -526,13 +508,13 @@ jobs:
|
||||
cmake \
|
||||
-S . \
|
||||
-B . \
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
|
||||
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||
-G "${{ matrix.config.generators }}" \
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=instdir \
|
||||
-DBUILD_SHARED_LIBS=${{ matrix.config.shared }}
|
||||
cmake --build . --config ${{ matrix.config.build_type }}
|
||||
cmake --build . --config ${{ env.BUILD_TYPE }}
|
||||
cmake --install . --strip
|
||||
ctest -VV -C ${{ matrix.config.build_type }}
|
||||
ctest -VV -C ${{ env.BUILD_TYPE }}
|
||||
|
||||
- name: '🚧 Linux ppc64le/aarch64 build'
|
||||
if: contains(matrix.config.arch, 'ppc64le') || contains(matrix.config.arch, 'aarch64')
|
||||
@@ -553,12 +535,12 @@ jobs:
|
||||
cmake \
|
||||
-S . \
|
||||
-B . \
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
|
||||
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||
-G "${{ matrix.config.generators }}" \
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=/instdir
|
||||
cmake --build . --config ${{ matrix.config.build_type }}
|
||||
cmake --build . --config ${{ env.BUILD_TYPE }}
|
||||
cmake --install . --strip
|
||||
ctest -VV -C ${{ matrix.config.build_type }}
|
||||
ctest -VV -C ${{ env.BUILD_TYPE }}
|
||||
|
||||
- name: '📦 Pack artifact'
|
||||
if: always()
|
||||
|
||||
360
.github/workflows/build-wheels-publish.yml
vendored
Normal file
360
.github/workflows/build-wheels-publish.yml
vendored
Normal file
@@ -0,0 +1,360 @@
|
||||
name: Build wheels with cibuildwheel
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- ".gitignore"
|
||||
- "AUTHORS.TXT"
|
||||
- "COPYING"
|
||||
- "COPYING.LGPL2"
|
||||
- "COPYING_GLIB"
|
||||
- "CREDITS.TXT"
|
||||
- "ChangeLog"
|
||||
- "README.md"
|
||||
- "docs/**"
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
# Enable DEBUG flag if not tag release
|
||||
UNICORN_DEBUG: ${{ startsWith(github.ref, 'refs/tags') && '0' || '1' }}
|
||||
|
||||
jobs:
|
||||
# job to be executed for every push - testing purpose
|
||||
build_wheels_python38_only:
|
||||
name: Building on ${{ matrix.os }} - ${{ matrix.arch }} ${{ matrix.cibw_build }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# NOTE: aarch64 builds are super slow due to QEMU emulation. Making this to parallelize and speed up workflow
|
||||
# i686 - manylinux
|
||||
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp38-manylinux' }
|
||||
# i686 - musllinux
|
||||
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp38-musllinux' }
|
||||
# x86_64 - manylinux
|
||||
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp38-manylinux' }
|
||||
# x86_64 - musllinux
|
||||
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp38-musllinux' }
|
||||
# aarch64 - manylinux
|
||||
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp38-manylinux' }
|
||||
# aarch64 - musllinux
|
||||
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp38-musllinux' }
|
||||
- { os: macos-13, arch: x86_64, cibw_build: '' }
|
||||
- { os: macos-latest, arch: arm64, cibw_build: '' }
|
||||
- { os: windows-2019, arch: AMD64, cibw_build: '' }
|
||||
- { os: windows-2019, arch: x86, cibw_build: '' }
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: '🛠️ Add msbuild to PATH'
|
||||
if: runner.os == 'Windows'
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
with:
|
||||
vs-version: '16.5'
|
||||
|
||||
- name: '🛠️ Win build dependencies'
|
||||
if: runner.os == 'Windows'
|
||||
shell: bash
|
||||
run: |
|
||||
choco install ninja cmake
|
||||
|
||||
- name: '🛠️ macOS dependencies'
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
brew install ninja
|
||||
|
||||
# https://cibuildwheel.pypa.io/en/stable/faq/#macos-building-cpython-38-wheels-on-arm64
|
||||
- uses: actions/setup-python@v5
|
||||
if: runner.os == 'macOS' && runner.arch == 'ARM64'
|
||||
with:
|
||||
python-version: 3.8
|
||||
|
||||
- name: '🛠️ Win MSVC 32 dev cmd setup'
|
||||
if: runner.os == 'Windows' && matrix.arch == 'x86'
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: x86
|
||||
|
||||
- name: '🛠️ Win MSVC 64 dev cmd setup'
|
||||
if: runner.os == 'Windows' && matrix.arch == 'AMD64'
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: x64
|
||||
|
||||
- name: '🛠️ Set up QEMU'
|
||||
if: runner.os == 'Linux'
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: '🚧 cibuildwheel run - Linux'
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
uses: pypa/cibuildwheel@v2.21.3
|
||||
env:
|
||||
CIBW_BUILD_FRONTEND: build
|
||||
CIBW_BUILD: ${{ matrix.cibw_build }}*
|
||||
CIBW_ARCHS: ${{ matrix.arch }}
|
||||
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
|
||||
CIBW_ENVIRONMENT_PASS_LINUX: DEBUG
|
||||
CIBW_TEST_REQUIRES: pytest
|
||||
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||
with:
|
||||
package-dir: bindings/python
|
||||
output-dir: wheelhouse
|
||||
|
||||
- name: '🚧 cibuildwheel run - Windows'
|
||||
if: matrix.os == 'windows-2019'
|
||||
uses: pypa/cibuildwheel@v2.21.3
|
||||
env:
|
||||
CIBW_BUILD_FRONTEND: build
|
||||
CIBW_BUILD: 'cp38*'
|
||||
CIBW_ARCHS: ${{ matrix.arch }}
|
||||
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
|
||||
CIBW_TEST_REQUIRES: pytest
|
||||
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||
with:
|
||||
package-dir: bindings/python
|
||||
output-dir: wheelhouse
|
||||
|
||||
- name: '🚧 cibuildwheel run - MacOS x86_84'
|
||||
if: matrix.os == 'macos-13'
|
||||
uses: pypa/cibuildwheel@v2.21.3
|
||||
env:
|
||||
CIBW_BUILD_FRONTEND: build
|
||||
CIBW_BUILD: 'cp38*'
|
||||
CIBW_ENVIRONMENT: SYSTEM_VERSION_COMPAT=0 DEBUG=${{ env.UNICORN_DEBUG }}
|
||||
CIBW_TEST_REQUIRES: pytest
|
||||
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||
with:
|
||||
package-dir: bindings/python
|
||||
output-dir: wheelhouse
|
||||
|
||||
- name: '🚧 cibuildwheel run - MacOS arm64'
|
||||
if: matrix.os == 'macos-latest'
|
||||
uses: pypa/cibuildwheel@v2.21.3
|
||||
env:
|
||||
CIBW_BUILD_FRONTEND: build
|
||||
CIBW_BUILD: 'cp38*'
|
||||
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
|
||||
CIBW_TEST_REQUIRES: pytest
|
||||
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||
# https://github.com/pypa/cibuildwheel/pull/1169
|
||||
CIBW_TEST_SKIP: "cp38-macosx_*:arm64"
|
||||
with:
|
||||
package-dir: bindings/python
|
||||
output-dir: wheelhouse
|
||||
|
||||
# we re-tag cp38 wheel (just an old one) with py2 tag. Hacky but it works...
|
||||
- name: '🚧 Python 2.7 wheels re-tagging - Windows'
|
||||
if: matrix.os == 'windows-2019'
|
||||
run: |
|
||||
python -m pip install -U pip wheel && Get-ChildItem -Path wheelhouse/ -Filter *cp38*.whl | Foreach-Object {
|
||||
python -m wheel tags --python-tag='py2' --abi-tag=none $_.FullName
|
||||
}
|
||||
- name: '🚧 Python 2.7 wheels re-tagging - Non-Windows'
|
||||
if: matrix.os != 'windows-2019'
|
||||
env:
|
||||
PIP_BREAK_SYSTEM_PACKAGES: 1
|
||||
run: |
|
||||
python3 -m pip install -U pip wheel && python3 -m wheel tags --python-tag='py2' --abi-tag=none wheelhouse/*cp38*.whl
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
|
||||
path: ./wheelhouse/*.whl
|
||||
|
||||
# Job to be executed to build all wheels for all platforms/architectures/python versions only for tag release
|
||||
build_wheels_all_versions:
|
||||
name: Building on ${{ matrix.os }} - ${{ matrix.arch }} ${{ matrix.cibw_build }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# NOTE: aarch64 builds are super slow due to QEMU emulation. Making this to parallelize and speed up workflow
|
||||
# i686 - manylinux
|
||||
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp37-manylinux' }
|
||||
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp39-manylinux' }
|
||||
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp310-manylinux' }
|
||||
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp311-manylinux' }
|
||||
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp312-manylinux' }
|
||||
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp313-manylinux' }
|
||||
# i686 - musllinux
|
||||
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp37-musllinux' }
|
||||
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp39-musllinux' }
|
||||
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp310-musllinux' }
|
||||
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp311-musllinux' }
|
||||
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp312-musllinux' }
|
||||
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp313-musllinux' }
|
||||
# x86_64 - manylinux
|
||||
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp37-manylinux' }
|
||||
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp39-manylinux' }
|
||||
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp310-manylinux' }
|
||||
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp311-manylinux' }
|
||||
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp312-manylinux' }
|
||||
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp313-manylinux' }
|
||||
# x86_64 - musllinux
|
||||
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp37-musllinux' }
|
||||
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp39-musllinux' }
|
||||
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp310-musllinux' }
|
||||
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp311-musllinux' }
|
||||
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp312-musllinux' }
|
||||
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp313-musllinux' }
|
||||
# aarch64 - manylinux
|
||||
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp37-manylinux' }
|
||||
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp39-manylinux' }
|
||||
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp310-manylinux' }
|
||||
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp311-manylinux' }
|
||||
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp312-manylinux' }
|
||||
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp313-manylinux' }
|
||||
# aarch64 - musllinux
|
||||
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp37-musllinux' }
|
||||
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp39-musllinux' }
|
||||
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp310-musllinux' }
|
||||
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp311-musllinux' }
|
||||
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp312-musllinux' }
|
||||
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp313-musllinux' }
|
||||
- { os: macos-13, arch: x86_64, cibw_build: '' }
|
||||
- { os: macos-latest, arch: arm64, cibw_build: '' }
|
||||
- { os: windows-2019, arch: AMD64, cibw_build: '' }
|
||||
- { os: windows-2019, arch: x86, cibw_build: '' }
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: '🛠️ Add msbuild to PATH'
|
||||
if: runner.os == 'Windows'
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
with:
|
||||
vs-version: '16.5'
|
||||
|
||||
- name: '🛠️ Win build dependencies'
|
||||
if: runner.os == 'Windows'
|
||||
shell: bash
|
||||
run: |
|
||||
choco install ninja cmake
|
||||
|
||||
- name: '🛠️ macOS dependencies'
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
brew install ninja
|
||||
|
||||
- name: '🛠️ Win MSVC 32 dev cmd setup'
|
||||
if: runner.os == 'Windows' && matrix.arch == 'x86'
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: x86
|
||||
|
||||
- name: '🛠️ Win MSVC 64 dev cmd setup'
|
||||
if: runner.os == 'Windows' && matrix.arch == 'AMD64'
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: x64
|
||||
|
||||
- name: '🛠️ Set up QEMU'
|
||||
if: runner.os == 'Linux'
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: '🚧 cibuildwheel run - Linux'
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
uses: pypa/cibuildwheel@v2.21.3
|
||||
env:
|
||||
CIBW_BUILD_FRONTEND: build
|
||||
CIBW_BUILD: ${{ matrix.cibw_build }}*
|
||||
CIBW_ARCHS: ${{ matrix.arch }}
|
||||
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
|
||||
CIBW_ENVIRONMENT_PASS_LINUX: DEBUG
|
||||
CIBW_TEST_REQUIRES: pytest
|
||||
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||
with:
|
||||
package-dir: bindings/python
|
||||
output-dir: wheelhouse
|
||||
|
||||
- name: '🚧 cibuildwheel run - Windows'
|
||||
if: matrix.os == 'windows-2019'
|
||||
uses: pypa/cibuildwheel@v2.21.3
|
||||
env:
|
||||
CIBW_BUILD_FRONTEND: build
|
||||
CIBW_SKIP: '*36* *38*'
|
||||
CIBW_BUILD: 'cp*'
|
||||
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
|
||||
CIBW_ARCHS: ${{ matrix.arch }}
|
||||
CIBW_TEST_REQUIRES: pytest
|
||||
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||
with:
|
||||
package-dir: bindings/python
|
||||
output-dir: wheelhouse
|
||||
|
||||
- name: '🚧 cibuildwheel run - MacOS x86_84'
|
||||
if: matrix.os == 'macos-13'
|
||||
uses: pypa/cibuildwheel@v2.21.3
|
||||
env:
|
||||
CIBW_BUILD_FRONTEND: build
|
||||
CIBW_SKIP: '*36* *38*'
|
||||
CIBW_BUILD: 'cp*'
|
||||
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
|
||||
CIBW_TEST_REQUIRES: pytest
|
||||
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||
with:
|
||||
package-dir: bindings/python
|
||||
output-dir: wheelhouse
|
||||
|
||||
- name: '🚧 cibuildwheel run - MacOS arm64'
|
||||
if: matrix.os == 'macos-latest'
|
||||
uses: pypa/cibuildwheel@v2.21.3
|
||||
env:
|
||||
CIBW_BUILD_FRONTEND: build
|
||||
CIBW_SKIP: '*36* *37* *38*'
|
||||
CIBW_BUILD: 'cp*'
|
||||
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
|
||||
CIBW_TEST_REQUIRES: pytest
|
||||
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||
with:
|
||||
package-dir: bindings/python
|
||||
output-dir: wheelhouse
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
|
||||
path: ./wheelhouse/*.whl
|
||||
|
||||
make_sdist:
|
||||
name: Make SDist
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Optional, use if you use setuptools_scm
|
||||
submodules: true # Optional, use if you have submodules
|
||||
|
||||
- name: Build SDist
|
||||
run: |
|
||||
cd bindings/python
|
||||
python3 -m pip install -U pip build
|
||||
python3 -m build --sdist
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: bindings/python/dist/*.tar.gz
|
||||
|
||||
publish:
|
||||
needs: [ build_wheels_python38_only, build_wheels_all_versions, make_sdist ]
|
||||
environment: pypi
|
||||
permissions:
|
||||
id-token: write
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
merge-multiple: true
|
||||
path: dist
|
||||
|
||||
- name: Show downloaded artifacts
|
||||
run: ls -laR dist
|
||||
|
||||
- name: '📦 Publish distribution to PyPI'
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.pypi_pass }}
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -91,3 +91,9 @@ cmocka/
|
||||
zig-cache/
|
||||
zig-out/
|
||||
.cache
|
||||
|
||||
##################
|
||||
## PyCharm Project
|
||||
##################
|
||||
|
||||
.idea/
|
||||
|
||||
@@ -30,6 +30,24 @@ if(APPLE AND NOT CMAKE_C_COMPILER)
|
||||
set(CMAKE_C_COMPILER "/usr/bin/cc")
|
||||
endif()
|
||||
|
||||
# Source: https://github.com/capstone-engine/capstone/blob/next/CMakeLists.txt
|
||||
# If building for OSX it's best to allow CMake to handle building both architectures
|
||||
if(APPLE)
|
||||
# The cibuildwheel on Github Actions sets this env variable
|
||||
# with the architecture flags it wants to build for.
|
||||
if(DEFINED ENV{ARCHFLAGS})
|
||||
if("$ENV{ARCHFLAGS}" STREQUAL "-arch arm64 -arch x86_64")
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
|
||||
elseif("$ENV{ARCHFLAGS}" STREQUAL "-arch arm64")
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
||||
elseif("$ENV{ARCHFLAGS}" STREQUAL "-arch x86_64")
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64")
|
||||
endif()
|
||||
else()
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Detect if unicorn is compiled as the top-level project
|
||||
set(PROJECT_IS_TOP_LEVEL OFF)
|
||||
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
recursive-include src *
|
||||
recursive-include prebuilt *
|
||||
include LICENSE.TXT
|
||||
include README.TXT
|
||||
graft unicorn/lib
|
||||
graft unicorn/include
|
||||
global-include *.a
|
||||
global-include *.so.2
|
||||
global-include *.*lib
|
||||
global-include *.dll
|
||||
global-include *.h
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
# Unicorn
|
||||
|
||||
Unicorn is a lightweight, multi-platform, multi-architecture CPU emulator framework
|
||||
based on [QEMU](http://qemu.org).
|
||||
|
||||
Unicorn offers some unparalleled features:
|
||||
|
||||
- Multi-architecture: ARM, ARM64 (ARMv8), M68K, MIPS, PowerPC, RISCV, SPARC, S390X, TriCore and X86 (16, 32, 64-bit)
|
||||
- Clean/simple/lightweight/intuitive architecture-neutral API
|
||||
- Implemented in pure C language, with bindings for Crystal, Clojure, Visual Basic, Perl, Rust, Ruby, Python, Java, .NET, Go, Delphi/Free Pascal, Haskell, Pharo, and Lua.
|
||||
- Native support for Windows & *nix (with Mac OSX, Linux, *BSD & Solaris confirmed)
|
||||
- High performance via Just-In-Time compilation
|
||||
- Support for fine-grained instrumentation at various levels
|
||||
- Thread-safety by design
|
||||
- Distributed under free software license GPLv2
|
||||
|
||||
Further information is available at http://www.unicorn-engine.org
|
||||
|
||||
# Python Bindings for Unicorn
|
||||
|
||||
Originally written by Nguyen Anh Quynh, polished and redesigned by elicn, maintained by all community contributors.
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e -x
|
||||
|
||||
cd bindings/python
|
||||
|
||||
# Compile wheels
|
||||
python3.7 setup.py bdist_wheel $@
|
||||
cd dist
|
||||
|
||||
# We can't repair an aarch64 wheel on x64 hosts
|
||||
# https://github.com/pypa/auditwheel/issues/244
|
||||
if [[ ! "$*" =~ "aarch64" ]];then
|
||||
auditwheel repair *.whl
|
||||
mv -f wheelhouse/*.whl .
|
||||
fi
|
||||
@@ -1,9 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# TODO: use cibuildwheel
|
||||
apk update
|
||||
apk add gcc make cmake pkgconfig linux-headers git musl-dev patchelf
|
||||
|
||||
python3 -m pip install -U pip setuptools auditwheel
|
||||
|
||||
cd bindings/python && python3 setup.py bdist_wheel && auditwheel repair dist/*.whl && mv -f wheelhouse/*.whl ./dist/
|
||||
40
bindings/python/pyproject.toml
Normal file
40
bindings/python/pyproject.toml
Normal file
@@ -0,0 +1,40 @@
|
||||
[build-system]
|
||||
requires = ["setuptools", "build", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "unicorn"
|
||||
version = "2.1.1"
|
||||
requires-python = ">= 2.7, != 3.0.*, != 3.1.*, != 3.2.*, != 3.3.*, != 3.4.*, != 3.5.*, != 3.6.*"
|
||||
authors = [
|
||||
{ name = "Nguyen Anh Quynh", email = "quynh@gmail.com" },
|
||||
]
|
||||
description = "Unicorn CPU emulator engine"
|
||||
readme = "README.md"
|
||||
keywords = ["emulation", "qemu", "unicorn"]
|
||||
classifiers = [
|
||||
'License :: OSI Approved :: BSD License',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
'Programming Language :: Python :: 3.10',
|
||||
'Programming Language :: Python :: 3.11',
|
||||
'Programming Language :: Python :: 3.12',
|
||||
'Programming Language :: Python :: 3.13',
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
Homepage = "http://www.unicorn-engine.org"
|
||||
Repository = "https://github.com/unicorn-engine/unicorn"
|
||||
"Bug Tracker" = "https://github.com/unicorn-engine/unicorn/issues"
|
||||
Changelog = "https://github.com/unicorn-engine/unicorn/blob/master/ChangeLog"
|
||||
|
||||
[project.optional-dependencies]
|
||||
test = [
|
||||
"pytest",
|
||||
"pytest-cov",
|
||||
]
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
include = ["unicorn*"]
|
||||
@@ -1,31 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
python3 ./sample_arm.py
|
||||
echo "=========================="
|
||||
python3 ./sample_armeb.py
|
||||
echo "=========================="
|
||||
python3 ./sample_arm64.py
|
||||
echo "=========================="
|
||||
python3 ./sample_arm64eb.py
|
||||
echo "=========================="
|
||||
python3 ./sample_m68k.py
|
||||
echo "=========================="
|
||||
python3 ./sample_mips.py
|
||||
echo "=========================="
|
||||
python3 ./sample_ppc.py
|
||||
echo "=========================="
|
||||
python3 ./sample_riscv.py
|
||||
echo "=========================="
|
||||
python3 ./sample_s390x.py
|
||||
echo "=========================="
|
||||
python3 ./sample_sparc.py
|
||||
echo "=========================="
|
||||
python3 ./sample_tricore.py
|
||||
echo "=========================="
|
||||
python3 ./sample_x86.py
|
||||
echo "=========================="
|
||||
python3 ./shellcode.py
|
||||
echo "=========================="
|
||||
python3 ./sample_ctl.py
|
||||
echo "=========================="
|
||||
python3 ./sample_network_auditing.py
|
||||
@@ -1,2 +0,0 @@
|
||||
[bdist_wheel]
|
||||
universal=1
|
||||
@@ -1,29 +1,19 @@
|
||||
#!/usr/bin/env python
|
||||
# Python binding for Unicorn engine. Nguyen Anh Quynh <aquynh@gmail.com>
|
||||
|
||||
from __future__ import print_function
|
||||
import glob
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
import shutil
|
||||
import sys
|
||||
import platform
|
||||
import setuptools
|
||||
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from setuptools import setup
|
||||
from sysconfig import get_platform
|
||||
from setuptools.command.build import build
|
||||
from setuptools.command.sdist import sdist
|
||||
from setuptools.command.bdist_egg import bdist_egg
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
SYSTEM = sys.platform
|
||||
|
||||
# sys.maxint is 2**31 - 1 on both 32 and 64 bit mingw
|
||||
IS_64BITS = platform.architecture()[0] == '64bit'
|
||||
|
||||
# are we building from the repository or from a source distribution?
|
||||
ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||
LIBS_DIR = os.path.join(ROOT_DIR, 'unicorn', 'lib')
|
||||
@@ -32,29 +22,28 @@ SRC_DIR = os.path.join(ROOT_DIR, 'src')
|
||||
UC_DIR = SRC_DIR if os.path.exists(SRC_DIR) else os.path.join(ROOT_DIR, '../..')
|
||||
BUILD_DIR = os.path.join(UC_DIR, 'build_python')
|
||||
|
||||
VERSION = "2.1.1"
|
||||
|
||||
if SYSTEM == 'darwin':
|
||||
if sys.platform == 'darwin':
|
||||
LIBRARY_FILE = "libunicorn.2.dylib"
|
||||
STATIC_LIBRARY_FILE = "libunicorn.a"
|
||||
elif SYSTEM in ('win32', 'cygwin'):
|
||||
elif sys.platform in ('win32', 'cygwin'):
|
||||
LIBRARY_FILE = "unicorn.dll"
|
||||
STATIC_LIBRARY_FILE = "unicorn.lib"
|
||||
else:
|
||||
LIBRARY_FILE = "libunicorn.so.2"
|
||||
STATIC_LIBRARY_FILE = "libunicorn.a"
|
||||
|
||||
|
||||
def clean_bins():
|
||||
shutil.rmtree(LIBS_DIR, ignore_errors=True)
|
||||
shutil.rmtree(HEADERS_DIR, ignore_errors=True)
|
||||
|
||||
|
||||
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
|
||||
directory.
|
||||
"""
|
||||
src = []
|
||||
|
||||
shutil.rmtree(SRC_DIR, ignore_errors=True)
|
||||
os.mkdir(SRC_DIR)
|
||||
|
||||
@@ -68,15 +57,14 @@ def copy_sources():
|
||||
shutil.copytree(os.path.join(ROOT_DIR, '../../cmake'), os.path.join(SRC_DIR, 'cmake/'))
|
||||
|
||||
try:
|
||||
# remove site-specific configuration file
|
||||
# might not exist
|
||||
# remove site-specific configuration file, might not exist
|
||||
os.remove(os.path.join(SRC_DIR, 'qemu/config-host.mak'))
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
src = []
|
||||
src.extend(glob.glob(os.path.join(ROOT_DIR, "../../*.[ch]")))
|
||||
src.extend(glob.glob(os.path.join(ROOT_DIR, "../../*.mk")))
|
||||
|
||||
src.extend(glob.glob(os.path.join(ROOT_DIR, "../../LICENSE*")))
|
||||
src.extend(glob.glob(os.path.join(ROOT_DIR, "../../README.md")))
|
||||
src.extend(glob.glob(os.path.join(ROOT_DIR, "../../*.TXT")))
|
||||
@@ -87,6 +75,7 @@ def copy_sources():
|
||||
log.info("%s -> %s" % (filename, outpath))
|
||||
shutil.copy(filename, outpath)
|
||||
|
||||
|
||||
def build_libraries():
|
||||
"""
|
||||
Prepare the unicorn directory for a binary distribution or installation.
|
||||
@@ -94,7 +83,6 @@ def build_libraries():
|
||||
|
||||
Will use a src/ dir if one exists in the current directory, otherwise assumes it's in the repo
|
||||
"""
|
||||
cwd = os.getcwd()
|
||||
clean_bins()
|
||||
os.mkdir(HEADERS_DIR)
|
||||
os.mkdir(LIBS_DIR)
|
||||
@@ -102,158 +90,84 @@ def build_libraries():
|
||||
# copy public headers
|
||||
shutil.copytree(os.path.join(UC_DIR, 'include', 'unicorn'), os.path.join(HEADERS_DIR, 'unicorn'))
|
||||
|
||||
# check if a prebuilt library exists
|
||||
# if so, use it instead of building
|
||||
# check if a prebuilt library exists and if so, use it instead of building
|
||||
if os.path.exists(os.path.join(ROOT_DIR, 'prebuilt', LIBRARY_FILE)):
|
||||
shutil.copy(os.path.join(ROOT_DIR, 'prebuilt', LIBRARY_FILE), LIBS_DIR)
|
||||
if STATIC_LIBRARY_FILE is not None and os.path.exists(os.path.join(ROOT_DIR, 'prebuilt', STATIC_LIBRARY_FILE)):
|
||||
shutil.copy(os.path.join(ROOT_DIR, 'prebuilt', STATIC_LIBRARY_FILE), LIBS_DIR)
|
||||
return
|
||||
|
||||
# otherwise, build!!
|
||||
os.chdir(UC_DIR)
|
||||
|
||||
try:
|
||||
subprocess.check_call(['msbuild', '/help'])
|
||||
except:
|
||||
has_msbuild = False
|
||||
else:
|
||||
has_msbuild = True
|
||||
|
||||
if has_msbuild and SYSTEM == 'win32':
|
||||
plat = 'Win32' if platform.architecture()[0] == '32bit' else 'x64'
|
||||
conf = 'Debug' if os.getenv('DEBUG', '') else 'Release'
|
||||
# otherwise, build
|
||||
if not os.path.exists(BUILD_DIR):
|
||||
os.mkdir(BUILD_DIR)
|
||||
|
||||
subprocess.check_call(['cmake', '-B', BUILD_DIR, '-G', "Visual Studio 16 2019", "-A", plat, "-DCMAKE_BUILD_TYPE=" + conf])
|
||||
subprocess.check_call(['msbuild', 'unicorn.sln', '-m', '-p:Platform=' + plat, '-p:Configuration=' + conf], cwd=BUILD_DIR)
|
||||
has_msbuild = shutil.which('msbuild') is not None
|
||||
conf = 'Debug' if int(os.getenv('DEBUG', 0)) else 'Release'
|
||||
|
||||
if has_msbuild and sys.platform == 'win32':
|
||||
plat = 'Win32' if platform.architecture()[0] == '32bit' else 'x64'
|
||||
|
||||
subprocess.check_call(['cmake', '-B', BUILD_DIR, '-G', "Visual Studio 16 2019", "-A", plat,
|
||||
"-DCMAKE_BUILD_TYPE=" + conf], cwd=UC_DIR)
|
||||
subprocess.check_call(['msbuild', 'unicorn.sln', '-m', '-p:Platform=' + plat, '-p:Configuration=' + conf],
|
||||
cwd=BUILD_DIR)
|
||||
|
||||
obj_dir = os.path.join(BUILD_DIR, conf)
|
||||
shutil.copy(os.path.join(obj_dir, LIBRARY_FILE), LIBS_DIR)
|
||||
shutil.copy(os.path.join(BUILD_DIR, STATIC_LIBRARY_FILE), LIBS_DIR)
|
||||
else:
|
||||
# platform description refs at https://docs.python.org/2/library/sys.html#sys.platform
|
||||
if not os.path.exists(BUILD_DIR):
|
||||
os.mkdir(BUILD_DIR)
|
||||
conf = 'Debug' if os.getenv('DEBUG', '') else 'Release'
|
||||
|
||||
cmake_args = ["cmake", '-B', BUILD_DIR, '-S', UC_DIR, "-DCMAKE_BUILD_TYPE=" + conf]
|
||||
if os.getenv("TRACE", ""):
|
||||
if os.getenv("TRACE"):
|
||||
cmake_args += ["-DUNICORN_TRACER=on"]
|
||||
subprocess.check_call(cmake_args)
|
||||
os.chdir(BUILD_DIR)
|
||||
subprocess.check_call(cmake_args, cwd=UC_DIR)
|
||||
threads = os.getenv("THREADS", "4")
|
||||
subprocess.check_call(["cmake", "--build", ".", "-j" + threads])
|
||||
subprocess.check_call(["cmake", "--build", ".", "-j" + threads], cwd=BUILD_DIR)
|
||||
|
||||
shutil.copy(LIBRARY_FILE, LIBS_DIR)
|
||||
shutil.copy(STATIC_LIBRARY_FILE, LIBS_DIR)
|
||||
|
||||
os.chdir(cwd)
|
||||
shutil.copy(os.path.join(BUILD_DIR, LIBRARY_FILE), LIBS_DIR)
|
||||
shutil.copy(os.path.join(BUILD_DIR, STATIC_LIBRARY_FILE), LIBS_DIR)
|
||||
|
||||
|
||||
class custom_sdist(sdist):
|
||||
class CustomSDist(sdist):
|
||||
def run(self):
|
||||
clean_bins()
|
||||
copy_sources()
|
||||
return sdist.run(self)
|
||||
return super().run()
|
||||
|
||||
class custom_build(build):
|
||||
|
||||
class CustomBuild(build):
|
||||
def run(self):
|
||||
if 'LIBUNICORN_PATH' in os.environ:
|
||||
log.info("Skipping building C extensions since LIBUNICORN_PATH is set")
|
||||
else:
|
||||
log.info("Building C extensions")
|
||||
build_libraries()
|
||||
return build.run(self)
|
||||
return super().run()
|
||||
|
||||
class custom_bdist_egg(bdist_egg):
|
||||
|
||||
class CustomBDistEgg(bdist_egg):
|
||||
def run(self):
|
||||
self.run_command('build')
|
||||
return bdist_egg.run(self)
|
||||
return super().run()
|
||||
|
||||
def dummy_src():
|
||||
return []
|
||||
|
||||
cmdclass = {}
|
||||
cmdclass['build'] = custom_build
|
||||
cmdclass['sdist'] = custom_sdist
|
||||
cmdclass['bdist_egg'] = custom_bdist_egg
|
||||
|
||||
if 'bdist_wheel' in sys.argv and '--plat-name' not in sys.argv:
|
||||
idx = sys.argv.index('bdist_wheel') + 1
|
||||
sys.argv.insert(idx, '--plat-name')
|
||||
name = get_platform()
|
||||
if 'linux' in name:
|
||||
# linux_* platform tags are disallowed because the python ecosystem is fubar
|
||||
# linux builds should be built in the centos 5 vm for maximum compatibility
|
||||
# see https://github.com/pypa/manylinux
|
||||
# see also https://github.com/angr/angr-dev/blob/master/bdist.sh
|
||||
sys.argv.insert(idx + 1, 'manylinux1_' + platform.machine())
|
||||
elif 'mingw' in name:
|
||||
if IS_64BITS:
|
||||
sys.argv.insert(idx + 1, 'win_amd64')
|
||||
else:
|
||||
sys.argv.insert(idx + 1, 'win32')
|
||||
else:
|
||||
# https://www.python.org/dev/peps/pep-0425/
|
||||
sys.argv.insert(idx + 1, name.replace('.', '_').replace('-', '_'))
|
||||
cmdclass = {'build': CustomBuild, 'sdist': CustomSDist, 'bdist_egg': CustomBDistEgg}
|
||||
|
||||
try:
|
||||
from setuptools.command.develop import develop
|
||||
class custom_develop(develop):
|
||||
|
||||
|
||||
class CustomDevelop(develop):
|
||||
def run(self):
|
||||
log.info("Building C extensions")
|
||||
build_libraries()
|
||||
return develop.run(self)
|
||||
return super().run()
|
||||
|
||||
cmdclass['develop'] = custom_develop
|
||||
|
||||
cmdclass['develop'] = CustomDevelop
|
||||
except ImportError:
|
||||
print("Proper 'develop' support unavailable.")
|
||||
|
||||
def join_all(src, files):
|
||||
return tuple(os.path.join(src, f) for f in files)
|
||||
|
||||
long_desc = '''
|
||||
Unicorn is a lightweight, multi-platform, multi-architecture CPU emulator framework
|
||||
based on [QEMU](http://qemu.org).
|
||||
|
||||
Unicorn offers some unparalleled features:
|
||||
|
||||
- Multi-architecture: ARM, ARM64 (ARMv8), M68K, MIPS, PowerPC, RISCV, SPARC, S390X, TriCore and X86 (16, 32, 64-bit)
|
||||
- Clean/simple/lightweight/intuitive architecture-neutral API
|
||||
- Implemented in pure C language, with bindings for Crystal, Clojure, Visual Basic, Perl, Rust, Ruby, Python, Java, .NET, Go, Delphi/Free Pascal, Haskell, Pharo, and Lua.
|
||||
- Native support for Windows & *nix (with Mac OSX, Linux, *BSD & Solaris confirmed)
|
||||
- High performance via Just-In-Time compilation
|
||||
- Support for fine-grained instrumentation at various levels
|
||||
- Thread-safety by design
|
||||
- Distributed under free software license GPLv2
|
||||
|
||||
Further information is available at http://www.unicorn-engine.org
|
||||
'''
|
||||
|
||||
setup(
|
||||
provides=['unicorn'],
|
||||
packages=setuptools.find_packages(include=["unicorn", "unicorn.*"]),
|
||||
name='unicorn',
|
||||
version=VERSION,
|
||||
author='Nguyen Anh Quynh',
|
||||
author_email='aquynh@gmail.com',
|
||||
description='Unicorn CPU emulator engine',
|
||||
long_description=long_desc,
|
||||
long_description_content_type="text/markdown",
|
||||
url='http://www.unicorn-engine.org',
|
||||
classifiers=[
|
||||
'License :: OSI Approved :: BSD License',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 3',
|
||||
],
|
||||
requires=['ctypes'],
|
||||
cmdclass=cmdclass,
|
||||
zip_safe=False,
|
||||
include_package_data=True,
|
||||
is_pure=False,
|
||||
package_data={
|
||||
'unicorn': ['unicorn/py.typed', 'lib/*', 'include/unicorn/*']
|
||||
}
|
||||
has_ext_modules=lambda: True, # It's not a Pure Python wheel
|
||||
)
|
||||
|
||||
@@ -6,7 +6,6 @@ from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.arm_const import *
|
||||
|
||||
|
||||
# code to be emulated
|
||||
ARM_CODE = b"\x37\x00\xa0\xe3\x03\x10\x42\xe0" # mov r0, #0x37; sub r1, r2, r3
|
||||
THUMB_CODE = b"\x83\xb0" # sub sp, #0xc
|
||||
@@ -98,6 +97,7 @@ def test_thumb():
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
|
||||
def test_read_sctlr():
|
||||
print("Read SCTLR")
|
||||
try:
|
||||
@@ -118,6 +118,7 @@ def test_read_sctlr():
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_arm()
|
||||
print("=" * 26)
|
||||
@@ -6,7 +6,6 @@ from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.arm64_const import *
|
||||
|
||||
|
||||
# code to be emulated
|
||||
ARM64_CODE = b"\xab\x05\x00\xb8\xaf\x05\x40\x38" # str x11, [x13]; ldrb x15, [x13]
|
||||
|
||||
@@ -85,6 +84,7 @@ def test_arm64_read_sctlr():
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
|
||||
def test_arm64_hook_mrs():
|
||||
def _hook_mrs(uc, reg, cp_reg, _):
|
||||
print(f">>> Hook MRS instruction: reg = 0x{reg:x}(UC_ARM64_REG_X2) cp_reg = {cp_reg}")
|
||||
@@ -116,6 +116,7 @@ def test_arm64_hook_mrs():
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_arm64()
|
||||
print("=" * 26)
|
||||
@@ -7,7 +7,6 @@ from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.arm64_const import *
|
||||
|
||||
|
||||
# code to be emulated
|
||||
ARM64_CODE = b"\xab\x05\x00\xb8\xaf\x05\x40\x38" # str x11, [x13]; ldrb x15, [x13]
|
||||
|
||||
@@ -5,7 +5,6 @@ from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.arm_const import *
|
||||
|
||||
|
||||
# code to be emulated
|
||||
ARM_CODE = b"\xe3\xa0\x00\x37\xe0\x42\x10\x03" # mov r0, #0x37; sub r1, r2, r3
|
||||
THUMB_CODE = b"\xb0\x83" # sub sp, #0xc
|
||||
@@ -6,6 +6,7 @@ from unicorn import *
|
||||
from unicorn.x86_const import *
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
def test_uc_ctl_read():
|
||||
uc = Uc(UC_ARCH_X86, UC_MODE_32)
|
||||
|
||||
@@ -21,6 +22,7 @@ def test_uc_ctl_read():
|
||||
|
||||
print(f">>> arch={arch} mode={mode} page size={page_size} timeout={timeout}")
|
||||
|
||||
|
||||
def time_emulation(uc, start, end):
|
||||
n = datetime.now()
|
||||
|
||||
@@ -28,6 +30,7 @@ def time_emulation(uc, start, end):
|
||||
|
||||
return (datetime.now() - n).total_seconds() * 1e6
|
||||
|
||||
|
||||
def test_uc_ctl_tb_cache():
|
||||
# Initialize emulator in X86-32bit mode
|
||||
uc = Uc(UC_ARCH_X86, UC_MODE_32)
|
||||
@@ -36,7 +39,7 @@ def test_uc_ctl_tb_cache():
|
||||
# Fill the code buffer with NOP.
|
||||
code = b"\x90" * 8 * 512
|
||||
|
||||
print("Controling the TB cache in a finer granularity by uc_ctl.")
|
||||
print("Controlling the TB cache in a finer granularity by uc_ctl.")
|
||||
|
||||
uc.mem_map(addr, 0x10000)
|
||||
|
||||
@@ -49,7 +52,7 @@ def test_uc_ctl_tb_cache():
|
||||
# Now we request cache for all TBs.
|
||||
for i in range(8):
|
||||
tb = uc.ctl_request_cache(addr + i * 512)
|
||||
print(f">>> TB is cached at {hex(tb.pc)} which has {tb.icount} instructions with {tb.size} bytes")
|
||||
print(f">>> TB is cached at {hex(tb[0])} which has {tb[1]} instructions with {tb[2]} bytes")
|
||||
|
||||
# Do emulation with all TB cached.
|
||||
cached = time_emulation(uc, addr, addr + len(code))
|
||||
@@ -62,12 +65,15 @@ def test_uc_ctl_tb_cache():
|
||||
|
||||
print(f">>> Run time: First time {standard}, Cached: {cached}, Cached evicted: {evicted}")
|
||||
|
||||
|
||||
def trace_new_edge(uc, cur, prev, data):
|
||||
print(f">>> Getting a new edge from {hex(prev.pc + prev.size - 1)} to {hex(cur.pc)}")
|
||||
|
||||
|
||||
def trace_tcg_sub(uc, address, arg1, arg2, size, data):
|
||||
print(f">>> Get a tcg sub opcode at {hex(address)} with args: {arg1} and {arg2}")
|
||||
|
||||
|
||||
def test_uc_ctl_exits():
|
||||
uc = Uc(UC_ARCH_X86, UC_MODE_32)
|
||||
addr = 0x1000
|
||||
@@ -98,7 +104,7 @@ def test_uc_ctl_exits():
|
||||
|
||||
uc.ctl_set_exits(exits)
|
||||
|
||||
# This should stop at ADDRESS + 6 and increase eax, even thouhg we don't provide an exit.
|
||||
# This should stop at ADDRESS + 6 and increase eax, even though we don't provide an exit.
|
||||
uc.emu_start(addr, 0)
|
||||
|
||||
eax = uc.reg_read(UC_X86_REG_EAX)
|
||||
@@ -106,7 +112,7 @@ def test_uc_ctl_exits():
|
||||
|
||||
print(f">>> eax = {hex(eax)} and ebx = {hex(ebx)} after the first emulation")
|
||||
|
||||
# This should stop at ADDRESS + 8, even thouhg we don't provide an exit.
|
||||
# This should stop at ADDRESS + 8, even though we don't provide an exit.
|
||||
uc.emu_start(addr, 0)
|
||||
|
||||
eax = uc.reg_read(UC_X86_REG_EAX)
|
||||
@@ -114,6 +120,7 @@ def test_uc_ctl_exits():
|
||||
|
||||
print(f">>> eax = {hex(eax)} and ebx = {hex(ebx)} after the first emulation")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_uc_ctl_read()
|
||||
print("=" * 32)
|
||||
@@ -6,7 +6,6 @@ from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.m68k_const import *
|
||||
|
||||
|
||||
# code to be emulated
|
||||
M68K_CODE = b"\x76\xed" # movq #-19, %d3
|
||||
# memory address where emulation starts
|
||||
@@ -6,7 +6,6 @@ from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.mips_const import *
|
||||
|
||||
|
||||
# code to be emulated
|
||||
MIPS_CODE_EB = b"\x34\x21\x34\x56" # ori $at, $at, 0x3456;
|
||||
MIPS_CODE_EL = b"\x56\x34\x21\x34" # ori $at, $at, 0x3456;
|
||||
@@ -3,10 +3,11 @@
|
||||
# Nguyen Tan Cong <shenlongbk@gmail.com>
|
||||
|
||||
from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.x86_const import *
|
||||
import pytest
|
||||
import struct
|
||||
import uuid
|
||||
from unicorn import *
|
||||
from unicorn.x86_const import *
|
||||
|
||||
SIZE_REG = 4
|
||||
SOCKETCALL_MAX_ARGS = 3
|
||||
@@ -360,6 +361,7 @@ def hook_intr(uc, intno, user_data):
|
||||
print_sockcall(msg)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("code", [X86_SEND_ETCPASSWD, X86_BIND_TCP, X86_REVERSE_TCP, X86_REVERSE_TCP_2])
|
||||
# Test X86 32 bit
|
||||
def test_i386(code):
|
||||
global fd_chains
|
||||
@@ -1,12 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
# Sample code for PPC of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.ppc_const import *
|
||||
|
||||
|
||||
# code to be emulated
|
||||
PPC_CODE = b"\x7F\x46\x1A\x14" # add r26, r6, r3
|
||||
# memory address where emulation starts
|
||||
@@ -62,4 +60,3 @@ def test_ppc():
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_ppc()
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
# Sample code for RISCV of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.riscv_const import *
|
||||
|
||||
|
||||
'''
|
||||
$ cstool riscv64 1305100093850502
|
||||
0 13 05 10 00 addi a0, zero, 1
|
||||
@@ -68,4 +66,3 @@ def test_riscv():
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_riscv()
|
||||
|
||||
@@ -60,4 +60,3 @@ def test_s390x():
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_s390x()
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
# KaiJern Lau <kj@theshepherdlab.io>
|
||||
|
||||
from __future__ import print_function
|
||||
import pytest
|
||||
from unicorn import *
|
||||
from unicorn.x86_const import *
|
||||
|
||||
@@ -44,6 +45,7 @@ X86_CODE64 = b"\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\
|
||||
# memory address where emulation starts
|
||||
ADDRESS = 0x1000000
|
||||
|
||||
|
||||
# callback for tracing instructions
|
||||
def hook_code(uc, address, size, user_data):
|
||||
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" % (address, size))
|
||||
@@ -59,6 +61,7 @@ def hook_code(uc, address, size, user_data):
|
||||
def hook_block(uc, address, size, user_data):
|
||||
print(">>> Tracing basic block at 0x%x, block size = 0x%x" % (address, size))
|
||||
|
||||
|
||||
def read_string(uc, address):
|
||||
ret = ""
|
||||
c = uc.mem_read(address, 1)[0]
|
||||
@@ -70,6 +73,7 @@ def read_string(uc, address):
|
||||
read_bytes += 1
|
||||
return ret
|
||||
|
||||
|
||||
# callback for tracing Linux interrupt
|
||||
def hook_intr(uc, intno, user_data):
|
||||
# only handle Linux syscall
|
||||
@@ -112,6 +116,7 @@ def hook_syscall32(mu, user_data):
|
||||
print(">>> got SYSCALL with EAX = 0x%x" % (eax))
|
||||
mu.emu_stop()
|
||||
|
||||
|
||||
def hook_syscall64(mu, user_data):
|
||||
rax = mu.reg_read(UC_X86_REG_RAX)
|
||||
rdi = mu.reg_read(UC_X86_REG_RDI)
|
||||
@@ -128,6 +133,9 @@ def hook_syscall64(mu, user_data):
|
||||
|
||||
mu.emu_stop()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mode,code",
|
||||
[(UC_MODE_32, X86_CODE32_SELF), (UC_MODE_32, X86_CODE32), (UC_MODE_64, X86_CODE64)])
|
||||
# Test X86 32 bit
|
||||
def test_i386(mode, code):
|
||||
if mode == UC_MODE_32:
|
||||
@@ -171,6 +179,7 @@ def test_i386(mode, code):
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_i386(UC_MODE_32, X86_CODE32_SELF)
|
||||
print("=" * 20)
|
||||
@@ -6,7 +6,6 @@ from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.sparc_const import *
|
||||
|
||||
|
||||
# code to be emulated
|
||||
SPARC_CODE = b"\x86\x00\x40\x02" # add %g1, %g2, %g3;
|
||||
# memory address where emulation starts
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
"""
|
||||
Created for Unicorn Engine by Eric Poole <eric.poole@aptiv.com>, 2022
|
||||
Copyright 2022 Aptiv
|
||||
'''
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
from unicorn import *
|
||||
@@ -14,14 +14,17 @@ TRICORE_CODE = b"\x82\x11\xbb\x00\x00\x08" # mov d0, #0x1; mov.u d0, #0x8000
|
||||
# memory address where emulation starts
|
||||
ADDRESS = 0x10000
|
||||
|
||||
|
||||
# callback for tracing basic blocks
|
||||
def hook_block(uc, address, size, user_data):
|
||||
print(">>> Tracing basic block at 0x%x, block size = 0x%x" % (address, size))
|
||||
|
||||
|
||||
# callback for tracing instructions
|
||||
def hook_code(uc, address, size, user_data):
|
||||
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" % (address, size))
|
||||
|
||||
|
||||
# Test TriCore
|
||||
def test_tricore():
|
||||
print("Emulate TriCore code")
|
||||
@@ -53,5 +56,6 @@ def test_tricore():
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_tricore()
|
||||
@@ -2,9 +2,9 @@
|
||||
# Sample code for X86 of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
|
||||
|
||||
from __future__ import print_function
|
||||
import pickle
|
||||
from unicorn import *
|
||||
from unicorn.x86_const import *
|
||||
import pickle
|
||||
|
||||
X86_CODE32 = b"\x41\x4a\x66\x0f\xef\xc1" # INC ecx; DEC edx; PXOR xmm0, xmm1
|
||||
X86_CODE32_LOOP = b"\x41\x4a\xeb\xfe" # INC ecx; DEC edx; JMP self-loop
|
||||
@@ -33,6 +33,7 @@ def hook_code(uc, address, size, user_data):
|
||||
eflags = uc.reg_read(UC_X86_REG_EFLAGS)
|
||||
print(">>> --- EFLAGS is 0x%x" % eflags)
|
||||
|
||||
|
||||
def hook_code64(uc, address, size, user_data):
|
||||
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" % (address, size))
|
||||
rip = uc.reg_read(UC_X86_REG_RIP)
|
||||
@@ -232,6 +233,7 @@ def test_i386_invalid_mem_read():
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
|
||||
def test_i386_jump():
|
||||
print("Emulate i386 code with jump")
|
||||
try:
|
||||
@@ -322,6 +324,7 @@ def test_i386_invalid_mem_write():
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
|
||||
def test_i386_jump_invalid():
|
||||
print("Emulate i386 code that jumps to invalid memory")
|
||||
try:
|
||||
@@ -359,6 +362,7 @@ def test_i386_jump_invalid():
|
||||
except UcError as e:
|
||||
print("ERROR %s" % e)
|
||||
|
||||
|
||||
def test_i386_loop():
|
||||
print("Emulate i386 code that loop forever")
|
||||
try:
|
||||
@@ -387,6 +391,7 @@ def test_i386_loop():
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
|
||||
# Test X86 32 bit with IN/OUT instruction
|
||||
def test_i386_inout():
|
||||
print("Emulate i386 code with IN/OUT instructions")
|
||||
@@ -474,6 +479,7 @@ def test_i386_context_save():
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
|
||||
def test_x86_64():
|
||||
print("Emulate x86_64 code")
|
||||
try:
|
||||
@@ -631,14 +637,17 @@ def test_x86_16():
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
|
||||
def mmio_read_cb(uc, offset, size, data):
|
||||
print(f">>> Read IO memory at offset {hex(offset)} with {hex(size)} bytes and return 0x19260817")
|
||||
|
||||
return 0x19260817
|
||||
|
||||
|
||||
def mmio_write_cb(uc, offset, size, value, data):
|
||||
print(f">>> Write value {hex(value)} to IO memory at offset {hex(offset)} with {hex(size)} bytes")
|
||||
|
||||
|
||||
def test_i386_mmio():
|
||||
print("Test i386 IO memory")
|
||||
try:
|
||||
@@ -664,6 +673,7 @@ def test_i386_mmio():
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_x86_16()
|
||||
test_i386()
|
||||
Reference in New Issue
Block a user