mirror of
https://github.com/lifting-bits/sleigh
synced 2026-06-21 13:56:12 +00:00
Compare commits
133 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 34a699c3bd | |||
| 05e1de0a8c | |||
| 24b9034914 | |||
| f2323af0ee | |||
| c3908f6d90 | |||
| 6924bbce83 | |||
| 1c23eba9ea | |||
| 0353b200d8 | |||
| 1dcdea8701 | |||
| 76e5cb4aca | |||
| 09ba8106d6 | |||
| aa46946172 | |||
| 6e0feed91c | |||
| acabb5ffc5 | |||
| 4becc755e9 | |||
| a1a03dbd26 | |||
| 403275e36c | |||
| 98158b7ebb | |||
| e6f6d4398f | |||
| 81a04f2e1c | |||
| a0345f9df2 | |||
| 0c3b79aa33 | |||
| b4f479a86f | |||
| ee82a39842 | |||
| 71870b0bcd | |||
| b2cd7abc2e | |||
| 40d91fd61b | |||
| 67c695f263 | |||
| c4cab14295 | |||
| e46879c87f | |||
| 5d9f0a1862 | |||
| f9bbbbcdb0 | |||
| cfa08a5f9c | |||
| 7702679f9e | |||
| 8ab198294f | |||
| 064320f431 | |||
| 0ea1abe327 | |||
| 8c12126d65 | |||
| 10ad498c54 | |||
| 534adad29a | |||
| 393adb711e | |||
| fb4dec76cb | |||
| 331f4cc2b7 | |||
| 0d84e6ffb5 | |||
| f84470ac10 | |||
| 04d1204eb5 | |||
| 1c5fad6a6b | |||
| 459824f983 | |||
| ea5986827e | |||
| 393ed42fc6 | |||
| 57e6d7c79d | |||
| 8c5b8049a6 | |||
| 7b1232ec99 | |||
| f9a4905c31 | |||
| ff5929e1fc | |||
| 844e5e07fe | |||
| 51bd95f360 | |||
| f63b99a700 | |||
| f1d1eab45f | |||
| 83ae3b5dfe | |||
| 548b28c67d | |||
| f23739ee3f | |||
| c8cb034afb | |||
| 384d7de32a | |||
| d75230a7bc | |||
| 7e9641e394 | |||
| 37b2cbcf1c | |||
| 7c6b742446 | |||
| b3669ea4bd | |||
| e1562dd87f | |||
| 262f8d8421 | |||
| ef4e13d243 | |||
| 6d6335b2c5 | |||
| 6f03e21e23 | |||
| cae987f993 | |||
| c3564b1e3e | |||
| 259bccedf0 | |||
| ddfe4bff8e | |||
| 186b4fe693 | |||
| 487732a026 | |||
| 2c197599aa | |||
| 316c91ccfb | |||
| b80fefc001 | |||
| d3ca7d78d6 | |||
| 7a045dd5e8 | |||
| f12acdfd99 | |||
| 97933e2ffe | |||
| 4b225d9317 | |||
| a130f452ac | |||
| df7b7c4ff2 | |||
| ded4e6ac03 | |||
| a4e41c9b35 | |||
| 56f3346c60 | |||
| 846b99c008 | |||
| fbbd3d7fc1 | |||
| 32ae1db007 | |||
| 12a9904dfb | |||
| e9b920d618 | |||
| f38eee41a2 | |||
| c888160f53 | |||
| 82c11bea62 | |||
| 21280b4e09 | |||
| 3b53dfd6f1 | |||
| 49bb897151 | |||
| 3b1afba2dc | |||
| 1858fc7473 | |||
| c08898c9ae | |||
| 8c78874c7e | |||
| cdaf9f6cea | |||
| 8dc9ab544d | |||
| db6dd1e40b | |||
| 9966017ca0 | |||
| 1c2f67ce48 | |||
| 74838a39ba | |||
| 72d364a90f | |||
| 755f9252f1 | |||
| 0474bbdc17 | |||
| ff84f3c8de | |||
| 2aa04f941e | |||
| a057b409fa | |||
| b3e26db5c3 | |||
| 01cf5e5240 | |||
| 8a0ad2de4a | |||
| e6cfbacd67 | |||
| 66a6b7c472 | |||
| 70bbd6ce0b | |||
| 5ee2f2c162 | |||
| 08b2fdbe4b | |||
| 60f5ab437c | |||
| b8609d4673 | |||
| 52bb4a54d6 | |||
| ed9eb2e521 | |||
| c6cf5f3728 |
+94
-70
@@ -3,15 +3,15 @@ name: Build
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
- "*"
|
||||
|
||||
# Version tags should start with "v"
|
||||
tags:
|
||||
- 'v*'
|
||||
- "v*"
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
- "*"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
release: [stable, HEAD]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Git User for Applying Patches
|
||||
# See this thread for more details https://github.community/t/github-actions-bot-email-address/17204/5
|
||||
@@ -37,21 +37,7 @@ jobs:
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
clang \
|
||||
rpm \
|
||||
doxygen \
|
||||
xdot \
|
||||
graphviz
|
||||
|
||||
# Minimum supported CMake version testing
|
||||
curl -L "https://github.com/Kitware/CMake/releases/download/v3.15.0/cmake-3.15.0-Linux-$(uname -m).sh" -o /tmp/cmake-install.sh
|
||||
mkdir -p "${HOME}/.local"
|
||||
bash /tmp/cmake-install.sh --skip-license --exclude-subdir "--prefix=${HOME}/.local"
|
||||
|
||||
# Use Homebrew for latest build tool version for use in CI
|
||||
brew install \
|
||||
ccache
|
||||
sudo apt-get install -y rpm ccache doxygen graphviz xdot
|
||||
|
||||
- name: Install macOS system dependencies
|
||||
if: runner.os == 'macOS'
|
||||
@@ -65,23 +51,28 @@ jobs:
|
||||
|
||||
- name: Install Windows system dependencies
|
||||
if: runner.os == 'Windows'
|
||||
run: choco install ccache
|
||||
uses: nick-fields/retry@v3
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
command: |
|
||||
choco install ccache doxygen.install graphviz
|
||||
vcpkg install zlib:x64-windows-static
|
||||
|
||||
- name: Generate cache key
|
||||
id: cache_key
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
|
||||
message("::set-output name=VALUE::build_${{ matrix.os }}_type-${{ matrix.build_type }}-${{ matrix.release }}")
|
||||
message("::set-output name=timestamp::${current_date}")
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CACHE_KEY=build_${{ matrix.os }}_type-${{ matrix.build_type }}-${{ matrix.release }}\n")
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CACHE_TIMESTAMP=${current_date}\n")
|
||||
|
||||
- name: Update the cache (ccache)
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: "${{ github.workspace }}/ccache"
|
||||
key: ${{ steps.cache_key.outputs.VALUE }}_ccache_${{ steps.cache_key.outputs.timestamp }}
|
||||
key: ${{ env.CACHE_KEY }}_ccache_${{ env.CACHE_TIMESTAMP }}
|
||||
restore-keys: |
|
||||
${{ steps.cache_key.outputs.VALUE }}_ccache_
|
||||
${{ env.CACHE_KEY }}_ccache_
|
||||
|
||||
- name: Setup ccache
|
||||
working-directory: "${{ github.workspace }}"
|
||||
@@ -96,6 +87,9 @@ jobs:
|
||||
# This should be multiplied by the number of compilation jobs and be no
|
||||
# larger than 5G, which is the cache max size
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_MAXSIZE=400M\n")
|
||||
# Tell CMake to use ccache
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CMAKE_CXX_COMPILER_LAUNCHER=ccache\n")
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CMAKE_C_COMPILER_LAUNCHER=ccache\n")
|
||||
# Clear stats before every build
|
||||
execute_process(COMMAND ccache -z)
|
||||
|
||||
@@ -103,17 +97,10 @@ jobs:
|
||||
run: cmake --version
|
||||
|
||||
- name: Configure the project
|
||||
run: cmake
|
||||
-S .
|
||||
-B build
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache
|
||||
shell: pwsh
|
||||
run: cmake "--preset=ci-$("${{ matrix.os }}".split("-")[0])"
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
|
||||
-Dsleigh_GHIDRA_RELEASE_TYPE=${{ matrix.release }}
|
||||
-Dsleigh_ENABLE_TESTS=ON
|
||||
-Dsleigh_ENABLE_EXAMPLES=ON
|
||||
-Dsleigh_ENABLE_PACKAGING=ON
|
||||
-Dsleigh_ENABLE_DOCUMENTATION=ON
|
||||
-Dsleigh_RELEASE_TYPE=${{ matrix.release }}
|
||||
|
||||
- name: Build the project
|
||||
run: cmake
|
||||
@@ -122,25 +109,72 @@ jobs:
|
||||
-j 2
|
||||
-v
|
||||
|
||||
- name: Test the project
|
||||
working-directory: build
|
||||
run: ctest -VV -C ${{ matrix.build_type }}
|
||||
|
||||
- name: Build the docs
|
||||
run: cmake
|
||||
--build build
|
||||
--config ${{ matrix.build_type }}
|
||||
--target docs
|
||||
-v
|
||||
|
||||
- name: Run the example
|
||||
run: cmake
|
||||
--build build
|
||||
-j 2
|
||||
--config ${{ matrix.build_type }}
|
||||
--target sleighexample_runner
|
||||
--target sleigh_example_runner
|
||||
|
||||
- name: Run the install target
|
||||
run: cmake --install build
|
||||
--config ${{ matrix.build_type }}
|
||||
--prefix install
|
||||
|
||||
- name: Test install directory
|
||||
- name: Smoketest sleigh lift
|
||||
run: |
|
||||
./install/bin/sleigh-lift --version
|
||||
./install/bin/sleigh-lift disassemble x86-64.sla 4881ecc00f0000
|
||||
./install/bin/sleigh-lift pcode x86-64.sla 4881ecc00f0000
|
||||
|
||||
- name: Test install directory Unix
|
||||
if: runner.os != 'Windows'
|
||||
working-directory: tests/find_package
|
||||
run: |
|
||||
cmake -B build -S . "-Dsleigh_DIR=${{ github.workspace }}/install/lib/cmake/sleigh" -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
|
||||
cmake --build build -j 2 --config ${{ matrix.build_type }}
|
||||
cd build
|
||||
ctest -V -C ${{ matrix.build_type }}
|
||||
- name: Test install directory Windows
|
||||
if: runner.os == 'Windows'
|
||||
working-directory: tests/find_package
|
||||
run: |
|
||||
cmake -B build -S . "-Dsleigh_DIR=${{ github.workspace }}/install/lib/cmake/sleigh" -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} "-DCMAKE_TOOLCHAIN_FILE=$env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows-static
|
||||
cmake --build build -j 2 --config ${{ matrix.build_type }}
|
||||
cd build
|
||||
ctest -V -C ${{ matrix.build_type }}
|
||||
|
||||
- name: Test tool install directory Unix
|
||||
if: runner.os != 'Windows'
|
||||
working-directory: extra-tools/sleigh-lift
|
||||
run: |
|
||||
cmake -B build -S . "-Dsleigh_DIR=${{ github.workspace }}/install/lib/cmake/sleigh" -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
|
||||
cmake --build build -j 2 --config ${{ matrix.build_type }}
|
||||
cmake --install build --config ${{ matrix.build_type }} --prefix install
|
||||
./install/bin/sleigh-lift --version
|
||||
./install/bin/sleigh-lift disassemble x86-64.sla 4881ecc00f0000
|
||||
./install/bin/sleigh-lift pcode x86-64.sla 4881ecc00f0000
|
||||
- name: Test tool install directory Windows
|
||||
if: runner.os == 'Windows'
|
||||
working-directory: extra-tools/sleigh-lift
|
||||
run: |
|
||||
cmake -B build -S . "-Dsleigh_DIR=${{ github.workspace }}/install/lib/cmake/sleigh" -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} "-DCMAKE_TOOLCHAIN_FILE=$env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows-static
|
||||
cmake --build build -j 2 --config ${{ matrix.build_type }}
|
||||
cmake --install build --config ${{ matrix.build_type }} --prefix install
|
||||
./install/bin/sleigh-lift --version
|
||||
./install/bin/sleigh-lift disassemble x86-64.sla 4881ecc00f0000
|
||||
./install/bin/sleigh-lift pcode x86-64.sla 4881ecc00f0000
|
||||
|
||||
- name: Create the packages
|
||||
run: cmake
|
||||
@@ -160,71 +194,61 @@ jobs:
|
||||
- name: Locate the packages (RelWithDebInfo only)
|
||||
if: matrix.build_type == 'RelWithDebInfo'
|
||||
shell: bash
|
||||
id: package_locations
|
||||
run: |
|
||||
echo ::set-output name=DEB_PACKAGE_PATH::$(ls build/*.deb)
|
||||
echo ::set-output name=DEB_PACKAGE_NAME::$(cd build && ls *.deb)
|
||||
echo "DEB_PACKAGE_PATH=$(ls build/*.deb)" >> $GITHUB_ENV
|
||||
echo "DEB_PACKAGE_NAME=$(cd build && ls *.deb)" >> $GITHUB_ENV
|
||||
|
||||
echo ::set-output name=RPM_PACKAGE_PATH::$(ls build/*.rpm)
|
||||
echo ::set-output name=RPM_PACKAGE_NAME::$(cd build && ls *.rpm)
|
||||
echo "RPM_PACKAGE_PATH=$(ls build/*.rpm)" >> $GITHUB_ENV
|
||||
echo "RPM_PACKAGE_NAME=$(cd build && ls *.rpm)" >> $GITHUB_ENV
|
||||
|
||||
# Rename .tar.gz files for OS
|
||||
pushd build
|
||||
for f in *.tar.gz; do mv "$f" "${{ runner.os }}-$f"; done
|
||||
popd
|
||||
|
||||
echo ::set-output name=TGZ_PACKAGE_PATH::$(ls build/*.tar.gz)
|
||||
echo ::set-output name=TGZ_PACKAGE_NAME::$(cd build && ls *.tar.gz)
|
||||
echo "TGZ_PACKAGE_PATH=$(ls build/*.tar.gz)" >> $GITHUB_ENV
|
||||
echo "TGZ_PACKAGE_NAME=$(cd build && ls *.tar.gz)" >> $GITHUB_ENV
|
||||
|
||||
# DEB Package
|
||||
- name: Upload the DEB package artifact (RelWithDebInfo only)
|
||||
if: matrix.build_type == 'RelWithDebInfo' && runner.os == 'Linux'
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.package_locations.outputs.DEB_PACKAGE_NAME }}
|
||||
path: ${{ steps.package_locations.outputs.DEB_PACKAGE_PATH }}
|
||||
name: ${{ env.DEB_PACKAGE_NAME }}
|
||||
path: ${{ env.DEB_PACKAGE_PATH }}
|
||||
|
||||
- name: Release DEB package artifact (RelWithDebInfo only)
|
||||
uses: softprops/action-gh-release@v0.1.14
|
||||
uses: softprops/action-gh-release@v2.0.4
|
||||
if: matrix.build_type == 'RelWithDebInfo' && runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/') && matrix.release == 'stable'
|
||||
with:
|
||||
files: ${{ steps.package_locations.outputs.DEB_PACKAGE_PATH }}
|
||||
files: ${{ env.DEB_PACKAGE_PATH }}
|
||||
|
||||
# RPM Package
|
||||
- name: Upload the RPM package artifact (RelWithDebInfo only)
|
||||
if: matrix.build_type == 'RelWithDebInfo' && runner.os == 'Linux'
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.package_locations.outputs.RPM_PACKAGE_NAME }}
|
||||
path: ${{ steps.package_locations.outputs.RPM_PACKAGE_PATH }}
|
||||
name: ${{ env.RPM_PACKAGE_NAME }}
|
||||
path: ${{ env.RPM_PACKAGE_PATH }}
|
||||
- name: Release RPM package artifact (RelWithDebInfo only)
|
||||
uses: softprops/action-gh-release@v0.1.14
|
||||
uses: softprops/action-gh-release@v2.0.4
|
||||
if: matrix.build_type == 'RelWithDebInfo' && runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/') && matrix.release == 'stable'
|
||||
with:
|
||||
files: ${{ steps.package_locations.outputs.RPM_PACKAGE_PATH }}
|
||||
files: ${{ env.RPM_PACKAGE_PATH }}
|
||||
|
||||
# TGZ Package
|
||||
- name: Upload the TGZ package artifact (RelWithDebInfo only)
|
||||
if: matrix.build_type == 'RelWithDebInfo'
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.package_locations.outputs.TGZ_PACKAGE_NAME }}
|
||||
path: ${{ steps.package_locations.outputs.TGZ_PACKAGE_PATH }}
|
||||
name: ${{ env.TGZ_PACKAGE_NAME }}
|
||||
path: ${{ env.TGZ_PACKAGE_PATH }}
|
||||
|
||||
- name: Release TGZ package artifact (RelWithDebInfo only)
|
||||
uses: softprops/action-gh-release@v0.1.14
|
||||
uses: softprops/action-gh-release@v2.0.4
|
||||
if: matrix.build_type == 'RelWithDebInfo' && startsWith(github.ref, 'refs/tags/') && matrix.release == 'stable'
|
||||
with:
|
||||
files: ${{ steps.package_locations.outputs.TGZ_PACKAGE_PATH }}
|
||||
|
||||
# This step is down at the bottom because Windows fails but we still want
|
||||
# to upload the built binaries, regardless. We also want to see if/when
|
||||
# Windows tests start passing or are still failing, so there is no special
|
||||
# handling. GitHub Actions does not support the concept of an allowable
|
||||
# failure state
|
||||
- name: Run the tests
|
||||
working-directory: build
|
||||
run: ctest -V -C ${{ matrix.build_type }}
|
||||
files: ${{ env.TGZ_PACKAGE_PATH }}
|
||||
|
||||
- name: ccache stats
|
||||
run: ccache -s --verbose
|
||||
run: ccache -s
|
||||
|
||||
@@ -12,9 +12,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-python@v3
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
# Use oldest supported version for maximum script compatibility
|
||||
python-version: '3.7'
|
||||
@@ -23,11 +23,11 @@ jobs:
|
||||
id: head_update
|
||||
run: |
|
||||
# Sets some outputs. See next step
|
||||
python3.7 scripts/update_ghidra_head.py --ci
|
||||
python3 scripts/update_ghidra_head.py --ci
|
||||
|
||||
# Need this to run further Actions on the newly created PR
|
||||
# See here for more details https://github.com/peter-evans/create-pull-request/blob/28fa4848947e0faa7fa50647691d01477589d5e9/docs/concepts-guidelines.md#authenticating-with-github-app-generated-tokens
|
||||
- uses: tibdex/github-app-token@v1
|
||||
- uses: tibdex/github-app-token@v2
|
||||
if: steps.head_update.outputs.did_update
|
||||
id: generate-token
|
||||
with:
|
||||
@@ -36,10 +36,19 @@ jobs:
|
||||
|
||||
- name: Create PR
|
||||
if: steps.head_update.outputs.did_update
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
title: Update Ghidra HEAD to commit ${{ steps.head_update.outputs.short_sha }}
|
||||
commit-message: Bump Ghidra HEAD commit ${{ steps.head_update.outputs.short_sha }}
|
||||
commit-message: |
|
||||
Bump Ghidra HEAD commit ${{ steps.head_update.outputs.short_sha }}
|
||||
|
||||
Changed files:
|
||||
|
||||
${{ steps.head_update.outputs.changed_files }}
|
||||
body: |
|
||||
Changed files:
|
||||
|
||||
${{ steps.head_update.outputs.changed_files }}
|
||||
branch: cron/update-ghidra-${{ steps.head_update.outputs.short_sha }}
|
||||
delete-branch: true
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
|
||||
+196
-683
@@ -6,397 +6,169 @@
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
include(cmake/prelude.cmake)
|
||||
|
||||
# Sets "library_root" variable for decompiler cpp root directory
|
||||
# Sets "ghidra_version" for numeric version number
|
||||
# Use "ghidrasource_SOURCE_DIR" variable for Ghidra repo root
|
||||
include(src/setup-ghidra-source.cmake)
|
||||
set(sleigh_RELEASE_IS_HEAD FALSE)
|
||||
if("${sleigh_RELEASE_TYPE}" STREQUAL "HEAD")
|
||||
set(sleigh_RELEASE_IS_HEAD TRUE)
|
||||
endif()
|
||||
|
||||
project("sleigh"
|
||||
project(sleigh
|
||||
VERSION "${ghidra_version}"
|
||||
DESCRIPTION "Unofficial CMake build for Ghidra Sleigh"
|
||||
HOMEPAGE_URL "https://github.com/lifting-bits/sleigh"
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
include("cmake/options.cmake")
|
||||
|
||||
if(sleigh_ENABLE_TESTS)
|
||||
include("CTest")
|
||||
endif()
|
||||
|
||||
if(sleigh_ENABLE_PACKAGING)
|
||||
include("cmake/packaging.cmake")
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
message(WARNING "sleigh: Packaging a Debug version")
|
||||
endif()
|
||||
endif()
|
||||
include(cmake/project-is-top-level.cmake)
|
||||
include(cmake/options.cmake)
|
||||
|
||||
#
|
||||
# Move headers so we can prefix with "ghidra/"
|
||||
#
|
||||
set(public_include_header_list
|
||||
"${PROJECT_SOURCE_DIR}/include/libsleigh.hh"
|
||||
"${PROJECT_SOURCE_DIR}/support/Support.h"
|
||||
"${PROJECT_SOURCE_DIR}/support/Version.h"
|
||||
"${library_root}/action.hh"
|
||||
"${library_root}/address.hh"
|
||||
"${library_root}/architecture.hh"
|
||||
"${library_root}/block.hh"
|
||||
"${library_root}/blockaction.hh"
|
||||
"${library_root}/callgraph.hh"
|
||||
"${library_root}/capability.hh"
|
||||
"${library_root}/cast.hh"
|
||||
"${library_root}/codedata.hh"
|
||||
"${library_root}/comment.hh"
|
||||
"${library_root}/comment_ghidra.hh"
|
||||
"${library_root}/condexe.hh"
|
||||
"${library_root}/context.hh"
|
||||
"${library_root}/coreaction.hh"
|
||||
"${library_root}/cover.hh"
|
||||
"${library_root}/cpool.hh"
|
||||
"${library_root}/cpool_ghidra.hh"
|
||||
"${library_root}/crc32.hh"
|
||||
"${library_root}/database.hh"
|
||||
"${library_root}/database_ghidra.hh"
|
||||
"${library_root}/doccore.hh"
|
||||
"${library_root}/docmain.hh"
|
||||
"${library_root}/double.hh"
|
||||
"${library_root}/dynamic.hh"
|
||||
"${library_root}/emulate.hh"
|
||||
"${library_root}/emulateutil.hh"
|
||||
"${library_root}/error.hh"
|
||||
"${library_root}/filemanage.hh"
|
||||
"${library_root}/float.hh"
|
||||
"${library_root}/flow.hh"
|
||||
"${library_root}/fspec.hh"
|
||||
"${library_root}/funcdata.hh"
|
||||
"${library_root}/ghidra_arch.hh"
|
||||
"${library_root}/ghidra_context.hh"
|
||||
"${library_root}/ghidra_process.hh"
|
||||
"${library_root}/ghidra_translate.hh"
|
||||
"${library_root}/globalcontext.hh"
|
||||
"${library_root}/grammar.hh"
|
||||
"${library_root}/graph.hh"
|
||||
"${library_root}/heritage.hh"
|
||||
"${library_root}/ifacedecomp.hh"
|
||||
"${library_root}/ifaceterm.hh"
|
||||
"${library_root}/inject_ghidra.hh"
|
||||
"${library_root}/inject_sleigh.hh"
|
||||
"${library_root}/interface.hh"
|
||||
"${library_root}/jumptable.hh"
|
||||
"${library_root}/libdecomp.hh"
|
||||
"${library_root}/loadimage.hh"
|
||||
"${library_root}/loadimage_ghidra.hh"
|
||||
"${library_root}/loadimage_xml.hh"
|
||||
"${library_root}/memstate.hh"
|
||||
"${library_root}/merge.hh"
|
||||
"${library_root}/op.hh"
|
||||
"${library_root}/opbehavior.hh"
|
||||
"${library_root}/opcodes.hh"
|
||||
"${library_root}/options.hh"
|
||||
"${library_root}/override.hh"
|
||||
"${library_root}/paramid.hh"
|
||||
"${library_root}/partmap.hh"
|
||||
"${library_root}/pcodecompile.hh"
|
||||
"${library_root}/pcodeinject.hh"
|
||||
"${library_root}/pcodeparse.hh"
|
||||
"${library_root}/pcoderaw.hh"
|
||||
"${library_root}/prefersplit.hh"
|
||||
"${library_root}/prettyprint.hh"
|
||||
"${library_root}/printc.hh"
|
||||
"${library_root}/printjava.hh"
|
||||
"${library_root}/printlanguage.hh"
|
||||
"${library_root}/rangemap.hh"
|
||||
"${library_root}/rangeutil.hh"
|
||||
"${library_root}/raw_arch.hh"
|
||||
"${library_root}/ruleaction.hh"
|
||||
"${library_root}/rulecompile.hh"
|
||||
"${library_root}/semantics.hh"
|
||||
"${library_root}/sleigh.hh"
|
||||
"${library_root}/sleigh_arch.hh"
|
||||
"${library_root}/sleighbase.hh"
|
||||
"${library_root}/slgh_compile.hh"
|
||||
"${library_root}/slghparse.hh"
|
||||
"${library_root}/slghpatexpress.hh"
|
||||
"${library_root}/slghpattern.hh"
|
||||
"${library_root}/slghsymbol.hh"
|
||||
"${library_root}/space.hh"
|
||||
"${library_root}/string_ghidra.hh"
|
||||
"${library_root}/stringmanage.hh"
|
||||
"${library_root}/subflow.hh"
|
||||
"${library_root}/testfunction.hh"
|
||||
"${library_root}/transform.hh"
|
||||
"${library_root}/translate.hh"
|
||||
"${library_root}/type.hh"
|
||||
"${library_root}/typegrp_ghidra.hh"
|
||||
"${library_root}/typeop.hh"
|
||||
"${library_root}/types.h"
|
||||
"${library_root}/unify.hh"
|
||||
"${library_root}/userop.hh"
|
||||
"${library_root}/variable.hh"
|
||||
"${library_root}/varmap.hh"
|
||||
"${library_root}/varnode.hh"
|
||||
"${library_root}/xml.hh"
|
||||
"${library_root}/xml_arch.hh"
|
||||
"${library_root}/unionresolve.hh"
|
||||
"${library_root}/marshal.hh"
|
||||
"${library_root}/analyzesigs.hh"
|
||||
"${library_root}/modelrules.hh"
|
||||
"${library_root}/signature.hh"
|
||||
"${library_root}/signature_ghidra.hh"
|
||||
)
|
||||
if(sleigh_RELEASE_IS_HEAD)
|
||||
list(APPEND public_include_header_list
|
||||
"${library_root}/compression.hh"
|
||||
"${library_root}/slaformat.hh"
|
||||
)
|
||||
endif()
|
||||
# Create custom target so that IDEs know these files are part of the sources
|
||||
add_custom_target(sleigh_all_headers SOURCES ${public_include_header_list})
|
||||
set(public_headers_dir ${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
file(MAKE_DIRECTORY "${public_headers_dir}/sleigh")
|
||||
file(MAKE_DIRECTORY "${public_headers_dir}/ghidra")
|
||||
# Copy the public headers into our build directory so that we can control the layout.
|
||||
# Ideally, we want to let people '#include <sleigh/{header}>' without installing sleigh
|
||||
# Ideally, we want to let people '#include <ghidra/{header}>' without installing sleigh
|
||||
foreach(public_header ${public_include_header_list})
|
||||
configure_file("${public_header}" "${public_headers_dir}/sleigh" COPYONLY)
|
||||
configure_file("${public_header}" "${public_headers_dir}/ghidra" COPYONLY)
|
||||
endforeach()
|
||||
# This project also generates a helper header for managing sleigh versions.
|
||||
# We intentionally use the `sleigh` directory for this header because it's
|
||||
# not from upstream.
|
||||
configure_file(cmake/libconfig.h.in "${public_headers_dir}/sleigh/libconfig.h")
|
||||
|
||||
set(sleigh_core_source_list
|
||||
"${library_root}/xml.cc"
|
||||
"${library_root}/space.cc"
|
||||
"${library_root}/float.cc"
|
||||
"${library_root}/address.cc"
|
||||
"${library_root}/pcoderaw.cc"
|
||||
"${library_root}/translate.cc"
|
||||
"${library_root}/opcodes.cc"
|
||||
"${library_root}/globalcontext.cc"
|
||||
)
|
||||
|
||||
set(sleigh_deccore_source_list
|
||||
"${library_root}/capability.cc"
|
||||
"${library_root}/architecture.cc"
|
||||
"${library_root}/options.cc"
|
||||
"${library_root}/graph.cc"
|
||||
"${library_root}/cover.cc"
|
||||
"${library_root}/block.cc"
|
||||
"${library_root}/cast.cc"
|
||||
"${library_root}/typeop.cc"
|
||||
"${library_root}/database.cc"
|
||||
"${library_root}/cpool.cc"
|
||||
"${library_root}/comment.cc"
|
||||
"${library_root}/stringmanage.cc"
|
||||
"${library_root}/fspec.cc"
|
||||
"${library_root}/action.cc"
|
||||
"${library_root}/loadimage.cc"
|
||||
"${library_root}/grammar.cc"
|
||||
"${library_root}/varnode.cc"
|
||||
"${library_root}/op.cc"
|
||||
"${library_root}/type.cc"
|
||||
"${library_root}/variable.cc"
|
||||
"${library_root}/varmap.cc"
|
||||
"${library_root}/jumptable.cc"
|
||||
"${library_root}/emulate.cc"
|
||||
"${library_root}/emulateutil.cc"
|
||||
"${library_root}/flow.cc"
|
||||
"${library_root}/userop.cc"
|
||||
"${library_root}/funcdata.cc"
|
||||
"${library_root}/funcdata_block.cc"
|
||||
"${library_root}/funcdata_op.cc"
|
||||
"${library_root}/funcdata_varnode.cc"
|
||||
"${library_root}/pcodeinject.cc"
|
||||
"${library_root}/heritage.cc"
|
||||
"${library_root}/prefersplit.cc"
|
||||
"${library_root}/rangeutil.cc"
|
||||
"${library_root}/ruleaction.cc"
|
||||
"${library_root}/subflow.cc"
|
||||
"${library_root}/blockaction.cc"
|
||||
"${library_root}/merge.cc"
|
||||
"${library_root}/double.cc"
|
||||
"${library_root}/transform.cc"
|
||||
"${library_root}/coreaction.cc"
|
||||
"${library_root}/condexe.cc"
|
||||
"${library_root}/override.cc"
|
||||
"${library_root}/dynamic.cc"
|
||||
"${library_root}/crc32.cc"
|
||||
"${library_root}/prettyprint.cc"
|
||||
"${library_root}/printlanguage.cc"
|
||||
"${library_root}/printc.cc"
|
||||
"${library_root}/printjava.cc"
|
||||
"${library_root}/memstate.cc"
|
||||
"${library_root}/opbehavior.cc"
|
||||
"${library_root}/paramid.cc"
|
||||
)
|
||||
if("${sleigh_GHIDRA_RELEASE_TYPE}" STREQUAL "HEAD")
|
||||
list(APPEND sleigh_deccore_source_list
|
||||
"${library_root}/unionresolve.cc"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(sleigh_extra_source_list
|
||||
"${library_root}/callgraph.cc"
|
||||
"${library_root}/ifacedecomp.cc"
|
||||
"${library_root}/ifaceterm.cc"
|
||||
"${library_root}/inject_sleigh.cc"
|
||||
"${library_root}/interface.cc"
|
||||
"${library_root}/libdecomp.cc"
|
||||
"${library_root}/loadimage_xml.cc"
|
||||
"${library_root}/raw_arch.cc"
|
||||
"${library_root}/rulecompile.cc"
|
||||
"${library_root}/sleigh_arch.cc"
|
||||
"${library_root}/testfunction.cc"
|
||||
"${library_root}/unify.cc"
|
||||
"${library_root}/xml_arch.cc"
|
||||
)
|
||||
|
||||
set(sleigh_source_list
|
||||
"${library_root}/sleigh.cc"
|
||||
"${library_root}/pcodeparse.cc"
|
||||
"${library_root}/pcodecompile.cc"
|
||||
"${library_root}/sleighbase.cc"
|
||||
"${library_root}/slghsymbol.cc"
|
||||
"${library_root}/slghpatexpress.cc"
|
||||
"${library_root}/slghpattern.cc"
|
||||
"${library_root}/semantics.cc"
|
||||
"${library_root}/context.cc"
|
||||
"${library_root}/filemanage.cc"
|
||||
)
|
||||
|
||||
set(sleigh_ghidra_source_list
|
||||
"${library_root}/ghidra_arch.cc"
|
||||
"${library_root}/inject_ghidra.cc"
|
||||
"${library_root}/ghidra_translate.cc"
|
||||
"${library_root}/loadimage_ghidra.cc"
|
||||
"${library_root}/typegrp_ghidra.cc"
|
||||
"${library_root}/database_ghidra.cc"
|
||||
"${library_root}/ghidra_context.cc"
|
||||
"${library_root}/cpool_ghidra.cc"
|
||||
"${library_root}/ghidra_process.cc"
|
||||
"${library_root}/comment_ghidra.cc"
|
||||
"${library_root}/string_ghidra.cc"
|
||||
)
|
||||
|
||||
set(sleigh_slacomp_source_list
|
||||
"${library_root}/slgh_compile.cc"
|
||||
"${library_root}/slghparse.cc"
|
||||
"${library_root}/slghscan.cc"
|
||||
)
|
||||
|
||||
#
|
||||
# sleigh settings
|
||||
#
|
||||
|
||||
add_library(sleigh_settings INTERFACE)
|
||||
add_library(sleigh::sleigh_settings ALIAS sleigh_settings)
|
||||
|
||||
target_compile_features(sleigh_settings INTERFACE
|
||||
cxx_std_11
|
||||
)
|
||||
|
||||
set(sleigh_SPEC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/sleigh/specfiles/")
|
||||
set(sleigh_SPEC_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/specfiles/")
|
||||
|
||||
set_target_properties(sleigh_settings PROPERTIES
|
||||
INTERFACE_POSITION_INDEPENDENT_CODE ON
|
||||
)
|
||||
|
||||
if(sleigh_ENABLE_SANITIZERS)
|
||||
message(STATUS "sleigh: Sanitizers have been enabled")
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
message(WARNING "sleigh: Debug builds are preferred when sanitizers are enabled")
|
||||
endif()
|
||||
|
||||
set(flag_list
|
||||
-fno-omit-frame-pointer -fsanitize=undefined,address
|
||||
)
|
||||
|
||||
target_compile_options(sleigh_settings INTERFACE ${flag_list})
|
||||
target_link_options(sleigh_settings INTERFACE ${flag_list})
|
||||
endif()
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(debug_setting_list
|
||||
OPACTION_DEBUG
|
||||
MERGEMULTI_DEBUG
|
||||
BLOCKCONSISTENT_DEBUG
|
||||
DFSVERIFY_DEBUG
|
||||
)
|
||||
|
||||
foreach(debug_setting ${debug_setting_list})
|
||||
if(NOT sleigh_${debug_setting})
|
||||
continue()
|
||||
endif()
|
||||
|
||||
message(STATUS "sleigh: Enabling debug setting: sleigh_${debug_setting}")
|
||||
|
||||
target_compile_definitions(sleigh_settings INTERFACE
|
||||
${debug_setting}
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(internal_setting_list
|
||||
CPUI_STATISTICS
|
||||
CPUI_RULECOMPILE
|
||||
)
|
||||
|
||||
foreach(internal_setting ${internal_setting_list})
|
||||
if(NOT sleigh_${internal_setting})
|
||||
continue()
|
||||
endif()
|
||||
|
||||
message(STATUS "sleigh: Enabling internal setting: sleigh_${internal_setting}")
|
||||
|
||||
target_compile_definitions(sleigh_settings INTERFACE
|
||||
${internal_setting}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
#
|
||||
# decomp_opt, decomp_dbg
|
||||
#
|
||||
|
||||
add_executable(decomp_opt
|
||||
${sleigh_core_source_list}
|
||||
${sleigh_deccore_source_list}
|
||||
${sleigh_extra_source_list}
|
||||
${sleigh_source_list}
|
||||
|
||||
"${library_root}/consolemain.cc"
|
||||
)
|
||||
add_executable(sleigh::decomp_opt ALIAS decomp_opt)
|
||||
|
||||
if(NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
|
||||
target_compile_definitions(decomp_opt PRIVATE
|
||||
__TERMINAL__
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(decomp_opt PRIVATE
|
||||
sleigh::sleigh_settings
|
||||
)
|
||||
target_include_directories(decomp_opt PRIVATE $<BUILD_INTERFACE:${library_root}>)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
target_compile_definitions(decomp_opt PRIVATE
|
||||
CPUI_DEBUG
|
||||
)
|
||||
|
||||
set_target_properties(decomp_opt PROPERTIES
|
||||
OUTPUT_NAME "decomp_dbg"
|
||||
)
|
||||
# External Dependencies
|
||||
if(sleigh_RELEASE_IS_HEAD)
|
||||
find_package(ZLIB REQUIRED)
|
||||
endif()
|
||||
|
||||
#
|
||||
# ghidra_test_dbg
|
||||
# sla
|
||||
#
|
||||
|
||||
if(sleigh_ENABLE_TESTS)
|
||||
add_executable(ghidra_test_dbg
|
||||
${sleigh_core_source_list}
|
||||
${sleigh_deccore_source_list}
|
||||
${sleigh_source_list}
|
||||
${sleigh_extra_source_list}
|
||||
|
||||
"${library_root}/test.cc"
|
||||
|
||||
"${library_root}/../unittests/testcirclerange.cc"
|
||||
"${library_root}/../unittests/testfloatemu.cc"
|
||||
"${library_root}/../unittests/testtypes.cc"
|
||||
)
|
||||
|
||||
target_link_libraries(ghidra_test_dbg PRIVATE
|
||||
sleigh::sleigh_settings
|
||||
)
|
||||
target_include_directories(ghidra_test_dbg PRIVATE $<BUILD_INTERFACE:${library_root}>)
|
||||
|
||||
if(NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
|
||||
target_compile_definitions(ghidra_test_dbg PRIVATE
|
||||
__TERMINAL__
|
||||
)
|
||||
endif()
|
||||
|
||||
add_test(
|
||||
NAME ghidra_unittest_dbg
|
||||
COMMAND ghidra_test_dbg -sleighpath "${CMAKE_CURRENT_BINARY_DIR}" unittests
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME ghidra_datatest_dbg
|
||||
COMMAND ghidra_test_dbg -sleighpath "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
-path "${ghidrasource_SOURCE_DIR}/Ghidra/Features/Decompiler/src/decompile/datatests"
|
||||
datatests
|
||||
)
|
||||
endif()
|
||||
|
||||
#
|
||||
# ghidra_opt, ghidra_dbg
|
||||
#
|
||||
|
||||
add_executable(ghidra_opt
|
||||
${sleigh_core_source_list}
|
||||
${sleigh_deccore_source_list}
|
||||
${sleigh_ghidra_source_list}
|
||||
)
|
||||
add_executable(sleigh::ghidra_opt ALIAS ghidra_opt)
|
||||
|
||||
target_link_libraries(ghidra_opt PRIVATE
|
||||
sleigh::sleigh_settings
|
||||
)
|
||||
target_include_directories(ghidra_opt PRIVATE $<BUILD_INTERFACE:${library_root}>)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
target_sources(ghidra_opt PRIVATE
|
||||
"${library_root}/callgraph.cc"
|
||||
"${library_root}/ifacedecomp.cc"
|
||||
"${library_root}/ifaceterm.cc"
|
||||
"${library_root}/interface.cc"
|
||||
"${library_root}/testfunction.cc"
|
||||
)
|
||||
|
||||
target_compile_definitions(ghidra_opt PRIVATE
|
||||
CPUI_DEBUG
|
||||
)
|
||||
|
||||
set_target_properties(ghidra_opt PROPERTIES
|
||||
OUTPUT_NAME "ghidra_dbg"
|
||||
)
|
||||
endif()
|
||||
|
||||
#
|
||||
# sleigh_opt, sleigh_dbg
|
||||
#
|
||||
|
||||
add_executable(sleigh_opt
|
||||
${sleigh_core_source_list}
|
||||
${sleigh_source_list}
|
||||
${sleigh_slacomp_source_list}
|
||||
)
|
||||
add_executable(sleigh::sleigh_opt ALIAS sleigh_opt)
|
||||
|
||||
target_link_libraries(sleigh_opt PRIVATE
|
||||
sleigh::sleigh_settings
|
||||
)
|
||||
target_include_directories(sleigh_opt PRIVATE $<BUILD_INTERFACE:${library_root}>)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set_target_properties(sleigh_opt PROPERTIES
|
||||
OUTPUT_NAME "sleigh_dbg"
|
||||
)
|
||||
endif()
|
||||
|
||||
#
|
||||
# sla, sla_dbg
|
||||
#
|
||||
|
||||
add_library(sla
|
||||
add_library(sleigh_sla
|
||||
${sleigh_core_source_list}
|
||||
${sleigh_source_list}
|
||||
|
||||
@@ -406,377 +178,118 @@ add_library(sla
|
||||
"${library_root}/emulate.cc"
|
||||
"${library_root}/opbehavior.cc"
|
||||
)
|
||||
add_library(sleigh::sla ALIAS sla)
|
||||
add_library(sleigh::sla ALIAS sleigh_sla)
|
||||
|
||||
target_link_libraries(sla PUBLIC
|
||||
sleigh::sleigh_settings
|
||||
)
|
||||
target_compile_features(sleigh_sla PUBLIC cxx_std_11)
|
||||
# Private include search path '#include "..."
|
||||
target_include_directories(sla PRIVATE $<BUILD_INTERFACE:${library_root}>)
|
||||
target_include_directories(sleigh_sla PRIVATE "$<BUILD_INTERFACE:${library_root}>")
|
||||
# Public include search path in build directory
|
||||
target_include_directories(
|
||||
sla SYSTEM
|
||||
INTERFACE $<BUILD_INTERFACE:${public_headers_dir}>
|
||||
sleigh_sla SYSTEM
|
||||
INTERFACE "$<BUILD_INTERFACE:${public_headers_dir}>"
|
||||
)
|
||||
target_compile_definitions(sleigh_sla PRIVATE "$<$<CONFIG:Debug>:YYDEBUG>")
|
||||
sleigh_add_optional_defines(sleigh_sla PUBLIC)
|
||||
|
||||
set_target_properties(sleigh_sla PROPERTIES
|
||||
EXPORT_NAME sla
|
||||
OUTPUT_NAME sla
|
||||
OUTPUT_NAME_DEBUG sla_dbg
|
||||
)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
target_compile_definitions(sla PRIVATE
|
||||
YYDEBUG
|
||||
)
|
||||
|
||||
set_target_properties(sla PROPERTIES
|
||||
OUTPUT_NAME "sla_dbg"
|
||||
)
|
||||
if(sleigh_RELEASE_IS_HEAD)
|
||||
target_link_libraries(sleigh_sla PUBLIC ZLIB::ZLIB)
|
||||
endif()
|
||||
|
||||
#
|
||||
# decomp, decomp_dbg
|
||||
# decomp
|
||||
#
|
||||
|
||||
add_library(decomp
|
||||
add_library(sleigh_decomp
|
||||
${sleigh_core_source_list}
|
||||
${sleigh_deccore_source_list}
|
||||
${sleigh_extra_source_list}
|
||||
${sleigh_source_list}
|
||||
)
|
||||
add_library(sleigh::decomp ALIAS decomp)
|
||||
add_library(sleigh::decomp ALIAS sleigh_decomp)
|
||||
|
||||
target_link_libraries(decomp PUBLIC
|
||||
sleigh::sleigh_settings
|
||||
)
|
||||
target_compile_features(sleigh_decomp PUBLIC cxx_std_11)
|
||||
# Private include search path '#include "..."
|
||||
target_include_directories(decomp PRIVATE $<BUILD_INTERFACE:${library_root}>)
|
||||
target_include_directories(sleigh_decomp PRIVATE "$<BUILD_INTERFACE:${library_root}>")
|
||||
# Public include search path in build directory
|
||||
target_include_directories(
|
||||
decomp SYSTEM
|
||||
INTERFACE $<BUILD_INTERFACE:${public_headers_dir}>
|
||||
sleigh_decomp SYSTEM
|
||||
INTERFACE "$<BUILD_INTERFACE:${public_headers_dir}>"
|
||||
)
|
||||
sleigh_add_optional_defines(sleigh_decomp PUBLIC)
|
||||
|
||||
set_target_properties(sleigh_decomp PROPERTIES
|
||||
EXPORT_NAME decomp
|
||||
OUTPUT_NAME decomp
|
||||
OUTPUT_NAME_DEBUG decomp_dbg
|
||||
)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set_target_properties(decomp PROPERTIES
|
||||
OUTPUT_NAME "decomp_dbg"
|
||||
)
|
||||
if(sleigh_RELEASE_IS_HEAD)
|
||||
target_link_libraries(sleigh_decomp PUBLIC ZLIB::ZLIB)
|
||||
endif()
|
||||
|
||||
# This is the root directory where all individual processor spec file directories will be created.
|
||||
# NOTE: Needs to be defined here before the install rules
|
||||
set(spec_files_build_dir "${CMAKE_CURRENT_BINARY_DIR}/specfiles")
|
||||
|
||||
#
|
||||
# Install rules
|
||||
#
|
||||
if(NOT CMAKE_SKIP_INSTALL_RULES)
|
||||
include(cmake/install-rules.cmake)
|
||||
endif()
|
||||
|
||||
#
|
||||
# Documentation
|
||||
# Build tool projects
|
||||
#
|
||||
|
||||
if(sleigh_ENABLE_DOCUMENTATION)
|
||||
message(STATUS "sleigh: Documentation has been enabled")
|
||||
|
||||
find_package(Doxygen REQUIRED COMPONENTS dot)
|
||||
|
||||
set(documentation_output "${CMAKE_CURRENT_BINARY_DIR}/doc")
|
||||
# Always run this target because we have no source file tracking for incremental builds
|
||||
add_custom_target(sleigh_documentation
|
||||
COMMAND "${CMAKE_COMMAND}" -E remove_directory "${library_root}/../doc" "${documentation_output}"
|
||||
COMMAND Doxygen::doxygen Doxyfile
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${library_root}/../doc" "${documentation_output}"
|
||||
COMMENT "sleigh: Generating the Doxygen documentation"
|
||||
WORKING_DIRECTORY "${library_root}"
|
||||
VERBATIM
|
||||
)
|
||||
if(sleigh_BUILD_TOOLS)
|
||||
add_subdirectory(tools)
|
||||
endif()
|
||||
|
||||
#
|
||||
# Spec files
|
||||
#
|
||||
# Sets 'spec_file_list' variable
|
||||
if(NOT "${sleigh_GHIDRA_RELEASE_TYPE}" STREQUAL "HEAD")
|
||||
include(spec-files-list/spec_files_stable.cmake)
|
||||
else()
|
||||
include(spec-files-list/spec_files_HEAD.cmake)
|
||||
if(sleigh_BUILD_SLEIGHSPECS)
|
||||
add_subdirectory(sleighspecs)
|
||||
endif()
|
||||
|
||||
# This prefix should match the Ghidra repo to where the sla spec files are located
|
||||
set(spec_files_dir_prefix Ghidra/Processors)
|
||||
# This is the root directory where all individual processor spec file directories will be created
|
||||
set(spec_files_build_dir "${CMAKE_CURRENT_BINARY_DIR}/specfiles")
|
||||
# This is where we will be copying the generated artifacts for each processor
|
||||
set(spec_files_root_dir "${spec_files_build_dir}/${spec_files_dir_prefix}")
|
||||
set(spec_files_build_log_dir ${CMAKE_CURRENT_BINARY_DIR}/spec_build_logs)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${spec_files_build_log_dir}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${spec_files_build_log_dir}
|
||||
)
|
||||
|
||||
# Start processing all `.slaspec` files individually
|
||||
set(spec_targets)
|
||||
set(spec_files)
|
||||
set(spec_dirs)
|
||||
include(cmake/modules/sleighCompile.cmake)
|
||||
# Example: '<ghidra_source_prefix>/Ghidra/Processors/8051/data/languages/mx51.slaspec'
|
||||
foreach(spec_file ${spec_file_list})
|
||||
# Get 'mx51'
|
||||
get_filename_component(spec_name "${spec_file}" NAME_WLE)
|
||||
|
||||
# Get '<ghidra_source_prefix>/Ghidra/Processors/8051/data/languages'
|
||||
get_filename_component(spec_dir "${spec_file}" DIRECTORY)
|
||||
|
||||
# Get '8051/data/languages'
|
||||
file(RELATIVE_PATH spec_proc_dir
|
||||
"${ghidrasource_SOURCE_DIR}/${spec_files_dir_prefix}"
|
||||
"${spec_dir}"
|
||||
)
|
||||
|
||||
# Add relative spec processor directory for later processing
|
||||
list(APPEND spec_dirs ${spec_proc_dir})
|
||||
|
||||
# Get '8051'
|
||||
get_filename_component(proc_name "${spec_proc_dir}" DIRECTORY)
|
||||
get_filename_component(proc_name "${proc_name}" DIRECTORY)
|
||||
|
||||
set(spec_build_log "${spec_files_build_log_dir}/${spec_name}_build.log")
|
||||
# Combine back again for the build directory output like
|
||||
# '<build_prefix>/Ghidra/Processors/8051/data/languages'
|
||||
set(spec_out_dir "${spec_files_root_dir}/${spec_proc_dir}")
|
||||
# '<build_prefix>/Ghidra/Processors/8051/data/languages/mx51.sla'
|
||||
set(spec_out "${spec_out_dir}/${spec_name}.sla")
|
||||
|
||||
string(REPLACE "." "_" spec_target_name ${spec_name})
|
||||
set(spec_target "sleigh_spec_${spec_target_name}")
|
||||
|
||||
# Compile the sla file
|
||||
sleigh_compile(
|
||||
TARGET "${spec_target}"
|
||||
COMPILER "$<TARGET_FILE:sleigh::sleigh_opt>"
|
||||
SLASPEC "${spec_file}"
|
||||
LOG_FILE "${spec_build_log}"
|
||||
OUT_FILE "${spec_out}"
|
||||
)
|
||||
add_dependencies(${spec_target} sleigh_copy_${proc_name}_dir)
|
||||
|
||||
list(APPEND spec_targets ${spec_target})
|
||||
list(APPEND spec_files ${spec_out})
|
||||
endforeach()
|
||||
|
||||
# Copy and create specfile directories
|
||||
list(REMOVE_DUPLICATES spec_dirs)
|
||||
foreach(spec_dir ${spec_dirs})
|
||||
set(spec_src_dir "${ghidrasource_SOURCE_DIR}/${spec_files_dir_prefix}/${spec_dir}")
|
||||
set(spec_out_dir "${spec_files_root_dir}/${spec_dir}")
|
||||
|
||||
# Get the processor directory name
|
||||
get_filename_component(proc_name "${spec_dir}" DIRECTORY)
|
||||
get_filename_component(proc_name "${proc_name}" DIRECTORY)
|
||||
|
||||
# Copy all other files from the slaspec source directory:
|
||||
# '<ghidra_source_prefix>/Ghidra/Processors/8051/data/languages'
|
||||
# NOTE: This only copies the directory once, so you will need to remove the
|
||||
# whole directory if you update any of the other files, like '*.cspec' or
|
||||
# '*.ldef' files
|
||||
# CMake only guarantees update monitoring for files listed explicitly
|
||||
add_custom_command(
|
||||
OUTPUT "${spec_out_dir}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory "${spec_src_dir}" "${spec_out_dir}"
|
||||
)
|
||||
add_custom_target(sleigh_copy_${proc_name}_dir
|
||||
DEPENDS "${spec_out_dir}"
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# All of the sla spec targets are combined into this one
|
||||
add_custom_target(sleigh_all_sla_specs ALL DEPENDS
|
||||
${spec_targets}
|
||||
)
|
||||
|
||||
#
|
||||
# Examples
|
||||
# Included Example
|
||||
#
|
||||
|
||||
if(sleigh_ENABLE_EXAMPLES)
|
||||
add_executable(sleighexample
|
||||
"${library_root}/sleighexample.cc"
|
||||
)
|
||||
|
||||
target_link_libraries(sleighexample PRIVATE
|
||||
sleigh::sla
|
||||
sleigh::decomp
|
||||
)
|
||||
|
||||
add_custom_target(sleighexample_runner
|
||||
"${CMAKE_COMMAND}" -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/specfiles"
|
||||
COMMAND "${CMAKE_COMMAND}" -E create_symlink "${spec_files_root_dir}/x86/data/languages/x86.sla" "${CMAKE_CURRENT_BINARY_DIR}/specfiles/x86.sla"
|
||||
COMMAND sleighexample disassemble
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
|
||||
add_dependencies(
|
||||
sleighexample_runner
|
||||
sleigh_spec_x86
|
||||
)
|
||||
endif()
|
||||
|
||||
# Add support library before configuring install targets
|
||||
add_subdirectory(support)
|
||||
|
||||
#
|
||||
# Install targets
|
||||
#
|
||||
|
||||
if(NOT CMAKE_SKIP_INSTALL_RULES)
|
||||
include("GNUInstallDirs")
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
sleigh_settings
|
||||
|
||||
sla
|
||||
decomp
|
||||
support
|
||||
|
||||
decomp_opt
|
||||
ghidra_opt
|
||||
sleigh_opt
|
||||
|
||||
EXPORT
|
||||
sleighTargets
|
||||
|
||||
INCLUDES DESTINATION
|
||||
${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
${public_include_header_list}
|
||||
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_INCLUDEDIR}/sleigh
|
||||
)
|
||||
|
||||
# Install the compiled sla files found in 'Ghidra' top-level directory
|
||||
install(
|
||||
DIRECTORY
|
||||
"${spec_files_build_dir}"
|
||||
|
||||
DESTINATION
|
||||
"${CMAKE_INSTALL_DATADIR}/sleigh"
|
||||
)
|
||||
|
||||
set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/sleigh")
|
||||
|
||||
if(sleigh_ENABLE_DOCUMENTATION)
|
||||
# Build docs during install
|
||||
install(CODE
|
||||
"execute_process(
|
||||
COMMAND \"${CMAKE_COMMAND}\" --build \"${CMAKE_BINARY_DIR}\" --target sleigh_documentation
|
||||
COMMAND_ECHO STDOUT
|
||||
)"
|
||||
)
|
||||
install(
|
||||
DIRECTORY
|
||||
"${documentation_output}/html/"
|
||||
|
||||
DESTINATION
|
||||
"${CMAKE_INSTALL_DOCDIR}"
|
||||
)
|
||||
endif(sleigh_ENABLE_DOCUMENTATION)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(output_folder_path "${CMAKE_CURRENT_BINARY_DIR}/symlinks")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${output_folder_path}"
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/symlinks"
|
||||
COMMENT "sleigh: Generating symlink folder"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(sleigh_symlinks_folder_builder DEPENDS
|
||||
"${output_folder_path}"
|
||||
)
|
||||
|
||||
add_custom_target(sleigh_symlinks_builder ALL)
|
||||
|
||||
foreach(target_name "decomp"
|
||||
"ghidra"
|
||||
"sleigh")
|
||||
|
||||
set(source_name "${target_name}_dbg")
|
||||
set(destination_name "${target_name}_opt")
|
||||
set(output_path "${output_folder_path}/${destination_name}")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${output_path}"
|
||||
COMMAND "${CMAKE_COMMAND}" -E create_symlink "${source_name}" "${destination_name}"
|
||||
WORKING_DIRECTORY "${output_folder_path}"
|
||||
COMMENT "sleigh: Generating executable symlink: ${source_name} -> ${destination_name}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
set(target_name "sleigh_${source_name}_symlink_builder")
|
||||
add_custom_target("${target_name}" DEPENDS
|
||||
"${output_path}"
|
||||
)
|
||||
|
||||
add_dependencies("${target_name}"
|
||||
sleigh_symlinks_folder_builder
|
||||
)
|
||||
|
||||
add_dependencies(sleigh_symlinks_builder
|
||||
"${target_name}"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
"${output_path}"
|
||||
|
||||
DESTINATION
|
||||
"${CMAKE_INSTALL_BINDIR}"
|
||||
|
||||
PERMISSIONS
|
||||
OWNER_READ OWNER_WRITE OWNER_EXECUTE
|
||||
GROUP_READ GROUP_EXECUTE
|
||||
WORLD_READ WORLD_EXECUTE
|
||||
)
|
||||
endforeach()
|
||||
if(PROJECT_IS_TOP_LEVEL)
|
||||
include(CMakeDependentOption)
|
||||
cmake_dependent_option(sleigh_BUILD_EXAMPLE "Build included sleigh example" "${sleigh_DEVELOPER_MODE}" "sleigh_BUILD_SLEIGHSPECS" OFF)
|
||||
if(sleigh_BUILD_EXAMPLE)
|
||||
add_subdirectory(example)
|
||||
endif()
|
||||
|
||||
set(
|
||||
sleigh_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/sleigh"
|
||||
CACHE PATH "CMake package config location relative to the install prefix"
|
||||
)
|
||||
mark_as_advanced(sleigh_INSTALL_CMAKEDIR)
|
||||
|
||||
install(
|
||||
EXPORT sleighTargets
|
||||
DESTINATION "${sleigh_INSTALL_CMAKEDIR}"
|
||||
NAMESPACE sleigh::
|
||||
)
|
||||
|
||||
# Specfiles installation setup
|
||||
set(
|
||||
sleigh_INSTALL_DATADIR "${CMAKE_INSTALL_DATADIR}/sleigh"
|
||||
CACHE PATH "sleigh data installation location relative to the install prefix"
|
||||
)
|
||||
mark_as_advanced(sleigh_INSTALL_DATADIR)
|
||||
|
||||
set(sleigh_INSTALL_SPECDIR "${sleigh_INSTALL_DATADIR}/specfiles"
|
||||
CACHE PATH "sleigh specfile root destination relative to the install prefix"
|
||||
)
|
||||
mark_as_advanced(sleigh_INSTALL_SPECDIR)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
configure_package_config_file(cmake/install-config.cmake.in
|
||||
${PROJECT_BINARY_DIR}/install-config.cmake
|
||||
INSTALL_DESTINATION "${sleigh_INSTALL_CMAKEDIR}"
|
||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO
|
||||
PATH_VARS sleigh_INSTALL_SPECDIR
|
||||
)
|
||||
|
||||
install(
|
||||
FILES ${PROJECT_BINARY_DIR}/install-config.cmake
|
||||
RENAME sleighConfig.cmake
|
||||
DESTINATION "${sleigh_INSTALL_CMAKEDIR}"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES cmake/modules/sleighCompile.cmake
|
||||
DESTINATION "${sleigh_INSTALL_CMAKEDIR}/modules"
|
||||
)
|
||||
endif()
|
||||
|
||||
add_subdirectory(tools)
|
||||
#
|
||||
# Support library provided by Trail of Bits
|
||||
#
|
||||
if(sleigh_BUILD_SUPPORT)
|
||||
# Add support library before configuring install targets
|
||||
add_subdirectory(support)
|
||||
endif()
|
||||
|
||||
#
|
||||
# Extras provided by Trail of Bits
|
||||
#
|
||||
if(sleigh_BUILD_EXTRATOOLS)
|
||||
add_subdirectory(extra-tools)
|
||||
endif()
|
||||
|
||||
#
|
||||
# Developer mode
|
||||
#
|
||||
if(NOT sleigh_DEVELOPER_MODE)
|
||||
return()
|
||||
elseif(NOT PROJECT_IS_TOP_LEVEL)
|
||||
message(AUTHOR_WARNING "Developer mode is intended for developers of sleigh")
|
||||
endif()
|
||||
|
||||
include(cmake/dev-mode.cmake)
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"version": 2,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 18,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "cmake-pedantic",
|
||||
"hidden": true,
|
||||
"warnings": {
|
||||
"dev": true,
|
||||
"deprecated": true,
|
||||
"uninitialized": true,
|
||||
"unusedCli": true,
|
||||
"systemVars": false
|
||||
},
|
||||
"errors": {
|
||||
"dev": true,
|
||||
"deprecated": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-mode",
|
||||
"hidden": true,
|
||||
"inherits": "cmake-pedantic",
|
||||
"cacheVariables": {
|
||||
"sleigh_DEVELOPER_MODE": "ON",
|
||||
"sleigh_BUILD_DOCUMENTATION": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-std",
|
||||
"description": "This preset makes sure the project actually builds with at least the specified standard",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_CXX_EXTENSIONS": "OFF",
|
||||
"CMAKE_CXX_STANDARD": "11",
|
||||
"CMAKE_CXX_STANDARD_REQUIRED": "ON",
|
||||
"CMAKE_POSITION_INDEPENDENT_CODE": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-std-tools",
|
||||
"description": "This preset makes sure the project actually builds with at least the specified standard for extra sleigh tools",
|
||||
"hidden": true,
|
||||
"inherits": "ci-std",
|
||||
"cacheVariables": {
|
||||
"CMAKE_CXX_STANDARD": "17"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "flags-unix",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_CXX_FLAGS": "-Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Wcast-qual -Wshadow -Wformat=2 -Wundef"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "flags-windows",
|
||||
"description": "Note that all the flags after /W4 are required for MSVC to conform to the language standard",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_CXX_FLAGS": "/utf-8 /W4 /permissive- /volatile:iso /Zc:preprocessor /EHsc /Zc:__cplusplus /Zc:externConstexpr /Zc:throwingNew"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-unix",
|
||||
"generator": "Unix Makefiles",
|
||||
"hidden": true,
|
||||
"inherits": ["flags-unix", "ci-std"],
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-win64",
|
||||
"inherits": ["flags-windows", "ci-std"],
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"architecture": "x64",
|
||||
"cacheVariables": {
|
||||
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake",
|
||||
"VCPKG_TARGET_TRIPLET": "x64-windows-static"
|
||||
},
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"name": "coverage-unix",
|
||||
"binaryDir": "${sourceDir}/build/coverage",
|
||||
"inherits": "ci-unix",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"ENABLE_COVERAGE": "ON",
|
||||
"CMAKE_BUILD_TYPE": "Coverage",
|
||||
"CMAKE_CXX_FLAGS_COVERAGE": "-Og -g --coverage -fkeep-static-functions",
|
||||
"CMAKE_EXE_LINKER_FLAGS_COVERAGE": "--coverage",
|
||||
"CMAKE_SHARED_LINKER_FLAGS_COVERAGE": "--coverage"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-coverage",
|
||||
"inherits": ["coverage-unix", "dev-mode"],
|
||||
"cacheVariables": {
|
||||
"COVERAGE_HTML_COMMAND": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-sanitize",
|
||||
"binaryDir": "${sourceDir}/build/sanitize",
|
||||
"inherits": ["ci-unix", "dev-mode"],
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Sanitize",
|
||||
"CMAKE_CXX_FLAGS_SANITIZE": "-O2 -g -fsanitize=address,undefined -fno-omit-frame-pointer -fno-common"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-build",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"name": "ci-macos",
|
||||
"inherits": ["ci-build", "ci-unix", "dev-mode"]
|
||||
},
|
||||
{
|
||||
"name": "ci-ubuntu",
|
||||
"inherits": ["ci-build", "ci-unix", "dev-mode"]
|
||||
},
|
||||
{
|
||||
"name": "ci-windows",
|
||||
"inherits": ["ci-build", "ci-win64", "dev-mode"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
* @ekilmer @tetsuo-cpp
|
||||
@@ -1,8 +1,8 @@
|
||||
# SLEIGH Library
|
||||
# Sleigh Library
|
||||
|
||||
[SLEIGH](https://ghidra.re/courses/languages/html/sleigh.html) is a language used to describe the semantics of instruction sets of general-purpose microprocessors, with enough detail to facilitate the reverse engineering of software compiled for these architectures. It is part of the [GHIDRA reverse engineering platform](https://github.com/NationalSecurityAgency/ghidra), and underpins two of its major components: its disassembly and decompilation engines.
|
||||
[Sleigh](https://ghidra.re/courses/languages/html/sleigh.html) is a language used to describe the semantics of instruction sets of general-purpose microprocessors, with enough detail to facilitate the reverse engineering of software compiled for these architectures. It is part of the [Ghidra reverse engineering platform](https://github.com/NationalSecurityAgency/ghidra) and underpins two of its major components: its disassembly and decompilation engines.
|
||||
|
||||
This repository provides a CMake-based build project for SLEIGH so that it can be built and packaged as a standalone library, and be reused in projects other than GHIDRA.
|
||||
This repository provides a CMake-based build project for Sleigh so that it can be built and packaged as a standalone library and be reused in projects other than Ghidra.
|
||||
|
||||
## Supported Platforms
|
||||
|
||||
@@ -10,7 +10,7 @@ This repository provides a CMake-based build project for SLEIGH so that it can b
|
||||
| ---- | ------- |
|
||||
| Linux | Yes |
|
||||
| macOS | Yes |
|
||||
| Windows | Not yet |
|
||||
| Windows | Yes |
|
||||
|
||||
## Dependencies and Prerequisites
|
||||
|
||||
@@ -18,8 +18,9 @@ This repository provides a CMake-based build project for SLEIGH so that it can b
|
||||
|
||||
| Name | Version | Linux Package to Install | macOS Homebrew Package to Install |
|
||||
| ---- | ------- | ------------------------ | --------------------------------- |
|
||||
| (HEAD builds) [zlib](https://www.zlib.net/) | Recent | zlib1g-dev | zlib |
|
||||
| [Git](https://git-scm.com/) | Latest | git | N/A |
|
||||
| [CMake](https://cmake.org/) | 3.21+ | cmake | cmake |
|
||||
| [CMake](https://cmake.org/) | 3.18+ | cmake | cmake |
|
||||
|
||||
**NOTE**: This CMake project pulls the Ghidra source code from the internet during configuration. See the [note on Ghidra source code section](#note-on-ghidra-source-code) for more details.
|
||||
|
||||
@@ -32,49 +33,43 @@ For building documentation:
|
||||
| [Doxygen](https://www.doxygen.nl/) | Latest | doxygen | doxygen |
|
||||
| [GraphViz](https://graphviz.org/) | Latest | graphviz | graphviz |
|
||||
|
||||
## Build and Install the SLEIGH Library
|
||||
## Build and Install the Sleigh Library
|
||||
|
||||
```sh
|
||||
# Clone this repository (CMake project for SLEIGH)
|
||||
# Clone this repository (CMake project for sleigh)
|
||||
git clone https://github.com/lifting-bits/sleigh.git
|
||||
cd sleigh
|
||||
|
||||
# Configure CMake
|
||||
cmake -B build -S .
|
||||
|
||||
# Build SLEIGH
|
||||
cmake --build build -j
|
||||
# Build Sleigh
|
||||
cmake --build build --parallel 8
|
||||
|
||||
# Install SLEIGH
|
||||
cmake --install build --prefix <path where SLEIGH will install>
|
||||
# Install Sleigh
|
||||
cmake --install build --prefix ./install
|
||||
```
|
||||
|
||||
### Note on Ghidra source code
|
||||
|
||||
The Ghidra source code is not actually included in this git repo, and by default, CMake will automatically pull a stable version from the internet for you.
|
||||
|
||||
Please see [`src/README.md`](./src/README.md) for more information on how to customize which Ghidra source code commit will be used/compiled, including specifying your own local copy of the Ghidra source.
|
||||
Please see [`src/README.md`](src/README.md) for more information on how to customize which Ghidra source code commit will be used/compiled, including specifying your own local copy of the Ghidra source.
|
||||
|
||||
## Packaging
|
||||
|
||||
The CMake configuration also supports building packages for SLEIGH. If the `sleigh_ENABLE_PACKAGING` option is set during the configuration step, the build step will generate a tarball containing the SLEIGH installation. Additionally, the build will create an RPM package if it finds `rpm` in the `PATH` and/or a DEB package if it finds `dpkg` in the `PATH`.
|
||||
The CMake configuration also supports building packages for Sleigh.
|
||||
|
||||
For example:
|
||||
|
||||
```sh
|
||||
cmake -B build -S . \
|
||||
-Dsleigh_ENABLE_PACKAGING=ON
|
||||
|
||||
# Build SLEIGH
|
||||
cmake --build build -j
|
||||
|
||||
# Package SLEIGH
|
||||
# Package Sleigh
|
||||
cmake --build build --target package
|
||||
```
|
||||
|
||||
## API Usage
|
||||
|
||||
An example program called `sleigh-lift` has been included to demonstrate how to use the SLEIGH API. It takes a hexadecimal string of bytes and either disassembles it or lifts it to p-code. The program can be invoked like so, where the `action` argument must be either `disassemble` or `pcode`:
|
||||
An example program called `sleigh-lift` has been included to demonstrate how to use the Sleigh API. It takes a hexadecimal string of bytes and can disassemble it or lift it to p-code. The program can be invoked as follows, where the `action` argument must be either `disassemble` or `pcode`:
|
||||
|
||||
```sh
|
||||
sleigh-lift [action] [sla_file] [bytes] [-a address] [-p root_sla_dir] [-s pspec_file]
|
||||
@@ -102,11 +97,11 @@ $ sleigh-lift pcode x86-64.sla 4881ecc00f0000
|
||||
(register,0x202,1) = INT_EQUAL (unique,0x12d00,1) (const,0x0,1)
|
||||
```
|
||||
|
||||
The `sleigh_ENABLE_EXAMPLES` option must be set to `ON` during the configuration step in order to build `sleigh-lift`.
|
||||
If you do not want to build `sleigh-lift`, you must set the CMake variable `sleigh_BUILD_EXTRATOOLS` option to `OFF` during CMake configuration.
|
||||
|
||||
## Helpers
|
||||
|
||||
This repository contains a helper that is not part of SLEIGH/GHIDRA, which can be found under `support/`. It has the following signature and can help the user find the location of a given spec file on the system:
|
||||
This repository contains a helper not part of Sleigh/Ghidra, which you can find in the `support` directory. It has the following signature and can help the user find the location of a given spec file on the system:
|
||||
|
||||
```c++
|
||||
std::optional<std::filesystem::path>
|
||||
@@ -115,20 +110,24 @@ FindSpecFile(std::string_view file_name,
|
||||
gDefaultSearchPaths);
|
||||
```
|
||||
|
||||
The `sleigh::FindSpecFile` function will search the the paths provided by the user via the `search_paths` argument for a spec file with the name `file_name`. The default argument for `search_paths` is `sleigh::gDefaultSearchPaths` which contains the install/build directories that the CMake project was configured with as well as a set of common installation locations.
|
||||
The `sleigh::FindSpecFile` function will search the paths provided by the user via the `search_paths` argument for a spec file with the name `file_name`. The default argument for `search_paths` is `sleigh::gDefaultSearchPaths` which contains the install/build directories generated during CMake configuration and a set of common installation locations.
|
||||
|
||||
If you do not want to build the helpers, you must set the CMake variable `sleigh_BUILD_SUPPORT` option to `OFF` during CMake configuration.
|
||||
|
||||
## Integration as a Dependency
|
||||
|
||||
An installation of sleigh provides a CMake interface that can be used to assist in building your project.
|
||||
An installation of Sleigh provides a CMake interface that you can use when building your project.
|
||||
|
||||
An example of how to use the CMake package config file can be found in the [find_package](tests/find_package/CMakeLists.txt) example.
|
||||
You can find an example of how to use the CMake package config file in the [find_package](tests/find_package/CMakeLists.txt) example.
|
||||
|
||||
We also provide a CMake helper function [`sleigh_compile`](cmake/modules/sleighCompile.cmake) to compile your own `.slaspec` files using the installed sleigh compiler from this project.
|
||||
We also provide a CMake helper function [`sleigh_compile`](cmake/modules/sleighCompile.cmake) to compile your `.slaspec` files using a sleigh compiler.
|
||||
|
||||
Lastly, the installed compiled sleigh files can be located through the CMake variable `sleigh_INSTALL_SPECDIR`, which is an absolute path to the root directory for where the compiled sleigh files are located---you should manually inspect this to know what to expect.
|
||||
You can find a more complex CMake example with compiling Sleigh specifications in the [`example`](example/CMakeLists.txt) directory, which uses the upstream-provided sleigh example source code.
|
||||
|
||||
Referencing the [CMake config file](cmake/install-config.cmake.in) is also suggested for learning more about the exposed CMake variables and modules.
|
||||
Lastly, you can locate the installed compiled sleigh files through the CMake variable `sleigh_INSTALL_SPECDIR`, which is an absolute path to the root directory for the compiled sleigh files---you should manually inspect this to know what to expect.
|
||||
|
||||
Referencing the [CMake config file](cmake/install-config.cmake.in) and [`specfiles` CMake file](sleighspecs/specfiles.cmake.in) is also suggested for learning more about the exposed CMake variables and modules.
|
||||
|
||||
## License
|
||||
|
||||
See the LICENSE file in the top directory of this repo.
|
||||
See the [LICENSE file](LICENSE).
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# ---- Variables ----
|
||||
|
||||
# We use variables separate from what CTest uses, because those have
|
||||
# customization issues
|
||||
set(
|
||||
COVERAGE_TRACE_COMMAND
|
||||
lcov -c -q
|
||||
-o "${PROJECT_BINARY_DIR}/coverage.info"
|
||||
-d "${PROJECT_BINARY_DIR}"
|
||||
--include "${library_root}/*"
|
||||
CACHE STRING
|
||||
"; separated command to generate a trace for the 'coverage' target"
|
||||
)
|
||||
|
||||
set(
|
||||
COVERAGE_HTML_COMMAND
|
||||
genhtml --legend -f -q
|
||||
"${PROJECT_BINARY_DIR}/coverage.info"
|
||||
-p "${library_root}"
|
||||
-o "${PROJECT_BINARY_DIR}/coverage_html"
|
||||
CACHE STRING
|
||||
"; separated command to generate an HTML report for the 'coverage' target"
|
||||
)
|
||||
|
||||
# ---- Coverage target ----
|
||||
|
||||
add_custom_target(
|
||||
coverage
|
||||
COMMAND ${COVERAGE_TRACE_COMMAND}
|
||||
COMMAND ${COVERAGE_HTML_COMMAND}
|
||||
COMMENT "Generating coverage report"
|
||||
VERBATIM
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
include(CTest)
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if(sleigh_BUILD_DOCUMENTATION)
|
||||
include(cmake/docs.cmake)
|
||||
endif()
|
||||
|
||||
option(ENABLE_COVERAGE "Enable coverage support separate from CTest's" OFF)
|
||||
if(ENABLE_COVERAGE)
|
||||
include(cmake/coverage.cmake)
|
||||
endif()
|
||||
@@ -0,0 +1,11 @@
|
||||
find_package(Doxygen REQUIRED COMPONENTS dot)
|
||||
|
||||
# Always run this target because we have no source file tracking for incremental builds
|
||||
add_custom_target(docs
|
||||
COMMAND "${CMAKE_COMMAND}" -E remove_directory "${DOXYGEN_OUTPUT_DIRECTORY}/html"
|
||||
COMMAND Doxygen::doxygen Doxyfile
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${library_root}/../doc" "${DOXYGEN_OUTPUT_DIRECTORY}"
|
||||
COMMENT "sleigh: Generating the Doxygen documentation"
|
||||
WORKING_DIRECTORY "${library_root}"
|
||||
VERBATIM
|
||||
)
|
||||
@@ -1,9 +1,56 @@
|
||||
#
|
||||
# Copyright (c) 2022-present, Trail of Bits, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed in accordance with the terms specified in
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
# This file provides access to the installed sleigh targets.
|
||||
#
|
||||
# There are optional components that could also be installed:
|
||||
# * Specs - Compiled sleigh specification files
|
||||
# * Support - Support library for easier use of sleigh
|
||||
# * ExtraTools - Extra tools created by Trail of Bits
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
# Extra version details. Either 'stable' or 'HEAD'
|
||||
set(sleigh_RELEASE_IS_HEAD "@sleigh_RELEASE_IS_HEAD@")
|
||||
if(sleigh_RELEASE_IS_HEAD)
|
||||
include(CMakeFindDependencyMacro)
|
||||
find_dependency(ZLIB)
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/sleighTargets.cmake")
|
||||
|
||||
# Path relative-root to reach installed specfiles directory
|
||||
set_and_check(sleigh_INSTALL_SPECDIR "@PACKAGE_sleigh_INSTALL_SPECDIR@")
|
||||
|
||||
# Helpers exposed by default when finding sleigh
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/modules/sleighCompile.cmake")
|
||||
|
||||
# Find-package component handling for Support library and ExtraTools
|
||||
set(_sleigh_supported_components Specs Support ExtraTools)
|
||||
|
||||
# Specs just sets a variable to the directory of installation
|
||||
set(_sleigh_Specs_targets "${CMAKE_CURRENT_LIST_DIR}/specfiles.cmake")
|
||||
set(_sleigh_Support_targets "${CMAKE_CURRENT_LIST_DIR}/sleighSupportTargets.cmake")
|
||||
set(_sleigh_ExtraTools_targets "${CMAKE_CURRENT_LIST_DIR}/sleighExtraToolsTargets.cmake")
|
||||
|
||||
macro(sleigh_load_component comp)
|
||||
if(NOT EXISTS "${_sleigh_${comp}_targets}" AND ${sleigh_FIND_REQUIRED_${comp}})
|
||||
set(sleigh_NOT_FOUND_MESSAGE
|
||||
"sleigh `${comp}` component targets were requested but not found.")
|
||||
set(sleigh_FOUND FALSE)
|
||||
return()
|
||||
endif()
|
||||
if(EXISTS "${_sleigh_${comp}_targets}")
|
||||
include("${_sleigh_${comp}_targets}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
foreach(_comp ${sleigh_FIND_COMPONENTS})
|
||||
if (NOT _comp IN_LIST _sleigh_supported_components)
|
||||
set(sleigh_FOUND FALSE)
|
||||
set(sleigh_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}")
|
||||
endif()
|
||||
sleigh_load_component("${_comp}")
|
||||
endforeach()
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
#
|
||||
# Copyright (c) 2022-present, Trail of Bits, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed in accordance with the terms specified in
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
if(PROJECT_IS_TOP_LEVEL)
|
||||
set(CMAKE_INSTALL_INCLUDEDIR include/sleigh CACHE PATH "")
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
sleigh_sla
|
||||
sleigh_decomp
|
||||
EXPORT
|
||||
sleighTargets
|
||||
RUNTIME #
|
||||
COMPONENT sleigh_Runtime
|
||||
LIBRARY #
|
||||
COMPONENT sleigh_Runtime
|
||||
NAMELINK_COMPONENT sleigh_Development
|
||||
ARCHIVE #
|
||||
COMPONENT sleigh_Development
|
||||
INCLUDES DESTINATION
|
||||
"${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY "${public_headers_dir}/"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
COMPONENT sleigh_Development
|
||||
)
|
||||
|
||||
if(sleigh_BUILD_DOCUMENTATION)
|
||||
install(
|
||||
DIRECTORY "${DOXYGEN_OUTPUT_DIRECTORY}/html/"
|
||||
DESTINATION "${CMAKE_INSTALL_DOCDIR}"
|
||||
COMPONENT sleigh_Documentation
|
||||
)
|
||||
endif()
|
||||
|
||||
set(
|
||||
sleigh_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/sleigh"
|
||||
CACHE PATH "CMake package config location relative to the install prefix"
|
||||
)
|
||||
mark_as_advanced(sleigh_INSTALL_CMAKEDIR)
|
||||
|
||||
install(
|
||||
EXPORT sleighTargets
|
||||
DESTINATION "${sleigh_INSTALL_CMAKEDIR}"
|
||||
NAMESPACE sleigh::
|
||||
COMPONENT sleigh_Development
|
||||
)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
write_basic_package_version_file(
|
||||
"sleighConfigVersion.cmake"
|
||||
COMPATIBILITY SameMinorVersion
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${PROJECT_BINARY_DIR}/sleighConfigVersion.cmake"
|
||||
DESTINATION "${sleigh_INSTALL_CMAKEDIR}"
|
||||
COMPONENT sleigh_Development
|
||||
)
|
||||
|
||||
configure_package_config_file(cmake/install-config.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/install-config.cmake"
|
||||
INSTALL_DESTINATION "${sleigh_INSTALL_CMAKEDIR}"
|
||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${PROJECT_BINARY_DIR}/install-config.cmake"
|
||||
RENAME sleighConfig.cmake
|
||||
DESTINATION "${sleigh_INSTALL_CMAKEDIR}"
|
||||
COMPONENT sleigh_Development
|
||||
)
|
||||
|
||||
install(
|
||||
FILES cmake/modules/sleighCompile.cmake
|
||||
DESTINATION "${sleigh_INSTALL_CMAKEDIR}/modules"
|
||||
COMPONENT sleigh_Development
|
||||
)
|
||||
|
||||
if(PROJECT_IS_TOP_LEVEL)
|
||||
include(cmake/packaging.cmake)
|
||||
endif()
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
Copyright (c) 2022-present, Trail of Bits, Inc.
|
||||
All rights reserved.
|
||||
|
||||
This source code is licensed in accordance with the terms specified in
|
||||
the LICENSE file found in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#ifndef SLEIGH_LIBCONFIG_H
|
||||
#define SLEIGH_LIBCONFIG_H
|
||||
|
||||
#cmakedefine sleigh_RELEASE_IS_HEAD
|
||||
#cmakedefine sleigh_VERSION "@sleigh_VERSION@"
|
||||
#cmakedefine sleigh_VERSION_MAJOR @sleigh_VERSION_MAJOR@
|
||||
#cmakedefine sleigh_VERSION_MINOR @sleigh_VERSION_MINOR@
|
||||
#cmakedefine sleigh_VERSION_PATCH @sleigh_VERSION_PATCH@
|
||||
#cmakedefine sleigh_VERSION_TWEAK @sleigh_VERSION_TWEAK@
|
||||
|
||||
#endif
|
||||
@@ -6,7 +6,7 @@
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
# Takes the following required arguments:
|
||||
#
|
||||
|
||||
+28
-18
@@ -6,27 +6,35 @@
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
option(sleigh_ENABLE_TESTS "Set to true to enable tests" ON)
|
||||
option(sleigh_ENABLE_EXAMPLES "Set to true to build examples" ON)
|
||||
option(sleigh_ENABLE_DOCUMENTATION "Set to true to enable the documentation")
|
||||
option(sleigh_ENABLE_PACKAGING "Set to true to enable packaging")
|
||||
option(sleigh_ENABLE_SANITIZERS "Set to true to enable sanitizers")
|
||||
# ---- Developer mode ----
|
||||
|
||||
# Internal debug settings
|
||||
option(sleigh_OPACTION_DEBUG "Turns on all the action tracing facilities")
|
||||
option(sleigh_MERGEMULTI_DEBUG "Check for MULTIEQUAL and INDIRECT intersections")
|
||||
option(sleigh_BLOCKCONSISTENT_DEBUG "Check that block graph structure is consistent")
|
||||
option(sleigh_DFSVERIFY_DEBUG "Make sure that the block ordering algorithm produces a true depth first traversal of the dominator tree")
|
||||
|
||||
# Additional internal settings
|
||||
option(sleigh_CPUI_STATISTICS "Turn on collection of cover and cast statistics")
|
||||
option(sleigh_CPUI_RULECOMPILE "Allow user defined dynamic rules")
|
||||
|
||||
# Sanity checking
|
||||
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(sleigh_ENABLE_DOCUMENTATION OFF CACHE BOOL "Unsupported on Windows" FORCE)
|
||||
# Developer mode enables targets and code paths in the CMake scripts that are
|
||||
# only relevant for the developer(s) of sleigh
|
||||
# Targets necessary to build the project must be provided unconditionally, so
|
||||
# consumers can trivially build and package the project
|
||||
if(PROJECT_IS_TOP_LEVEL)
|
||||
option(sleigh_DEVELOPER_MODE "Enable developer mode")
|
||||
option(BUILD_SHARED_LIBS "Build shared libs. (Untested and not supported)")
|
||||
endif()
|
||||
|
||||
if(sleigh_DEVELOPER_MODE)
|
||||
option(sleigh_BUILD_DOCUMENTATION "Build documentation using Doxygen")
|
||||
set(
|
||||
DOXYGEN_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/docs"
|
||||
CACHE PATH "Path for the generated Doxygen documentation"
|
||||
)
|
||||
endif()
|
||||
|
||||
include(CMakeDependentOption)
|
||||
|
||||
# Optional project target building
|
||||
option(sleigh_BUILD_TOOLS "Build and install executable tools" "${PROJECT_IS_TOP_LEVEL}")
|
||||
option(sleigh_BUILD_SLEIGHSPECS "Build and install sleigh spec files" "${PROJECT_IS_TOP_LEVEL}")
|
||||
|
||||
# Add-ons by ToB
|
||||
option(sleigh_BUILD_SUPPORT "Build ToB support libraries" "${PROJECT_IS_TOP_LEVEL}")
|
||||
cmake_dependent_option(sleigh_BUILD_EXTRATOOLS "Build extra ToB sleigh tools" "${PROJECT_IS_TOP_LEVEL}" "sleigh_BUILD_SUPPORT" OFF)
|
||||
|
||||
# ---- Warning guard ----
|
||||
|
||||
# target_include_directories with the SYSTEM modifier will request the compiler
|
||||
@@ -34,12 +42,14 @@ endif()
|
||||
# This is to provide a user experience similar to find_package when
|
||||
# add_subdirectory or FetchContent is used to consume this project
|
||||
set(warning_guard "")
|
||||
|
||||
if(NOT PROJECT_IS_TOP_LEVEL)
|
||||
option(sleigh_INCLUDES_WITH_SYSTEM
|
||||
"Use SYSTEM modifier for sleigh's includes, disabling warnings"
|
||||
ON
|
||||
)
|
||||
mark_as_advanced(sleigh_INCLUDES_WITH_SYSTEM)
|
||||
|
||||
if(sleigh_INCLUDES_WITH_SYSTEM)
|
||||
set(warning_guard SYSTEM)
|
||||
endif()
|
||||
|
||||
+27
-30
@@ -7,48 +7,45 @@
|
||||
#
|
||||
|
||||
set(PACKAGE_VERSION 1)
|
||||
if("${sleigh_GHIDRA_RELEASE_TYPE}" STREQUAL "HEAD")
|
||||
if("${sleigh_RELEASE_TYPE}" STREQUAL "HEAD")
|
||||
set(PACKAGE_VERSION "DEV.${ghidra_short_commit}")
|
||||
endif()
|
||||
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "SLEIGH was designed for the GHIDRA reverse engineering platform built by the National Security Agency and is used to describe microprocessors with enough detail to facilitate two major components of GHIDRA, the disassembly and decompilation engines. This is an unofficial release by Trail of Bits.")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Sleigh was designed for the Ghidra reverse engineering platform built by the National Security Agency and is used to describe microprocessors with enough detail to facilitate two major components of Ghidra, the disassembly and decompilation engines. This is an unofficial release by Trail of Bits.")
|
||||
set(CPACK_PACKAGE_NAME "sleigh")
|
||||
set(CPACK_PACKAGE_VENDOR "Trail of Bits")
|
||||
set(CPACK_PACKAGE_CONTACT "info@trailofbits.com")
|
||||
set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/lifting-bits/sleigh")
|
||||
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}-${PACKAGE_VERSION}.x86_64")
|
||||
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}-${PACKAGE_VERSION}.${CMAKE_SYSTEM_PROCESSOR}")
|
||||
set(CPACK_PACKAGE_RELOCATABLE ON)
|
||||
|
||||
set(CPACK_DEBIAN_PACKAGE_RELEASE "${PACKAGE_VERSION}")
|
||||
set(CPACK_DEBIAN_PACKAGE_PRIORITY "extra")
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION "default")
|
||||
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "${CPACK_PACKAGE_HOMEPAGE_URL}")
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc-dev-bin (>=2.31)")
|
||||
|
||||
set(CPACK_RPM_PACKAGE_RELEASE_DIST "${PACKAGE_VERSION}")
|
||||
set(CPACK_RPM_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
|
||||
set(CPACK_RPM_PACKAGE_GROUP "default")
|
||||
set(CPACK_RPM_PACKAGE_REQUIRES "glibc >= 2.31")
|
||||
|
||||
set(CPACK_GENERATOR "TGZ")
|
||||
|
||||
unset(rpm_executable_path CACHE)
|
||||
find_program(rpm_executable_path "rpm")
|
||||
if("${rpm_executable_path}" STREQUAL "rpm_executable_path-NOTFOUND")
|
||||
message(WARNING "sleigh: the RPM package generator requires the 'rpm' tool")
|
||||
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
|
||||
unset(rpm_executable_path CACHE)
|
||||
find_program(rpm_executable_path "rpm")
|
||||
if("${rpm_executable_path}" STREQUAL "rpm_executable_path-NOTFOUND")
|
||||
message(WARNING "sleigh: the RPM package generator requires the 'rpm' tool")
|
||||
else()
|
||||
list(APPEND CPACK_GENERATOR "RPM")
|
||||
message(STATUS "sleigh: the RPM generator has been enabled")
|
||||
endif()
|
||||
set(CPACK_RPM_PACKAGE_RELEASE_DIST "${PACKAGE_VERSION}")
|
||||
set(CPACK_RPM_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
|
||||
set(CPACK_RPM_PACKAGE_GROUP "default")
|
||||
|
||||
else()
|
||||
list(APPEND CPACK_GENERATOR "RPM")
|
||||
message(STATUS "sleigh: the RPM generator has been enabled")
|
||||
endif()
|
||||
|
||||
unset(dpkg_executable_path CACHE)
|
||||
find_program(dpkg_executable_path "dpkg")
|
||||
if("${dpkg_executable_path}" STREQUAL "dpkg_executable_path-NOTFOUND")
|
||||
message(WARNING "sleigh: the DEB package generator requires the 'dpkg' tool")
|
||||
else()
|
||||
list(APPEND CPACK_GENERATOR "DEB")
|
||||
message(STATUS "sleigh: the DEB generator has been enabled")
|
||||
unset(dpkg_executable_path CACHE)
|
||||
find_program(dpkg_executable_path "dpkg")
|
||||
if("${dpkg_executable_path}" STREQUAL "dpkg_executable_path-NOTFOUND")
|
||||
message(WARNING "sleigh: the DEB package generator requires the 'dpkg' tool")
|
||||
else()
|
||||
list(APPEND CPACK_GENERATOR "DEB")
|
||||
message(STATUS "sleigh: the DEB generator has been enabled")
|
||||
endif()
|
||||
set(CPACK_DEBIAN_PACKAGE_RELEASE "${PACKAGE_VERSION}")
|
||||
set(CPACK_DEBIAN_PACKAGE_PRIORITY "extra")
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION "default")
|
||||
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "${CPACK_PACKAGE_HOMEPAGE_URL}")
|
||||
endif()
|
||||
|
||||
include(CPack)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# ---- In-source guard ----
|
||||
|
||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"In-source builds are not supported. "
|
||||
"Please read the documentation before trying to build this project. "
|
||||
"You may need to delete 'CMakeCache.txt' and 'CMakeFiles/' first."
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,6 @@
|
||||
# This variable is set by project() in CMake 3.21+
|
||||
string(
|
||||
COMPARE EQUAL
|
||||
"${CMAKE_SOURCE_DIR}" "${PROJECT_SOURCE_DIR}"
|
||||
PROJECT_IS_TOP_LEVEL
|
||||
)
|
||||
@@ -0,0 +1,115 @@
|
||||
#
|
||||
# Copyright (c) 2022-present, Trail of Bits, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed in accordance with the terms specified in
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
include(../cmake/prelude.cmake)
|
||||
|
||||
# We include this because the source code for this example is in upstream
|
||||
include(../src/setup-ghidra-source.cmake)
|
||||
|
||||
project(sleigh_example
|
||||
VERSION "${ghidra_version}"
|
||||
DESCRIPTION "Sleigh example"
|
||||
HOMEPAGE_URL "https://github.com/lifting-bits/sleigh"
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
include(../cmake/project-is-top-level.cmake)
|
||||
|
||||
if(NOT TARGET sleigh::sla)
|
||||
find_package(sleigh)
|
||||
if(NOT sleigh_FOUND)
|
||||
message(WARNING "Could not find sleigh library, building from source")
|
||||
# Exclude from all because there are no install rules for the example
|
||||
# See sleigh-lift for example with install rules
|
||||
add_subdirectory(.. sleigh EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_executable(sleigh_example
|
||||
"${library_root}/sleighexample.cc"
|
||||
)
|
||||
|
||||
target_compile_features(sleigh_example PRIVATE cxx_std_11)
|
||||
sleigh_add_optional_defines(sleigh_example PRIVATE)
|
||||
target_link_libraries(sleigh_example PRIVATE
|
||||
sleigh::sla
|
||||
)
|
||||
|
||||
set_target_properties(sleigh_example PROPERTIES
|
||||
OUTPUT_NAME sleighexample
|
||||
)
|
||||
|
||||
#
|
||||
# Compile our required sleigh spec file
|
||||
#
|
||||
# Get the native machine's sleigh compiler or use the one we're about to build
|
||||
# if not cross compiling
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
find_program(
|
||||
SLEIGH_EXECUTABLE sleigh
|
||||
DOC "Path to host system sleigh compiler"
|
||||
REQUIRED
|
||||
)
|
||||
set(sleigh_compiler "${SLEIGH_EXECUTABLE}")
|
||||
else()
|
||||
# Try to find/acquire or bootstrap the sleigh spec compiler
|
||||
# Logic is repeated in sleighspecs/CMakeLists.txt
|
||||
if(NOT TARGET sleigh::sleigh)
|
||||
find_package(sleigh QUIET)
|
||||
if(NOT sleigh_FOUND OR NOT TARGET sleigh::sleigh)
|
||||
find_program(
|
||||
SLEIGH_EXECUTABLE sleigh
|
||||
DOC "Path to host system sleigh compiler"
|
||||
)
|
||||
if(NOT SLEIGH_EXECUTABLE)
|
||||
message(WARNING "Could not find sleigh compiler, building from source")
|
||||
set(saved_skip_install_rules "${CMAKE_SKIP_INSTALL_RULES}")
|
||||
set(CMAKE_SKIP_INSTALL_RULES TRUE)
|
||||
add_subdirectory(../tools/spec-compiler spec-compiler EXCLUDE_FROM_ALL)
|
||||
set(CMAKE_SKIP_INSTALL_RULES "${saved_skip_install_rules}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(SLEIGH_EXECUTABLE)
|
||||
set(sleigh_compiler "${SLEIGH_EXECUTABLE}")
|
||||
else()
|
||||
set(sleigh_compiler "$<TARGET_FILE:sleigh::sleigh>")
|
||||
endif()
|
||||
|
||||
# Compile the sla file
|
||||
include(../cmake/modules/sleighCompile.cmake)
|
||||
|
||||
sleigh_compile(
|
||||
TARGET sleigh_example_sleigh_spec_x86
|
||||
COMPILER "${sleigh_compiler}"
|
||||
SLASPEC "${ghidrasource_SOURCE_DIR}/Ghidra/Processors/x86/data/languages/x86.slaspec"
|
||||
LOG_FILE "${CMAKE_CURRENT_BINARY_DIR}/specfiles/x86.sla.log"
|
||||
OUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/specfiles/x86.sla"
|
||||
)
|
||||
set_property(
|
||||
TARGET sleigh_example_sleigh_spec_x86
|
||||
PROPERTY EXCLUDE_FROM_ALL FALSE
|
||||
)
|
||||
|
||||
#
|
||||
# Run the example
|
||||
#
|
||||
add_custom_target(sleigh_example_runner)
|
||||
set(example_actions disassemble pcode emulate)
|
||||
foreach(action ${example_actions})
|
||||
add_custom_target(sleigh_example_${action}
|
||||
COMMAND sleigh_example ${action}
|
||||
COMMENT "Running example ${action}"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
add_dependencies(sleigh_example_${action} sleigh_example_sleigh_spec_x86)
|
||||
add_dependencies(sleigh_example_runner sleigh_example_${action})
|
||||
endforeach()
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# Copyright (c) 2022-present, Trail of Bits, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed in accordance with the terms specified in
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
add_subdirectory(sleigh-lift)
|
||||
@@ -0,0 +1,63 @@
|
||||
#
|
||||
# Copyright (c) 2021-present, Trail of Bits, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed in accordance with the terms specified in
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
project(sleighLift CXX)
|
||||
|
||||
set(build_from_source FALSE)
|
||||
if(NOT TARGET sleigh::support)
|
||||
find_package(sleigh)
|
||||
if(NOT sleigh_FOUND)
|
||||
message(WARNING "Could not find sleigh, building from source")
|
||||
set(sleigh_BUILD_SUPPORT ON CACHE BOOL "" FORCE)
|
||||
set(sleigh_BUILD_SLEIGHSPECS ON CACHE BOOL "" FORCE)
|
||||
add_subdirectory(../.. sleigh)
|
||||
else()
|
||||
find_package(sleigh REQUIRED COMPONENTS Support Specs)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_executable(sleigh_lift
|
||||
src/main.cpp
|
||||
)
|
||||
add_executable(sleigh::lift ALIAS sleigh_lift)
|
||||
|
||||
target_link_libraries(sleigh_lift PRIVATE
|
||||
sleigh::sla
|
||||
sleigh::decomp
|
||||
sleigh::support
|
||||
)
|
||||
target_compile_features(sleigh_lift PRIVATE cxx_std_17)
|
||||
set_target_properties(sleigh_lift PROPERTIES
|
||||
EXPORT_NAME lift
|
||||
OUTPUT_NAME sleigh-lift
|
||||
)
|
||||
|
||||
if(NOT CMAKE_SKIP_INSTALL_RULES)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
set(
|
||||
sleigh_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/sleigh"
|
||||
CACHE PATH "CMake package config location relative to the install prefix"
|
||||
)
|
||||
mark_as_advanced(sleigh_INSTALL_CMAKEDIR)
|
||||
|
||||
install(
|
||||
TARGETS sleigh_lift
|
||||
EXPORT sleighExtraToolsTargets
|
||||
RUNTIME #
|
||||
COMPONENT sleigh_ExtraToolsRuntime
|
||||
)
|
||||
install(
|
||||
EXPORT sleighExtraToolsTargets
|
||||
DESTINATION "${sleigh_INSTALL_CMAKEDIR}"
|
||||
NAMESPACE sleigh::
|
||||
COMPONENT sleigh_ExtraToolsDevelopment
|
||||
)
|
||||
endif()
|
||||
@@ -45,7 +45,7 @@ static void PrintVersion(void) {
|
||||
}
|
||||
}
|
||||
|
||||
class InMemoryLoadImage : public LoadImage {
|
||||
class InMemoryLoadImage : public ghidra::LoadImage {
|
||||
public:
|
||||
explicit InMemoryLoadImage(uint64_t base_addr)
|
||||
: LoadImage("nofile"), base_addr(base_addr) {}
|
||||
@@ -55,7 +55,8 @@ public:
|
||||
image_buffer = std::move(buf);
|
||||
}
|
||||
|
||||
void loadFill(unsigned char *ptr, int size, const Address &addr) override {
|
||||
void loadFill(unsigned char *ptr, int size,
|
||||
const ghidra::Address &addr) override {
|
||||
uint64_t start = addr.getOffset();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
uint64_t offset = start + i;
|
||||
@@ -88,7 +89,7 @@ static std::string ParseHexBytes(std::string_view bytes, uint64_t addr,
|
||||
<< "' specified in bytes arg." << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
const uint64_t addr_mask = ~0ULL >> (64UL - addr_size);
|
||||
const uint64_t addr_mask = ~0ULL >> (64UL - addr_size * 8);
|
||||
auto byte_addr = addr + (i / 2);
|
||||
auto masked_addr = byte_addr & addr_mask;
|
||||
// Make sure that if a really big number is specified for `address`,
|
||||
@@ -108,18 +109,18 @@ static std::string ParseHexBytes(std::string_view bytes, uint64_t addr,
|
||||
return buffer;
|
||||
}
|
||||
|
||||
class AssemblyPrinter : public AssemblyEmit {
|
||||
class AssemblyPrinter : public ghidra::AssemblyEmit {
|
||||
public:
|
||||
void dump(const Address &addr, const std::string &mnemonic,
|
||||
void dump(const ghidra::Address &addr, const std::string &mnemonic,
|
||||
const std::string &body) override {
|
||||
addr.printRaw(std::cout);
|
||||
std::cout << ": " << mnemonic << ' ' << body << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
static void PrintAssembly(Sleigh &engine, uint64_t addr, size_t len) {
|
||||
static void PrintAssembly(ghidra::Sleigh &engine, uint64_t addr, size_t len) {
|
||||
AssemblyPrinter asm_emit;
|
||||
Address cur_addr(engine.getDefaultCodeSpace(), addr),
|
||||
ghidra::Address cur_addr(engine.getDefaultCodeSpace(), addr),
|
||||
last_addr(engine.getDefaultCodeSpace(), addr + len);
|
||||
while (cur_addr < last_addr) {
|
||||
int32_t instr_len = engine.printAssembly(asm_emit, cur_addr);
|
||||
@@ -127,15 +128,16 @@ static void PrintAssembly(Sleigh &engine, uint64_t addr, size_t len) {
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintVarData(std::ostream &s, VarnodeData &data) {
|
||||
static void PrintVarData(std::ostream &s, ghidra::VarnodeData &data) {
|
||||
s << '(' << data.space->getName() << ',';
|
||||
data.space->printOffset(s, data.offset);
|
||||
s << ',' << std::dec << data.size << ')';
|
||||
}
|
||||
|
||||
class PcodePrinter : public PcodeEmit {
|
||||
class PcodePrinter : public ghidra::PcodeEmit {
|
||||
public:
|
||||
void dump(const Address &, OpCode op, VarnodeData *outvar, VarnodeData *vars,
|
||||
void dump(const ghidra::Address &, ghidra::OpCode op,
|
||||
ghidra::VarnodeData *outvar, ghidra::VarnodeData *vars,
|
||||
int32_t isize) override {
|
||||
if (outvar) {
|
||||
PrintVarData(std::cout, *outvar);
|
||||
@@ -150,9 +152,9 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static void PrintPcode(Sleigh &engine, uint64_t addr, size_t len) {
|
||||
static void PrintPcode(ghidra::Sleigh &engine, uint64_t addr, size_t len) {
|
||||
PcodePrinter pcode_emit;
|
||||
Address cur_addr(engine.getDefaultCodeSpace(), addr),
|
||||
ghidra::Address cur_addr(engine.getDefaultCodeSpace(), addr),
|
||||
last_addr(engine.getDefaultCodeSpace(), addr + len);
|
||||
while (cur_addr < last_addr) {
|
||||
int32_t instr_len = engine.oneInstruction(pcode_emit, cur_addr);
|
||||
@@ -256,12 +258,21 @@ int main(int argc, char *argv[]) {
|
||||
<< std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// Put together SLEIGH components
|
||||
// Put together Sleigh components
|
||||
ghidra::AttributeId::initialize();
|
||||
ghidra::ElementId::initialize();
|
||||
InMemoryLoadImage load_image(addr);
|
||||
ContextInternal ctx;
|
||||
Sleigh engine(&load_image, &ctx);
|
||||
DocumentStorage storage;
|
||||
Element *root = storage.openDocument(sla_file_path->string())->getRoot();
|
||||
ghidra::ContextInternal ctx;
|
||||
ghidra::Sleigh engine(&load_image, &ctx);
|
||||
ghidra::DocumentStorage storage;
|
||||
#ifdef sleigh_RELEASE_IS_HEAD
|
||||
std::istringstream sla("<sleigh>" + sla_file_path->string() + "</sleigh>");
|
||||
ghidra::Element *root =
|
||||
storage.parseDocument(sla)->getRoot();
|
||||
#else
|
||||
ghidra::Element *root =
|
||||
storage.openDocument(sla_file_path->string())->getRoot();
|
||||
#endif
|
||||
storage.registerTag(root);
|
||||
std::optional<std::filesystem::path> pspec_file_path;
|
||||
if (args->pspec_file_name) {
|
||||
@@ -285,7 +296,8 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
if (pspec_file_path) {
|
||||
Element *pspec_root = storage.openDocument(pspec_file_path->string())->getRoot();
|
||||
ghidra::Element *pspec_root =
|
||||
storage.openDocument(pspec_file_path->string())->getRoot();
|
||||
storage.registerTag(pspec_root);
|
||||
}
|
||||
engine.initialize(storage);
|
||||
@@ -294,19 +306,27 @@ int main(int argc, char *argv[]) {
|
||||
// we can set the default context
|
||||
// This imitates what is done in
|
||||
// void Architecture::parseProcessorConfig(DocumentStorage &store)
|
||||
const Element *el = storage.getTag("processor_spec");
|
||||
const ghidra::Element *el = storage.getTag("processor_spec");
|
||||
if (el) {
|
||||
const List &list(el->getChildren());
|
||||
for (List::const_iterator iter = list.begin(); iter != list.end(); ++iter) {
|
||||
const string &elname((*iter)->getName());
|
||||
if (elname == "context_data") {
|
||||
ctx.restoreFromSpec(*iter, &engine);
|
||||
ghidra::XmlDecode decoder(&engine, el);
|
||||
ghidra::uint4 elemId = decoder.openElement(ghidra::ELEM_PROCESSOR_SPEC);
|
||||
for (;;) {
|
||||
ghidra::uint4 subId = decoder.peekElement();
|
||||
if (subId == 0)
|
||||
break;
|
||||
else if (subId == ghidra::ELEM_CONTEXT_DATA) {
|
||||
ctx.decodeFromSpec(decoder);
|
||||
break;
|
||||
} else {
|
||||
decoder.openElement();
|
||||
decoder.closeElementSkipping(subId);
|
||||
}
|
||||
}
|
||||
decoder.closeElement(elemId);
|
||||
}
|
||||
|
||||
// In order to parse and validate the byte string properly, we need to get the
|
||||
// address size from SLEIGH. Therefore this needs to happen after
|
||||
// address size from Sleigh. Therefore this needs to happen after
|
||||
// initialization.
|
||||
//
|
||||
// Ensure that we don't start disassembling until we've set the image buffer.
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2021-present, Trail of Bits, Inc.
|
||||
All rights reserved.
|
||||
|
||||
This source code is licensed in accordance with the terms specified in
|
||||
the LICENSE file found in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef _MSC_VER
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated"
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#endif
|
||||
#include "address.hh"
|
||||
#include "context.hh"
|
||||
#include "emulate.hh"
|
||||
#include "error.hh"
|
||||
#include "float.hh"
|
||||
#include "globalcontext.hh"
|
||||
#include "loadimage.hh"
|
||||
#include "memstate.hh"
|
||||
#include "opbehavior.hh"
|
||||
#include "opcodes.hh"
|
||||
#include "partmap.hh"
|
||||
#include "pcoderaw.hh"
|
||||
#include "semantics.hh"
|
||||
#include "sleigh.hh"
|
||||
#include "sleighbase.hh"
|
||||
#include "slghpatexpress.hh"
|
||||
#include "slghpattern.hh"
|
||||
#include "slghsymbol.hh"
|
||||
#include "space.hh"
|
||||
#include "translate.hh"
|
||||
#include "types.h"
|
||||
#include "xml.hh"
|
||||
#ifndef _MSC_VER
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "Support.h"
|
||||
#include "Version.h"
|
||||
@@ -1,165 +0,0 @@
|
||||
From 031d9830abe8517540389672fd22dc479e46d696 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Kilmer <eric.d.kilmer@gmail.com>
|
||||
Date: Sun, 13 Feb 2022 12:59:42 -0500
|
||||
Subject: [PATCH] Small improvements to C++ decompiler testing from CLI
|
||||
|
||||
* Fixes argument parsing to accept more than one option for specifying
|
||||
paths.
|
||||
|
||||
* Return a non-zero exit code (clamped to max value 255, even if more
|
||||
than 255 tests fail) indicating number of failed tests. This is
|
||||
helpful when running in a script (like in CI) to detect failures
|
||||
instead of detecting failures through manual visual inspection of
|
||||
output text.
|
||||
---
|
||||
.../Decompiler/src/decompile/cpp/test.cc | 42 ++++++++++++++-----
|
||||
.../Decompiler/src/decompile/cpp/test.hh | 2 +-
|
||||
.../src/decompile/cpp/testfunction.cc | 3 +-
|
||||
.../src/decompile/cpp/testfunction.hh | 2 +-
|
||||
4 files changed, 36 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/test.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/test.cc
|
||||
index e81f2564a..ebc049c29 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/test.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/test.cc
|
||||
@@ -14,6 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "test.hh"
|
||||
+
|
||||
+#include <algorithm>
|
||||
+
|
||||
#include "libdecomp.hh"
|
||||
|
||||
vector<UnitTest *> UnitTest::tests;
|
||||
@@ -21,7 +24,8 @@ vector<UnitTest *> UnitTest::tests;
|
||||
/// Run all the tests unless a non-empty set of names is passed in.
|
||||
/// In which case, only the named tests in the set are run.
|
||||
/// \param testNames is the set of names
|
||||
-void UnitTest::run(set<string> &testNames)
|
||||
+/// \return number of failed tests
|
||||
+int UnitTest::run(set<string> &testNames)
|
||||
|
||||
{
|
||||
int total = 0;
|
||||
@@ -42,6 +46,7 @@ void UnitTest::run(set<string> &testNames)
|
||||
}
|
||||
std::cerr << "==============================" << std::endl;
|
||||
std::cerr << passed << "/" << total << " tests passed." << std::endl;
|
||||
+ return total - passed;
|
||||
}
|
||||
|
||||
/// Create list of the absolute path of all tests to be run
|
||||
@@ -85,7 +90,7 @@ int main(int argc, char **argv) {
|
||||
set<string> dataTestNames;
|
||||
string dirname("../datatests");
|
||||
string sleighdirname("../../../../../../..");
|
||||
- if (argc > 0) {
|
||||
+ while (argc > 0) {
|
||||
string command(argv[0]);
|
||||
if (command == "-path") {
|
||||
dirname = argv[1];
|
||||
@@ -109,30 +114,47 @@ int main(int argc, char **argv) {
|
||||
argv += 1;
|
||||
argc -= 1;
|
||||
}
|
||||
- }
|
||||
- if (argc > 0) {
|
||||
- string command(argv[0]);
|
||||
- if (command == "unittests") {
|
||||
+ else if (command == "unittests") {
|
||||
runUnitTests = true;
|
||||
runDataTests = false; // Run only unit tests
|
||||
unitTestNames.insert(argv + 1,argv + argc);
|
||||
+ break;
|
||||
}
|
||||
else if (command == "datatests") {
|
||||
runUnitTests = false; // Run only data-tests
|
||||
runDataTests = true;
|
||||
dataTestNames.insert(argv + 1,argv + argc);
|
||||
+ break;
|
||||
}
|
||||
else {
|
||||
- cout << "USAGE: ghidra_test [-path <datatestdir>] [[unittests|datatests] [testname1 testname2 ...]]" << endl;
|
||||
+ cout << "USAGE: ghidra_test [-usesleighenv] [-sleighpath <sleighdir>] [-path <datatestdir>] [[unittests|datatests] [testname1 testname2 ...]]" << endl;
|
||||
+ return -1;
|
||||
}
|
||||
}
|
||||
startDecompilerLibrary(sleighdirname.c_str());
|
||||
- if (runUnitTests)
|
||||
- UnitTest::run(unitTestNames);
|
||||
+
|
||||
+ // Keep track of failed tests as return code to indicate failures, clamped at
|
||||
+ // max 255 value
|
||||
+ int failedTests = 0;
|
||||
+ if (runUnitTests) {
|
||||
+ int errors = UnitTest::run(unitTestNames);
|
||||
+ // Clamp at 255 max return code
|
||||
+ failedTests = std::min(
|
||||
+ failedTests +
|
||||
+ (errors < 0 ? 255 : std::min(errors, 255)),
|
||||
+ 255);
|
||||
+ }
|
||||
if (runDataTests) {
|
||||
vector<string> testFiles;
|
||||
gatherDataTests(dirname,dataTestNames,testFiles);
|
||||
cout << endl << endl;
|
||||
- FunctionTestCollection::runTestFiles(testFiles,cout);
|
||||
+ int errors = FunctionTestCollection::runTestFiles(testFiles,cout);
|
||||
+ // Clamp at 255 max return code
|
||||
+ failedTests = std::min(
|
||||
+ failedTests +
|
||||
+ (errors < 0 ? 255 : std::min(errors, 255)),
|
||||
+ 255);
|
||||
}
|
||||
+
|
||||
+ return failedTests;
|
||||
}
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/test.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/test.hh
|
||||
index 8b762c5b1..a138f511d 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/test.hh
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/test.hh
|
||||
@@ -54,7 +54,7 @@ struct UnitTest {
|
||||
tests.push_back(this);
|
||||
}
|
||||
|
||||
- static void run(std::set<std::string> &testNames); ///< Run all the instantiated tests
|
||||
+ static int run(std::set<std::string> &testNames); ///< Run all the instantiated tests
|
||||
};
|
||||
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.cc
|
||||
index 66f8d3fa2..c136a964b 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.cc
|
||||
@@ -304,7 +304,7 @@ void FunctionTestCollection::runTests(list<string> &lateStream)
|
||||
/// Run through all XML files in the given list, processing each in turn.
|
||||
/// \param testFiles is the given list of test files
|
||||
/// \param s is the output stream to print results to
|
||||
-void FunctionTestCollection::runTestFiles(const vector<string> &testFiles,ostream &s)
|
||||
+int FunctionTestCollection::runTestFiles(const vector<string> &testFiles,ostream &s)
|
||||
|
||||
{
|
||||
int4 totalTestsApplied = 0;
|
||||
@@ -344,4 +344,5 @@ void FunctionTestCollection::runTestFiles(const vector<string> &testFiles,ostrea
|
||||
if (iter == failures.end()) break;
|
||||
}
|
||||
}
|
||||
+ return totalTestsApplied - totalTestsSucceeded;
|
||||
}
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.hh
|
||||
index 52125b401..46abd6bce 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.hh
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.hh
|
||||
@@ -91,7 +91,7 @@ class FunctionTestCollection {
|
||||
void restoreXml(DocumentStorage &store,const Element *el); ///< Load tests from a \<decompilertest> tag.
|
||||
void restoreXmlOldForm(DocumentStorage &store,const Element *el); ///< Load tests from \<binaryimage> tag.
|
||||
void runTests(list<string> &lateStream); ///< Run the script and perform the tests
|
||||
- static void runTestFiles(const vector<string> &testFiles,ostream &s); ///< Run tests for each listed file
|
||||
+ static int runTestFiles(const vector<string> &testFiles,ostream &s); ///< Run tests for each listed file
|
||||
};
|
||||
|
||||
#endif
|
||||
--
|
||||
2.35.1
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
From 031d9830abe8517540389672fd22dc479e46d696 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Kilmer <eric.d.kilmer@gmail.com>
|
||||
Date: Sun, 13 Feb 2022 12:59:42 -0500
|
||||
Subject: [PATCH] Small improvements to C++ decompiler testing from CLI
|
||||
|
||||
* Fixes argument parsing to accept more than one option for specifying
|
||||
paths.
|
||||
|
||||
* Return a non-zero exit code (clamped to max value 255, even if more
|
||||
than 255 tests fail) indicating number of failed tests. This is
|
||||
helpful when running in a script (like in CI) to detect failures
|
||||
instead of detecting failures through manual visual inspection of
|
||||
output text.
|
||||
---
|
||||
.../Decompiler/src/decompile/cpp/test.cc | 42 ++++++++++++++-----
|
||||
.../Decompiler/src/decompile/cpp/test.hh | 2 +-
|
||||
.../src/decompile/cpp/testfunction.cc | 3 +-
|
||||
.../src/decompile/cpp/testfunction.hh | 2 +-
|
||||
4 files changed, 36 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/test.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/test.cc
|
||||
index e81f2564a..ebc049c29 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/test.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/test.cc
|
||||
@@ -14,6 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "test.hh"
|
||||
+
|
||||
+#include <algorithm>
|
||||
+
|
||||
#include "libdecomp.hh"
|
||||
|
||||
vector<UnitTest *> UnitTest::tests;
|
||||
@@ -21,7 +24,8 @@ vector<UnitTest *> UnitTest::tests;
|
||||
/// Run all the tests unless a non-empty set of names is passed in.
|
||||
/// In which case, only the named tests in the set are run.
|
||||
/// \param testNames is the set of names
|
||||
-void UnitTest::run(set<string> &testNames)
|
||||
+/// \return number of failed tests
|
||||
+int UnitTest::run(set<string> &testNames)
|
||||
|
||||
{
|
||||
int total = 0;
|
||||
@@ -42,6 +46,7 @@ void UnitTest::run(set<string> &testNames)
|
||||
}
|
||||
std::cerr << "==============================" << std::endl;
|
||||
std::cerr << passed << "/" << total << " tests passed." << std::endl;
|
||||
+ return total - passed;
|
||||
}
|
||||
|
||||
/// Create list of the absolute path of all tests to be run
|
||||
@@ -85,7 +90,7 @@ int main(int argc, char **argv) {
|
||||
set<string> dataTestNames;
|
||||
string dirname("../datatests");
|
||||
string sleighdirname("../../../../../../..");
|
||||
- if (argc > 0) {
|
||||
+ while (argc > 0) {
|
||||
string command(argv[0]);
|
||||
if (command == "-path") {
|
||||
dirname = argv[1];
|
||||
@@ -109,30 +114,47 @@ int main(int argc, char **argv) {
|
||||
argv += 1;
|
||||
argc -= 1;
|
||||
}
|
||||
- }
|
||||
- if (argc > 0) {
|
||||
- string command(argv[0]);
|
||||
- if (command == "unittests") {
|
||||
+ else if (command == "unittests") {
|
||||
runUnitTests = true;
|
||||
runDataTests = false; // Run only unit tests
|
||||
unitTestNames.insert(argv + 1,argv + argc);
|
||||
+ break;
|
||||
}
|
||||
else if (command == "datatests") {
|
||||
runUnitTests = false; // Run only data-tests
|
||||
runDataTests = true;
|
||||
dataTestNames.insert(argv + 1,argv + argc);
|
||||
+ break;
|
||||
}
|
||||
else {
|
||||
- cout << "USAGE: ghidra_test [-path <datatestdir>] [[unittests|datatests] [testname1 testname2 ...]]" << endl;
|
||||
+ cout << "USAGE: ghidra_test [-usesleighenv] [-sleighpath <sleighdir>] [-path <datatestdir>] [[unittests|datatests] [testname1 testname2 ...]]" << endl;
|
||||
+ return -1;
|
||||
}
|
||||
}
|
||||
startDecompilerLibrary(sleighdirname.c_str());
|
||||
- if (runUnitTests)
|
||||
- UnitTest::run(unitTestNames);
|
||||
+
|
||||
+ // Keep track of failed tests as return code to indicate failures, clamped at
|
||||
+ // max 255 value
|
||||
+ int failedTests = 0;
|
||||
+ if (runUnitTests) {
|
||||
+ int errors = UnitTest::run(unitTestNames);
|
||||
+ // Clamp at 255 max return code
|
||||
+ failedTests = std::min(
|
||||
+ failedTests +
|
||||
+ (errors < 0 ? 255 : std::min(errors, 255)),
|
||||
+ 255);
|
||||
+ }
|
||||
if (runDataTests) {
|
||||
vector<string> testFiles;
|
||||
gatherDataTests(dirname,dataTestNames,testFiles);
|
||||
cout << endl << endl;
|
||||
- FunctionTestCollection::runTestFiles(testFiles,cout);
|
||||
+ int errors = FunctionTestCollection::runTestFiles(testFiles,cout);
|
||||
+ // Clamp at 255 max return code
|
||||
+ failedTests = std::min(
|
||||
+ failedTests +
|
||||
+ (errors < 0 ? 255 : std::min(errors, 255)),
|
||||
+ 255);
|
||||
}
|
||||
+
|
||||
+ return failedTests;
|
||||
}
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/test.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/test.hh
|
||||
index 8b762c5b1..a138f511d 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/test.hh
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/test.hh
|
||||
@@ -54,7 +54,7 @@ struct UnitTest {
|
||||
tests.push_back(this);
|
||||
}
|
||||
|
||||
- static void run(std::set<std::string> &testNames); ///< Run all the instantiated tests
|
||||
+ static int run(std::set<std::string> &testNames); ///< Run all the instantiated tests
|
||||
};
|
||||
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.cc
|
||||
index 66f8d3fa2..c136a964b 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.cc
|
||||
@@ -304,7 +304,7 @@ void FunctionTestCollection::runTests(list<string> &lateStream)
|
||||
/// Run through all XML files in the given list, processing each in turn.
|
||||
/// \param testFiles is the given list of test files
|
||||
/// \param s is the output stream to print results to
|
||||
-void FunctionTestCollection::runTestFiles(const vector<string> &testFiles,ostream &s)
|
||||
+int FunctionTestCollection::runTestFiles(const vector<string> &testFiles,ostream &s)
|
||||
|
||||
{
|
||||
int4 totalTestsApplied = 0;
|
||||
@@ -344,4 +344,5 @@ void FunctionTestCollection::runTestFiles(const vector<string> &testFiles,ostrea
|
||||
if (iter == failures.end()) break;
|
||||
}
|
||||
}
|
||||
+ return totalTestsApplied - totalTestsSucceeded;
|
||||
}
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.hh
|
||||
index 52125b401..46abd6bce 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.hh
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/testfunction.hh
|
||||
@@ -91,7 +91,7 @@ class FunctionTestCollection {
|
||||
void restoreXml(DocumentStorage &store,const Element *el); ///< Load tests from a \<decompilertest> tag.
|
||||
void restoreXmlOldForm(DocumentStorage &store,const Element *el); ///< Load tests from \<binaryimage> tag.
|
||||
void runTests(list<string> &lateStream); ///< Run the script and perform the tests
|
||||
- static void runTestFiles(const vector<string> &testFiles,ostream &s); ///< Run tests for each listed file
|
||||
+ static int runTestFiles(const vector<string> &testFiles,ostream &s); ///< Run tests for each listed file
|
||||
};
|
||||
|
||||
#endif
|
||||
--
|
||||
2.35.1
|
||||
|
||||
+108
-39
@@ -1,18 +1,26 @@
|
||||
"""Script to update CMake files for latest Ghidra Sleigh changes"""
|
||||
import pathlib
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from typing import AnyStr, Union
|
||||
from pathlib import Path
|
||||
from typing import AnyStr, Union, List
|
||||
|
||||
PROJECT_ROOT = pathlib.Path(__file__).parent.parent.resolve()
|
||||
HEAD_SPEC_FILE = PROJECT_ROOT / "spec-files-list" / "spec_files_HEAD.cmake"
|
||||
PROJECT_ROOT = Path(__file__).parent.parent.resolve()
|
||||
HEAD_SPEC_FILE = PROJECT_ROOT / "src" / "spec_files_HEAD.cmake"
|
||||
assert HEAD_SPEC_FILE.exists()
|
||||
SETUP_GHIDRA_FILE = PROJECT_ROOT / "src" / "setup-ghidra-source.cmake"
|
||||
assert SETUP_GHIDRA_FILE.exists()
|
||||
|
||||
# Paths in Ghidra repo that affect this repo. Used with git diff
|
||||
SLEIGH_PATHS: List[str] = [
|
||||
# Source code and tests
|
||||
"Ghidra/Features/Decompiler/src/decompile",
|
||||
# Sleigh files
|
||||
"Ghidra/Processors",
|
||||
]
|
||||
|
||||
GIT_EXE = shutil.which("git")
|
||||
assert GIT_EXE is not None
|
||||
|
||||
@@ -21,21 +29,18 @@ def msg(s: str) -> None:
|
||||
print(f"[!] {s}")
|
||||
|
||||
|
||||
PathString = Union[AnyStr, pathlib.Path]
|
||||
PathString = Union[AnyStr, Path]
|
||||
|
||||
|
||||
def clone_ghidra_git(dir: PathString) -> None:
|
||||
def clone_ghidra_git(clone_dir: PathString) -> None:
|
||||
"""Clone the Ghidra git dir at specified directory"""
|
||||
# Shallow clone
|
||||
assert GIT_EXE is not None
|
||||
subprocess.run(
|
||||
[
|
||||
GIT_EXE,
|
||||
"clone",
|
||||
"https://github.com/NationalSecurityAgency/ghidra",
|
||||
"--depth",
|
||||
"1",
|
||||
dir,
|
||||
clone_dir,
|
||||
],
|
||||
stdout=sys.stdout,
|
||||
stderr=sys.stderr,
|
||||
@@ -43,36 +48,90 @@ def clone_ghidra_git(dir: PathString) -> None:
|
||||
)
|
||||
|
||||
|
||||
def update_head_commit(latest_commit: str):
|
||||
def git_get_changed_files(
|
||||
repo: Path, old_commit: str, new_commit: str, paths: List[str], ci: bool
|
||||
) -> List[str]:
|
||||
"""Get list of changed files from old_commit to new_commit at the specified paths"""
|
||||
assert GIT_EXE is not None
|
||||
changed_files = (
|
||||
subprocess.run(
|
||||
[
|
||||
GIT_EXE,
|
||||
"diff",
|
||||
"--name-status",
|
||||
f"{old_commit}...{new_commit}",
|
||||
"--",
|
||||
*paths,
|
||||
],
|
||||
cwd=repo,
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
.stdout.decode()
|
||||
.strip()
|
||||
.splitlines()
|
||||
)
|
||||
num_changed = len(changed_files)
|
||||
if num_changed > 0:
|
||||
msg(f"Found {num_changed} changed sleigh files:")
|
||||
print("\n".join(changed_files))
|
||||
if ci:
|
||||
with open(os.environ["GITHUB_OUTPUT"], "a") as gh_out:
|
||||
gh_out.write("changed_files<<EOF\n")
|
||||
gh_out.write("```\n")
|
||||
gh_out.write("\n".join(changed_files))
|
||||
gh_out.write("\n```\n")
|
||||
gh_out.write("EOF\n")
|
||||
return changed_files
|
||||
|
||||
|
||||
def is_sleigh_updated(
|
||||
ghidra_repo: Path, old_commit: str, new_commit: str, ci: bool
|
||||
) -> bool:
|
||||
"""Check if files we're interested in have been touched at all"""
|
||||
changed_files = git_get_changed_files(
|
||||
ghidra_repo, old_commit, new_commit, SLEIGH_PATHS, ci
|
||||
)
|
||||
return len(changed_files) > 0
|
||||
|
||||
|
||||
def update_head_commit(
|
||||
setup_file: Path, ghidra_repo_dir: PathString, latest_commit: str, ci: bool
|
||||
) -> bool:
|
||||
"""Edit the Ghidra script to point to the latest commit"""
|
||||
head_commit_line = r"set\(ghidra_head_git_tag \"([0-9A-Fa-f]+)\"\)"
|
||||
updated = False
|
||||
|
||||
fd, abspath = tempfile.mkstemp()
|
||||
with open(fd, "w") as w:
|
||||
with open(SETUP_GHIDRA_FILE, "r") as r:
|
||||
with setup_file.open("r") as r:
|
||||
for line in r:
|
||||
match = re.search(head_commit_line, line)
|
||||
if match is not None:
|
||||
current_commit = match.group(1)
|
||||
if current_commit != latest_commit:
|
||||
msg(f"Found new commit: {latest_commit}")
|
||||
line = re.sub(
|
||||
head_commit_line,
|
||||
f'set(ghidra_head_git_tag "{latest_commit}")',
|
||||
line,
|
||||
)
|
||||
updated = True
|
||||
if is_sleigh_updated(
|
||||
ghidra_repo_dir, current_commit, latest_commit, ci
|
||||
):
|
||||
line = re.sub(
|
||||
head_commit_line,
|
||||
f'set(ghidra_head_git_tag "{latest_commit}")',
|
||||
line,
|
||||
)
|
||||
updated = True
|
||||
else:
|
||||
msg("No sleigh files updated")
|
||||
w.write(line)
|
||||
|
||||
# Make the swap with the new content
|
||||
shutil.copymode(SETUP_GHIDRA_FILE, abspath)
|
||||
os.remove(SETUP_GHIDRA_FILE)
|
||||
shutil.move(abspath, SETUP_GHIDRA_FILE)
|
||||
shutil.copymode(setup_file, abspath)
|
||||
os.remove(setup_file)
|
||||
shutil.move(abspath, setup_file)
|
||||
return updated
|
||||
|
||||
|
||||
def update_head_version_file(ghidra_root_dir: PathString) -> None:
|
||||
def update_head_version_file(setup_file: Path, ghidra_root_dir: PathString) -> None:
|
||||
"""Edit the Ghidra script to point to the latest version"""
|
||||
cmake_head_version_line = (
|
||||
r"set\(ghidra_head_version \"([0-9]+(\.[0-9]+)?(\.[0-9]+)?)\"\)"
|
||||
@@ -86,7 +145,7 @@ def update_head_version_file(ghidra_root_dir: PathString) -> None:
|
||||
assert match is not None
|
||||
source_version = match.group(1)
|
||||
|
||||
with SETUP_GHIDRA_FILE.open("r") as f:
|
||||
with setup_file.open("r") as f:
|
||||
content = f.read()
|
||||
match = re.search(cmake_head_version_line, content)
|
||||
assert match is not None
|
||||
@@ -99,7 +158,7 @@ def update_head_version_file(ghidra_root_dir: PathString) -> None:
|
||||
msg(f"Found new version: {source_version}")
|
||||
fd, abspath = tempfile.mkstemp()
|
||||
with open(fd, "w") as w:
|
||||
with SETUP_GHIDRA_FILE.open("r") as r:
|
||||
with setup_file.open("r") as r:
|
||||
for line in r:
|
||||
match = re.search(cmake_head_version_line, line)
|
||||
if match is not None:
|
||||
@@ -111,9 +170,9 @@ def update_head_version_file(ghidra_root_dir: PathString) -> None:
|
||||
w.write(line)
|
||||
|
||||
# Make the swap with the new content
|
||||
shutil.copymode(SETUP_GHIDRA_FILE, abspath)
|
||||
os.remove(SETUP_GHIDRA_FILE)
|
||||
shutil.move(abspath, SETUP_GHIDRA_FILE)
|
||||
shutil.copymode(setup_file, abspath)
|
||||
os.remove(setup_file)
|
||||
shutil.move(abspath, setup_file)
|
||||
|
||||
|
||||
def update_spec_files(ghidra_repo_dir: PathString, cmake_file: PathString):
|
||||
@@ -122,9 +181,7 @@ def update_spec_files(ghidra_repo_dir: PathString, cmake_file: PathString):
|
||||
for dirpath, _, fnames in os.walk(ghidra_repo_dir / "Ghidra" / "Processors"):
|
||||
for file in fnames:
|
||||
if file.endswith(".slaspec"):
|
||||
spec_files.append(
|
||||
(pathlib.Path(dirpath) / file).relative_to(ghidra_repo_dir)
|
||||
)
|
||||
spec_files.append((Path(dirpath) / file).relative_to(ghidra_repo_dir))
|
||||
assert len(spec_files) > 0
|
||||
spec_files.sort()
|
||||
|
||||
@@ -152,22 +209,27 @@ def get_latest_commit(ghidra_repo_dir: PathString) -> str:
|
||||
)
|
||||
|
||||
|
||||
def update_head(ghidra_repo_dir: PathString, ci: bool) -> bool:
|
||||
def update_head(
|
||||
setup_file: Path, spec_file: Path, ghidra_repo_dir: PathString, ci: bool
|
||||
) -> bool:
|
||||
"""Update to latest head and make changes to the CMake files"""
|
||||
tmpdirname = None
|
||||
if ghidra_repo_dir is None:
|
||||
tmpdirname = tempfile.TemporaryDirectory()
|
||||
ghidra_repo_dir = pathlib.Path(tmpdirname.name) / "ghidra"
|
||||
ghidra_repo_dir = Path(tmpdirname.name) / "ghidra"
|
||||
clone_ghidra_git(ghidra_repo_dir)
|
||||
|
||||
latest_commit = get_latest_commit(ghidra_repo_dir)
|
||||
did_update_commit = update_head_commit(latest_commit)
|
||||
did_update_commit = update_head_commit(
|
||||
setup_file, ghidra_repo_dir, latest_commit, ci
|
||||
)
|
||||
if did_update_commit:
|
||||
if ci:
|
||||
print(f"::set-output name=short_sha::{latest_commit[:9]}")
|
||||
print("::set-output name=did_update::true")
|
||||
update_spec_files(ghidra_repo_dir, HEAD_SPEC_FILE)
|
||||
update_head_version_file(ghidra_repo_dir)
|
||||
with open(os.environ["GITHUB_OUTPUT"], "a") as gh_out:
|
||||
gh_out.write(f"short_sha={latest_commit[:9]}\n")
|
||||
gh_out.write("did_update=true\n")
|
||||
update_spec_files(ghidra_repo_dir, spec_file)
|
||||
update_head_version_file(setup_file, ghidra_repo_dir)
|
||||
else:
|
||||
msg(f"Already at the latest commit: {latest_commit}")
|
||||
|
||||
@@ -186,7 +248,7 @@ if __name__ == "__main__":
|
||||
def dir_path(string):
|
||||
if string is None:
|
||||
return string
|
||||
string = pathlib.Path(string).expanduser().resolve()
|
||||
string = Path(string).expanduser().resolve()
|
||||
if string.is_dir():
|
||||
return string
|
||||
else:
|
||||
@@ -207,5 +269,12 @@ if __name__ == "__main__":
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if not update_head(args.ghidra_repo, args.ci):
|
||||
if args.ci:
|
||||
assert (
|
||||
"GITHUB_OUTPUT" in os.environ
|
||||
), "CI needs `GITHUB_OUTPUT` environment variable set to a file location"
|
||||
|
||||
if not update_head(SETUP_GHIDRA_FILE, HEAD_SPEC_FILE, args.ghidra_repo, args.ci):
|
||||
msg("No update required")
|
||||
else:
|
||||
msg("Update required!")
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
#
|
||||
# Copyright (c) 2022-present, Trail of Bits, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed in accordance with the terms specified in
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
include(../cmake/prelude.cmake)
|
||||
include(../src/setup-ghidra-source.cmake)
|
||||
|
||||
project(sleigh_specs
|
||||
VERSION "${ghidra_version}"
|
||||
DESCRIPTION "Sleigh specifications"
|
||||
HOMEPAGE_URL "https://github.com/lifting-bits/sleigh"
|
||||
# Language is for installing the helper CMake file
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
include(../cmake/project-is-top-level.cmake)
|
||||
|
||||
# This is the root directory where all individual processor spec file directories will be created.
|
||||
if(NOT DEFINED spec_files_build_dir)
|
||||
set(spec_files_build_dir "${CMAKE_CURRENT_BINARY_DIR}/specfiles")
|
||||
endif()
|
||||
|
||||
# This prefix should match the Ghidra repo to where the sla spec files are located
|
||||
set(spec_files_dir_prefix "Ghidra/Processors")
|
||||
|
||||
# This is where we will be copying the generated artifacts for each processor
|
||||
set(spec_files_root_dir "${spec_files_build_dir}/${spec_files_dir_prefix}")
|
||||
set(spec_files_build_log_dir "${CMAKE_CURRENT_BINARY_DIR}/spec_build_logs")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${spec_files_build_log_dir}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${spec_files_build_log_dir}"
|
||||
)
|
||||
|
||||
# Get the native machine's sleigh compiler or use the one we're about to build
|
||||
# if not cross compiling
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
find_program(
|
||||
SLEIGH_EXECUTABLE sleigh
|
||||
DOC "Path to host system sleigh compiler"
|
||||
REQUIRED
|
||||
)
|
||||
else()
|
||||
# Try to find/acquire or bootstrap the sleigh spec compiler
|
||||
# Logic is repeated in example/CMakeLists.txt
|
||||
if(NOT TARGET sleigh::sleigh)
|
||||
find_package(sleigh QUIET)
|
||||
if(NOT sleigh_FOUND OR NOT TARGET sleigh::sleigh)
|
||||
find_program(
|
||||
SLEIGH_EXECUTABLE sleigh
|
||||
DOC "Path to host system sleigh compiler"
|
||||
)
|
||||
if(NOT SLEIGH_EXECUTABLE)
|
||||
message(WARNING "Could not find sleigh compiler, building from source")
|
||||
set(saved_skip_install_rules "${CMAKE_SKIP_INSTALL_RULES}")
|
||||
set(CMAKE_SKIP_INSTALL_RULES TRUE)
|
||||
add_subdirectory(../tools/spec-compiler spec-compiler EXCLUDE_FROM_ALL)
|
||||
set(CMAKE_SKIP_INSTALL_RULES "${saved_skip_install_rules}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(SLEIGH_EXECUTABLE)
|
||||
set(sleigh_compiler "${SLEIGH_EXECUTABLE}")
|
||||
else()
|
||||
set(sleigh_compiler "$<TARGET_FILE:sleigh::sleigh>")
|
||||
endif()
|
||||
|
||||
# Start processing all `.slaspec` files individually
|
||||
set(spec_targets)
|
||||
set(spec_files)
|
||||
set(spec_dirs)
|
||||
include(../cmake/modules/sleighCompile.cmake)
|
||||
|
||||
# Example: '<ghidra_source_prefix>/Ghidra/Processors/8051/data/languages/mx51.slaspec'
|
||||
foreach(spec_file ${spec_file_list})
|
||||
# Get 'mx51'
|
||||
get_filename_component(spec_name "${spec_file}" NAME_WLE)
|
||||
|
||||
# Get '<ghidra_source_prefix>/Ghidra/Processors/8051/data/languages'
|
||||
get_filename_component(spec_dir "${spec_file}" DIRECTORY)
|
||||
|
||||
# Get '8051/data/languages'
|
||||
file(RELATIVE_PATH spec_proc_dir
|
||||
"${ghidrasource_SOURCE_DIR}/${spec_files_dir_prefix}"
|
||||
"${spec_dir}"
|
||||
)
|
||||
|
||||
# Add relative spec processor directory for later processing
|
||||
list(APPEND spec_dirs ${spec_proc_dir})
|
||||
|
||||
# Get '8051'
|
||||
get_filename_component(proc_name "${spec_proc_dir}" DIRECTORY)
|
||||
get_filename_component(proc_name "${proc_name}" DIRECTORY)
|
||||
|
||||
set(spec_build_log "${spec_files_build_log_dir}/${spec_name}_build.log")
|
||||
|
||||
# Combine back again for the build directory output like
|
||||
# '<build_prefix>/Ghidra/Processors/8051/data/languages'
|
||||
set(spec_out_dir "${spec_files_root_dir}/${spec_proc_dir}")
|
||||
|
||||
# '<build_prefix>/Ghidra/Processors/8051/data/languages/mx51.sla'
|
||||
set(spec_out "${spec_out_dir}/${spec_name}.sla")
|
||||
|
||||
string(REPLACE "." "_" spec_target_name ${spec_name})
|
||||
set(spec_target "sleigh_spec_${spec_target_name}")
|
||||
|
||||
# Compile the sla file
|
||||
sleigh_compile(
|
||||
TARGET "${spec_target}"
|
||||
COMPILER "${sleigh_compiler}"
|
||||
SLASPEC "${spec_file}"
|
||||
LOG_FILE "${spec_build_log}"
|
||||
OUT_FILE "${spec_out}"
|
||||
)
|
||||
add_dependencies(${spec_target} sleigh_copy_${proc_name}_dir)
|
||||
|
||||
list(APPEND spec_targets ${spec_target})
|
||||
list(APPEND spec_files ${spec_out})
|
||||
endforeach()
|
||||
|
||||
# Copy and create specfile directories
|
||||
list(REMOVE_DUPLICATES spec_dirs)
|
||||
|
||||
foreach(spec_dir ${spec_dirs})
|
||||
set(spec_src_dir "${ghidrasource_SOURCE_DIR}/${spec_files_dir_prefix}/${spec_dir}")
|
||||
set(spec_out_dir "${spec_files_root_dir}/${spec_dir}")
|
||||
|
||||
# Get the processor directory name
|
||||
get_filename_component(proc_name "${spec_dir}" DIRECTORY)
|
||||
get_filename_component(proc_name "${proc_name}" DIRECTORY)
|
||||
|
||||
# Copy all other files from the slaspec source directory:
|
||||
# '<ghidra_source_prefix>/Ghidra/Processors/8051/data/languages'
|
||||
# NOTE: This only copies the directory once, so you will need to remove the
|
||||
# whole directory if you update any of the other files, like '*.cspec' or
|
||||
# '*.ldef' files
|
||||
# CMake only guarantees update monitoring for files listed explicitly
|
||||
add_custom_command(
|
||||
OUTPUT "${spec_out_dir}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory "${spec_src_dir}" "${spec_out_dir}"
|
||||
)
|
||||
add_custom_target(sleigh_copy_${proc_name}_dir
|
||||
DEPENDS "${spec_out_dir}"
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# All of the sla spec targets are combined into this one
|
||||
add_custom_target(sleigh_all_sla_specs ALL DEPENDS
|
||||
${spec_targets}
|
||||
)
|
||||
|
||||
if(NOT CMAKE_SKIP_INSTALL_RULES)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# Specfiles installation setup
|
||||
set(sleigh_INSTALL_DATADIR "${CMAKE_INSTALL_DATADIR}/sleigh"
|
||||
CACHE PATH "sleigh data installation location relative to the install prefix"
|
||||
)
|
||||
mark_as_advanced(sleigh_INSTALL_DATADIR)
|
||||
|
||||
set(sleigh_INSTALL_SPECDIR "${sleigh_INSTALL_DATADIR}/specfiles"
|
||||
CACHE PATH "sleigh specfile root destination relative to the install prefix"
|
||||
)
|
||||
mark_as_advanced(sleigh_INSTALL_SPECDIR)
|
||||
|
||||
# Install the compiled sla files found in 'Ghidra' top-level directory
|
||||
install(
|
||||
DIRECTORY "${spec_files_build_dir}/"
|
||||
DESTINATION "${sleigh_INSTALL_SPECDIR}"
|
||||
COMPONENT sleigh_Runtime
|
||||
)
|
||||
|
||||
set(
|
||||
sleigh_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/sleigh"
|
||||
CACHE PATH "CMake package config location relative to the install prefix"
|
||||
)
|
||||
mark_as_advanced(sleigh_INSTALL_CMAKEDIR)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
configure_package_config_file(specfiles.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/specfiles.cmake"
|
||||
INSTALL_DESTINATION "${sleigh_INSTALL_CMAKEDIR}"
|
||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO
|
||||
PATH_VARS sleigh_INSTALL_SPECDIR
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${PROJECT_BINARY_DIR}/specfiles.cmake"
|
||||
DESTINATION "${sleigh_INSTALL_CMAKEDIR}"
|
||||
COMPONENT sleigh_Development
|
||||
)
|
||||
|
||||
if(PROJECT_IS_TOP_LEVEL)
|
||||
include(CPack)
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,12 @@
|
||||
#
|
||||
# Copyright (c) 2022-present, Trail of Bits, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed in accordance with the terms specified in
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
# Path relative-root to reach installed specfiles directory
|
||||
set_and_check(sleigh_INSTALL_SPECDIR "@PACKAGE_sleigh_INSTALL_SPECDIR@")
|
||||
+21
-21
@@ -1,45 +1,45 @@
|
||||
# Ghidra Source code
|
||||
|
||||
This project uses CMake's [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) module to set up the Ghidra source tree. This means we can apply [patches](../patches) that live only in this repo for small changes to features like packaging or running tests.
|
||||
This project uses CMake's [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) module to set up the Ghidra source tree. Using `FetchContent` means we can apply [patches](patches) that live only in this repo for minor changes that affect usage, packaging, or running tests.
|
||||
|
||||
By default, CMake pulls a stable version of Ghidra. You may use a more recent commit by specifying `-Dsleigh_GHIDRA_RELEASE_TYPE=HEAD` during CMake configuration.
|
||||
|
||||
See the `sleigh_GHIDRA_*` CMake cache variable comments for more details on how to customize your Ghidra source checkout.
|
||||
By default, CMake pulls a stable version of Ghidra. During CMake configuration, you may use a more recent commit by specifying `-Dsleigh_RELEASE_TYPE=HEAD`.
|
||||
|
||||
## Advanced Usage Notes
|
||||
|
||||
Always reference the [CMake Documentation](https://cmake.org/cmake/help/latest/) for explanation of features and cache variable usages/effects.
|
||||
Always reference the [CMake Documentation](https://cmake.org/cmake/help/latest/) and check CMake cache variables with `ccmake build` to discover all available options.
|
||||
|
||||
### Using your own Ghidra checkout
|
||||
|
||||
This method is useful for developing new features on top of the latest commits in Ghidra's default branch. If the commit(s) at the tip of Ghidra's default branch are not supported by this repo, we welcome pull requests to update support and pin that commit.
|
||||
This method helps develop new features on top of the latest commits in Ghidra's default branch. Please open an issue or pull request if the commit at the tip of Ghidra's default branch does not build.
|
||||
|
||||
**Arbitrary Ghidra checkouts are not officially supported.**
|
||||
**Arbitrary Ghidra checkouts/commits are not officially supported.**
|
||||
|
||||
If you want to use your own Ghidra source checkout, then set the following during CMake configuration:
|
||||
Set the following during CMake configuration if you want to use your own Ghidra source checkout:
|
||||
|
||||
* `-Dsleigh_GHIDRA_RELEASE_TYPE=HEAD` if using commits on Ghidra's default branch (`master`) or any branch that may be incompatible with the current stable version.
|
||||
* `-Dsleigh_RELEASE_TYPE=HEAD` if using commits on Ghidra's default branch (`master`) or any branch that may be incompatible with the current stable version.
|
||||
|
||||
* `-DFETCHCONTENT_SOURCE_DIR_GHIDRASOURCE=<path to your own Ghidra source>`. Remember, no existing [patches](../patches/HEAD) will be applied to your own source directory.
|
||||
* `-DFETCHCONTENT_SOURCE_DIR_GHIDRASOURCE=<path to your own Ghidra source>`. Remember, CMake will not apply any [patches](patches/HEAD) to the specified source directory.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/NationalSecurityAgency/ghidra src/ghidra
|
||||
|
||||
cmake -B build-dev-head -S . \
|
||||
-Dsleigh_GHIDRA_RELEASE_TYPE=HEAD \
|
||||
-DFETCHCONTENT_SOURCE_DIR_GHIDRASOURCE="$(pwd)/src/ghidra"
|
||||
-Dsleigh_RELEASE_TYPE=HEAD \
|
||||
"-DFETCHCONTENT_SOURCE_DIR_GHIDRASOURCE=$PWD/src/ghidra"
|
||||
```
|
||||
|
||||
### Reusing Downloaded Ghidra Source
|
||||
|
||||
If you want to share a single Ghidra source checkout/clone for multiple build directories, the [_FetchContent Base Directory_](https://cmake.org/cmake/help/latest/module/FetchContent.html#variable:FETCHCONTENT_BASE_DIR) (`FETCHCONTENT_BASE_DIR`) should encode the build generator name and be located outside of the build directory (the name would look something like `cmake_fc_ghidra_${sleigh_GHIDRA_RELEASE_TYPE}_${CMAKE_GENERATOR}`).
|
||||
The following scenario is discouraged. It can be brittle if everything does not match up. It is only helpful if you do not want to apply Ghidra source patches yourself.
|
||||
|
||||
Initially, this means that every new build generator used for building the project will have to re-download the ghidra source tree, but any subsequent run with an already-initialize generator should be faster and skip the download.
|
||||
Suppose you want to share a single Ghidra source checkout/clone for multiple build directories. In that case, the _FetchContent Base Directory_ (`FETCHCONTENT_BASE_DIR`) should encode the build generator name and be located outside of the build directory (the name would look something like `cmake_fc_ghidra_${sleigh_RELEASE_TYPE}_${CMAKE_GENERATOR}`).
|
||||
|
||||
Initially, this means that every new build generator used for building the project will have to re-download the Ghidra source tree. Still, any subsequent run with an already-initialize generator should be faster and skip the download.
|
||||
|
||||
```bash
|
||||
$ cmake -B build-release -S . -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DFETCHCONTENT_BASE_DIR=./src/cmake_fc_ghidra_stable_Ninja
|
||||
"-DFETCHCONTENT_BASE_DIR=$PWD/src/cmake_fc_ghidra_stable_Ninja"
|
||||
-- Using Ghidra version 10.0.4 at commit 5b07797
|
||||
-- Populating ghidrasource
|
||||
-- Configuring done
|
||||
@@ -69,7 +69,7 @@ HEAD is now at 5b07797cb Updated 10.0.4 Change History
|
||||
|
||||
$ cmake -B build-debug -S . -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DFETCHCONTENT_BASE_DIR=./src/cmake_fc_ghidra_stable_Ninja
|
||||
"-DFETCHCONTENT_BASE_DIR=$PWD/src/cmake_fc_ghidra_stable_Ninja"
|
||||
-- Using Ghidra version 10.0.4 at commit 5b07797
|
||||
-- Populating ghidrasource
|
||||
-- Configuring done
|
||||
@@ -88,19 +88,19 @@ $ cmake -B build-debug -S . -G Ninja \
|
||||
...
|
||||
```
|
||||
|
||||
The above also works when using `HEAD` commit of Ghidra.
|
||||
The above also works when using the `HEAD` commit of Ghidra.
|
||||
|
||||
```bash
|
||||
$ cmake -B build-head-release -S . -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-Dsleigh_GHIDRA_RELEASE_TYPE=HEAD \
|
||||
-DFETCHCONTENT_BASE_DIR=./src/cmake_fc_ghidra_HEAD_Ninja
|
||||
-Dsleigh_RELEASE_TYPE=HEAD \
|
||||
"-DFETCHCONTENT_BASE_DIR=$PWD/src/cmake_fc_ghidra_HEAD_Ninja"
|
||||
...
|
||||
|
||||
$ cmake -B build-head-debug -S . -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-Dsleigh_GHIDRA_RELEASE_TYPE=HEAD \
|
||||
-DFETCHCONTENT_BASE_DIR=./src/cmake_fc_ghidra_HEAD_Ninja
|
||||
-Dsleigh_RELEASE_TYPE=HEAD \
|
||||
"-DFETCHCONTENT_BASE_DIR=$PWD/src/cmake_fc_ghidra_HEAD_Ninja"
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#
|
||||
# Copyright (c) 2022-present, Trail of Bits, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed in accordance with the terms specified in
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
# Internal settings
|
||||
option(sleigh_CPUI_RULECOMPILE "Allow user defined dynamic rules")
|
||||
option(sleigh_CPUI_STATISTICS "Turn on collection of cover and cast statistics")
|
||||
|
||||
# Internal debug settings (naming is swapped to help with discoverability in CMake options)
|
||||
option(sleigh_DEBUG_BLOCKCONSISTENT "Check that block graph structure is consistent")
|
||||
option(sleigh_DEBUG_DFSVERIFY "Make sure that the block ordering algorithm produces a true depth first traversal of the dominator tree")
|
||||
option(sleigh_DEBUG_MERGEMULTI "Check for MULTIEQUAL and INDIRECT intersections")
|
||||
option(sleigh_DEBUG_OPACTION "Turns on all the action tracing facilities")
|
||||
|
||||
#
|
||||
# Common options that can apply to all project targets
|
||||
#
|
||||
macro(sleigh_add_optional_defines target visibility)
|
||||
set(opt_defines "")
|
||||
if(sleigh_CPUI_RULECOMPILE)
|
||||
list(APPEND opt_defines "CPUI_RULECOMPILE")
|
||||
endif()
|
||||
if(sleigh_CPUI_STATISTICS)
|
||||
list(APPEND opt_defines "CPUI_STATISTICS")
|
||||
endif()
|
||||
if(sleigh_DEBUG_BLOCKCONSISTENT)
|
||||
list(APPEND opt_defines "BLOCKCONSISTENT_DEBUG")
|
||||
endif()
|
||||
if(sleigh_DEBUG_DFSVERIFY)
|
||||
list(APPEND opt_defines "DFSVERIFY_DEBUG")
|
||||
endif()
|
||||
if(sleigh_DEBUG_MERGEMULTI)
|
||||
list(APPEND opt_defines "MERGEMULTI_DEBUG")
|
||||
endif()
|
||||
if(sleigh_DEBUG_OPACTION)
|
||||
list(APPEND opt_defines "OPACTION_DEBUG")
|
||||
endif()
|
||||
if(WIN32)
|
||||
list(APPEND opt_defines "_WINDOWS")
|
||||
endif()
|
||||
target_compile_definitions("${target}" ${visibility} ${opt_defines})
|
||||
endmacro()
|
||||
@@ -0,0 +1,256 @@
|
||||
From 6c36965500d26d5a35dfbc91725956ae1d51e394 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Cameron <asc@tetsuo.sh>
|
||||
Date: Mon, 5 Jun 2023 16:45:04 +1200
|
||||
Subject: [PATCH 1/5] Fix UBSAN errors in decompiler
|
||||
|
||||
---
|
||||
.../Decompiler/src/decompile/cpp/fspec.cc | 8 ++++++--
|
||||
.../src/decompile/cpp/funcdata_varnode.cc | 8 +++++++-
|
||||
.../Decompiler/src/decompile/cpp/op.cc | 6 +++++-
|
||||
.../Decompiler/src/decompile/cpp/opbehavior.cc | 8 +++++++-
|
||||
.../src/decompile/cpp/pcodecompile.cc | 18 +++++++++++-------
|
||||
.../Decompiler/src/decompile/cpp/ruleaction.cc | 18 ++++++++++++++----
|
||||
.../Decompiler/src/decompile/cpp/semantics.cc | 2 ++
|
||||
.../Decompiler/src/decompile/cpp/semantics.hh | 2 +-
|
||||
.../src/decompile/cpp/slgh_compile.cc | 2 +-
|
||||
.../Decompiler/src/decompile/cpp/type.cc | 2 +-
|
||||
.../src/decompile/unittests/testfloatemu.cc | 2 +-
|
||||
11 files changed, 56 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc
|
||||
index dc96f0c19..3482cf17c 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc
|
||||
@@ -2727,8 +2727,12 @@ void ProtoModelMerged::decode(Decoder &decoder)
|
||||
modellist.push_back(mymodel);
|
||||
}
|
||||
decoder.closeElement(elemId);
|
||||
- ((ParamListMerged *)input)->finalize();
|
||||
- ((ParamListMerged *)output)->finalize();
|
||||
+ if (input->getType() == ParamList::p_merged) {
|
||||
+ ((ParamListMerged *)input)->finalize();
|
||||
+ }
|
||||
+ if (output->getType() == ParamList::p_merged) {
|
||||
+ ((ParamListMerged *)output)->finalize();
|
||||
+ }
|
||||
}
|
||||
|
||||
void ParameterBasic::setTypeLock(bool val)
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc
|
||||
index fc094ee96..1f7e53ebe 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc
|
||||
@@ -503,7 +503,13 @@ void Funcdata::setHighLevel(void)
|
||||
void Funcdata::transferVarnodeProperties(Varnode *vn,Varnode *newVn,int4 lsbOffset)
|
||||
|
||||
{
|
||||
- uintb newConsume = (vn->getConsume() >> 8*lsbOffset) & calc_mask(newVn->getSize());
|
||||
+ uintb newConsume = vn->getConsume();
|
||||
+ if (8*lsbOffset < sizeof(newConsume)) {
|
||||
+ newConsume >>= 8*lsbOffset;
|
||||
+ } else {
|
||||
+ newConsume = 0;
|
||||
+ }
|
||||
+ newConsume &= calc_mask(newVn->getSize());
|
||||
|
||||
uint4 vnFlags = vn->getFlags() & (Varnode::directwrite|Varnode::addrforce);
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc
|
||||
index 921335173..46cdc39f3 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc
|
||||
@@ -666,7 +666,11 @@ uintb PcodeOp::getNZMaskLocal(bool cliploop) const
|
||||
break;
|
||||
case CPUI_PIECE:
|
||||
resmask = getIn(0)->getNZMask();
|
||||
- resmask <<= 8*getIn(1)->getSize();
|
||||
+ if (8*getIn(1)->getSize() < sizeof(resmask)) {
|
||||
+ resmask <<= 8*getIn(1)->getSize();
|
||||
+ } else {
|
||||
+ resmask = 0;
|
||||
+ }
|
||||
resmask |= getIn(1)->getNZMask();
|
||||
break;
|
||||
case CPUI_INT_MULT:
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/opbehavior.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/opbehavior.cc
|
||||
index aebcfd910..6c47e6eb1 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/opbehavior.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/opbehavior.cc
|
||||
@@ -746,7 +746,13 @@ uintb OpBehaviorPiece::evaluateBinary(int4 sizeout,int4 sizein,uintb in1,uintb i
|
||||
uintb OpBehaviorSubpiece::evaluateBinary(int4 sizeout,int4 sizein,uintb in1,uintb in2) const
|
||||
|
||||
{
|
||||
- uintb res = (in1>>(in2*8)) & calc_mask(sizeout);
|
||||
+ uintb res = in1;
|
||||
+ if (in2 < sizeof(in1)) {
|
||||
+ res >>= (in2*8);
|
||||
+ } else {
|
||||
+ res = 0;
|
||||
+ }
|
||||
+ res &= calc_mask(sizeout);
|
||||
return res;
|
||||
}
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodecompile.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/pcodecompile.cc
|
||||
index ca9d71ab9..85d4dd281 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodecompile.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/pcodecompile.cc
|
||||
@@ -621,8 +621,10 @@ vector<OpTpl *> *PcodeCompile::assignBitRange(VarnodeTpl *vn,uint4 bitoffset,uin
|
||||
uint4 smallsize = (numbits+7)/8; // Size of input (output of rhs)
|
||||
bool shiftneeded = (bitoffset != 0);
|
||||
bool zextneeded = true;
|
||||
- uintb mask = (uintb)2;
|
||||
- mask = ~(((mask<<(numbits-1))-1) << bitoffset);
|
||||
+ uintb mask = 0;
|
||||
+ const int4 masknumbits = sizeof(mask) * 8;
|
||||
+ if (numbits - 1 < masknumbits && bitoffset < masknumbits)
|
||||
+ mask = ~(((static_cast<uintb>(2) << (numbits - 1)) - 1) << bitoffset);
|
||||
|
||||
if (vn->getSize().getType()==ConstTpl::real) {
|
||||
// If we know the size of the bitranged varnode, we can
|
||||
@@ -726,9 +728,6 @@ ExprTree *PcodeCompile::createBitRange(SpecificSymbol *sym,uint4 bitoffset,uint4
|
||||
}
|
||||
}
|
||||
|
||||
- uintb mask = (uintb)2;
|
||||
- mask = ((mask<<(numbits-1))-1);
|
||||
-
|
||||
if (truncneeded && ((bitoffset % 8)==0)) {
|
||||
truncshift = bitoffset/8;
|
||||
bitoffset = 0;
|
||||
@@ -751,8 +750,13 @@ ExprTree *PcodeCompile::createBitRange(SpecificSymbol *sym,uint4 bitoffset,uint4
|
||||
appendOp(CPUI_INT_RIGHT,res,bitoffset,4);
|
||||
if (truncneeded)
|
||||
appendOp(CPUI_SUBPIECE,res,truncshift,4);
|
||||
- if (maskneeded)
|
||||
- appendOp(CPUI_INT_AND,res,mask,finalsize);
|
||||
+ if (maskneeded) {
|
||||
+ uintb mask = 0;
|
||||
+ if (numbits - 1 < sizeof(mask) * 8)
|
||||
+ mask = static_cast<uintb>(2) << (numbits - 1);
|
||||
+ --mask;
|
||||
+ appendOp(CPUI_INT_AND, res, mask, finalsize);
|
||||
+ }
|
||||
force_size(res->outvn,ConstTpl(ConstTpl::real,finalsize),*res->ops);
|
||||
return res;
|
||||
}
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc
|
||||
index 3703c8ef5..ac6e21c00 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc
|
||||
@@ -976,7 +976,12 @@ int4 RulePullsubIndirect::applyOp(PcodeOp *op,Funcdata &data)
|
||||
Varnode *outvn = op->getOut();
|
||||
if (outvn->isPrecisLo()||outvn->isPrecisHi()) return 0; // Don't pull apart double precision object
|
||||
|
||||
- uintb consume = calc_mask(newSize) << 8 * minByte;
|
||||
+ uintb consume = calc_mask(newSize);
|
||||
+ if (8 * minByte < sizeof(consume)) {
|
||||
+ consume <<= 8 * minByte;
|
||||
+ } else {
|
||||
+ consume = 0;
|
||||
+ }
|
||||
consume = ~consume;
|
||||
if ((consume & indir->getIn(0)->getConsume())!=0) return 0;
|
||||
|
||||
@@ -6803,8 +6808,9 @@ int4 RulePtrsubCharConstant::applyOp(PcodeOp *op,Funcdata &data)
|
||||
Varnode *sb = op->getIn(0);
|
||||
Datatype *sbType = sb->getTypeReadFacing(op);
|
||||
if (sbType->getMetatype() != TYPE_PTR) return 0;
|
||||
- TypeSpacebase *sbtype = (TypeSpacebase *)((TypePointer *)sbType)->getPtrTo();
|
||||
- if (sbtype->getMetatype() != TYPE_SPACEBASE) return 0;
|
||||
+ Datatype *sbTypePtr = ((TypePointer *)sbType)->getPtrTo();
|
||||
+ if (sbTypePtr->getMetatype() != TYPE_SPACEBASE) return 0;
|
||||
+ TypeSpacebase *sbtype = (TypeSpacebase *)sbTypePtr;
|
||||
Varnode *vn1 = op->getIn(1);
|
||||
if (!vn1->isConstant()) return 0;
|
||||
Varnode *outvn = op->getOut();
|
||||
@@ -8616,7 +8622,11 @@ int4 RuleSubvarSubpiece::applyOp(PcodeOp *op,Funcdata &data)
|
||||
Varnode *outvn = op->getOut();
|
||||
int4 flowsize = outvn->getSize();
|
||||
uintb mask = calc_mask( flowsize );
|
||||
- mask <<= 8*((int4)op->getIn(1)->getOffset());
|
||||
+ if (8*((int4)op->getIn(1)->getOffset()) < sizeof(mask)) {
|
||||
+ mask <<= 8*((int4)op->getIn(1)->getOffset());
|
||||
+ } else {
|
||||
+ mask = 0;
|
||||
+ }
|
||||
bool aggressive = outvn->isPtrFlow();
|
||||
if (!aggressive) {
|
||||
if ((vn->getConsume() & mask) != vn->getConsume()) return 0;
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc
|
||||
index cd9b9835b..8a4616c3b 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc
|
||||
@@ -22,6 +22,7 @@ ConstTpl::ConstTpl(const_type tp)
|
||||
|
||||
{ // Constructor for relative jump constants and uniques
|
||||
type = tp;
|
||||
+ select = v_space;
|
||||
}
|
||||
|
||||
ConstTpl::ConstTpl(const_type tp,uintb val)
|
||||
@@ -56,6 +57,7 @@ ConstTpl::ConstTpl(AddrSpace *sid)
|
||||
{
|
||||
type = spaceid;
|
||||
value.spaceid = sid;
|
||||
+ select = v_space;
|
||||
}
|
||||
|
||||
bool ConstTpl::isConstSpace(void) const
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh
|
||||
index e0b069959..9117a45c7 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh
|
||||
@@ -47,7 +47,7 @@ class ConstTpl {
|
||||
uintb value_real;
|
||||
v_field select; // Which part of handle to use as constant
|
||||
public:
|
||||
- ConstTpl(void) { type = real; value_real = 0; }
|
||||
+ ConstTpl(void) { type = real; value_real = 0; select = v_space; }
|
||||
ConstTpl(const ConstTpl &op2) {
|
||||
type=op2.type; value=op2.value; value_real=op2.value_real; select=op2.select; }
|
||||
ConstTpl(const_type tp,uintb val);
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc
|
||||
index c060053bf..c9004023c 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc
|
||||
@@ -2164,8 +2164,8 @@ string SleighCompile::checkSymbols(SymbolScope *scope)
|
||||
ostringstream msg;
|
||||
SymbolTree::const_iterator iter;
|
||||
for(iter=scope->begin();iter!=scope->end();++iter) {
|
||||
+ if ((*iter)->getType() != SleighSymbol::label_symbol) continue;
|
||||
LabelSymbol *sym = (LabelSymbol *)*iter;
|
||||
- if (sym->getType() != SleighSymbol::label_symbol) continue;
|
||||
if (sym->getRefCount() == 0)
|
||||
msg << " Label <" << sym->getName() << "> was placed but not used" << endl;
|
||||
else if (!sym->isPlaced())
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
index e6292e138..bd31b7470 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
@@ -3561,8 +3561,8 @@ void TypeFactory::recalcPointerSubmeta(Datatype *base,sub_metatype sub)
|
||||
top.submeta = sub; // Search on the incorrect submeta
|
||||
iter = tree.lower_bound(&top);
|
||||
while(iter != tree.end()) {
|
||||
+ if ((*iter)->getMetatype() != TYPE_PTR) break;
|
||||
TypePointer *ptr = (TypePointer *)*iter;
|
||||
- if (ptr->getMetatype() != TYPE_PTR) break;
|
||||
if (ptr->ptrto != base) break;
|
||||
++iter;
|
||||
if (ptr->submeta == sub) {
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/unittests/testfloatemu.cc b/Ghidra/Features/Decompiler/src/decompile/unittests/testfloatemu.cc
|
||||
index c35bde877..061e53677 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/unittests/testfloatemu.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/unittests/testfloatemu.cc
|
||||
@@ -346,7 +346,7 @@ TEST(float_opTrunc_to_int) {
|
||||
|
||||
for(float f:float_test_values) {
|
||||
// avoid undefined behavior
|
||||
- if((int64_t)f > std::numeric_limits<int>::max() || (int64_t)f < std::numeric_limits<int>::min())
|
||||
+ if(f > std::numeric_limits<int>::max() || f < std::numeric_limits<int>::min() || std::isnan(f))
|
||||
continue;
|
||||
uintb true_result = ((uintb)(int32_t)f) & 0xffffffff;
|
||||
uintb encoding = format.getEncoding(f);
|
||||
--
|
||||
2.44.0
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From 290b06621c7a8c32c1470d16dbd8740876d57640 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Cameron <asc@tetsuo.sh>
|
||||
Date: Wed, 3 Aug 2022 20:01:18 +1000
|
||||
Subject: [PATCH 2/5] Use `stroull` instead of `stroul` to parse address
|
||||
offsets
|
||||
|
||||
---
|
||||
Ghidra/Features/Decompiler/src/decompile/cpp/space.cc | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/space.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/space.cc
|
||||
index bda09fc94..d077ee375 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/space.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/space.cc
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "space.hh"
|
||||
#include "translate.hh"
|
||||
|
||||
+#include <climits>
|
||||
+
|
||||
namespace ghidra {
|
||||
|
||||
AttributeId ATTRIB_BASE = AttributeId("base",89);
|
||||
@@ -274,7 +276,10 @@ uintb AddrSpace::read(const string &s,int4 &size) const
|
||||
}
|
||||
}
|
||||
catch(LowlevelError &err) { // Name doesn't exist
|
||||
- offset = strtoul(s.c_str(),&tmpdata,0);
|
||||
+ offset = strtoull(s.c_str(),&tmpdata,0);
|
||||
+ if (offset == ULLONG_MAX) {
|
||||
+ throw LowlevelError("Offset outside of valid range");
|
||||
+ }
|
||||
offset = addressToByte(offset,wordsize);
|
||||
enddata = (const char *) tmpdata;
|
||||
if (enddata - s.c_str() == s.size()) { // If no size or offset override
|
||||
--
|
||||
2.44.0
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
From 73d6f5a2a9a39dba3117947b3e27fe112c7d7074 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Kilmer <eric.d.kilmer@gmail.com>
|
||||
Date: Mon, 4 Mar 2024 11:18:57 -0500
|
||||
Subject: [PATCH 3/5] Fix sleighexample
|
||||
|
||||
---
|
||||
Ghidra/Features/Decompiler/src/decompile/cpp/sleighexample.cc | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/sleighexample.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/sleighexample.cc
|
||||
index f356825c9..5cab3f85c 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/sleighexample.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/sleighexample.cc
|
||||
@@ -315,12 +315,12 @@ int main(int argc,char **argv)
|
||||
ContextInternal context;
|
||||
|
||||
// Set up the assembler/pcode-translator
|
||||
- string sleighfilename = "specfiles/x86.sla";
|
||||
+ istringstream sleighfilename("<sleigh>specfiles/x86.sla</sleigh>");
|
||||
Sleigh trans(&loader,&context);
|
||||
|
||||
// Read sleigh file into DOM
|
||||
DocumentStorage docstorage;
|
||||
- Element *sleighroot = docstorage.openDocument(sleighfilename)->getRoot();
|
||||
+ Element *sleighroot = docstorage.parseDocument(sleighfilename)->getRoot();
|
||||
docstorage.registerTag(sleighroot);
|
||||
trans.initialize(docstorage); // Initialize the translator
|
||||
|
||||
--
|
||||
2.44.0
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
From 2b6f5b2a70158503c844e8259717b7168ced9bc0 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Kilmer <eric.d.kilmer@gmail.com>
|
||||
Date: Sat, 30 Mar 2024 18:26:27 -0400
|
||||
Subject: [PATCH 4/5] Fix opening sla files on Windows
|
||||
|
||||
Compressed files need to be opened as binaries when reading.
|
||||
---
|
||||
Ghidra/Features/Decompiler/src/decompile/cpp/sleigh.cc | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh.cc
|
||||
index 471b99199..ba1a3b22c 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh.cc
|
||||
@@ -560,7 +560,7 @@ void Sleigh::initialize(DocumentStorage &store)
|
||||
if (el == (const Element *)0)
|
||||
throw LowlevelError("Could not find sleigh tag");
|
||||
sla::FormatDecode decoder(this);
|
||||
- ifstream s(el->getContent());
|
||||
+ ifstream s(el->getContent(), std::ios_base::binary);
|
||||
if (!s)
|
||||
throw LowlevelError("Could not open .sla file: " + el->getContent());
|
||||
decoder.ingestStream(s);
|
||||
--
|
||||
2.44.0
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
From a7fc8b440ab58cb377460e11c7449488ff5abc96 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Kilmer <eric.d.kilmer@gmail.com>
|
||||
Date: Sat, 30 Mar 2024 18:46:16 -0400
|
||||
Subject: [PATCH 5/5] Add missing index check to prevent errors in Windows
|
||||
|
||||
Not sure why this only appears when testing on Windows.
|
||||
---
|
||||
Ghidra/Features/Decompiler/src/decompile/cpp/ifacedecomp.cc | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ifacedecomp.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ifacedecomp.cc
|
||||
index ac94d261c..a76ad389b 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/ifacedecomp.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ifacedecomp.cc
|
||||
@@ -1842,7 +1842,7 @@ void IfcProtooverride::execute(istream &s)
|
||||
s >> ws;
|
||||
Address callpoint(parse_machaddr(s,discard,*dcp->conf->types));
|
||||
int4 i;
|
||||
- for(i=0;dcp->fd->numCalls();++i)
|
||||
+ for(i=0;i<dcp->fd->numCalls();++i)
|
||||
if (dcp->fd->getCallSpecs(i)->getOp()->getAddr() == callpoint) break;
|
||||
if (i == dcp->fd->numCalls())
|
||||
throw IfaceExecutionError("No call is made at this address");
|
||||
--
|
||||
2.44.0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Ghidra Patches
|
||||
|
||||
This directory contains small patches that should not affect any deployed Ghidra sleigh functionality from its original intent.
|
||||
This directory contains small patches that do not affect any deployed Ghidra sleigh functionality from its original intent unless otherwise specified.
|
||||
|
||||
These patches primarily support packaging and testing, or fixing critical issues that prevent building for one reason or another.
|
||||
|
||||
@@ -0,0 +1,271 @@
|
||||
From 0e437cb96249306d17f26ff6614871ecd9b37359 Mon Sep 17 00:00:00 2001
|
||||
From: "github-actions[bot]"
|
||||
<41898282+github-actions[bot]@users.noreply.github.com>
|
||||
Date: Wed, 2 Aug 2023 23:19:42 +1000
|
||||
Subject: [PATCH 1/2] Fix UBSAN errors in decompiler
|
||||
|
||||
---
|
||||
.../Decompiler/src/decompile/cpp/fspec.cc | 8 ++++++--
|
||||
.../src/decompile/cpp/funcdata_varnode.cc | 8 +++++++-
|
||||
.../Decompiler/src/decompile/cpp/op.cc | 6 +++++-
|
||||
.../Decompiler/src/decompile/cpp/opbehavior.cc | 8 +++++++-
|
||||
.../src/decompile/cpp/pcodecompile.cc | 18 +++++++++++-------
|
||||
.../Decompiler/src/decompile/cpp/ruleaction.cc | 18 ++++++++++++++----
|
||||
.../Decompiler/src/decompile/cpp/semantics.cc | 2 ++
|
||||
.../Decompiler/src/decompile/cpp/semantics.hh | 2 +-
|
||||
.../src/decompile/cpp/slgh_compile.cc | 2 +-
|
||||
.../Decompiler/src/decompile/cpp/slghsymbol.cc | 2 +-
|
||||
.../Decompiler/src/decompile/cpp/type.cc | 2 +-
|
||||
.../src/decompile/unittests/testfloatemu.cc | 2 +-
|
||||
12 files changed, 57 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc
|
||||
index 8380d3cd..a18d5007 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc
|
||||
@@ -2661,8 +2661,12 @@ void ProtoModelMerged::decode(Decoder &decoder)
|
||||
modellist.push_back(mymodel);
|
||||
}
|
||||
decoder.closeElement(elemId);
|
||||
- ((ParamListMerged *)input)->finalize();
|
||||
- ((ParamListMerged *)output)->finalize();
|
||||
+ if (input->getType() == ParamList::p_merged) {
|
||||
+ ((ParamListMerged *)input)->finalize();
|
||||
+ }
|
||||
+ if (output->getType() == ParamList::p_merged) {
|
||||
+ ((ParamListMerged *)output)->finalize();
|
||||
+ }
|
||||
}
|
||||
|
||||
void ParameterBasic::setTypeLock(bool val)
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc
|
||||
index f7781707..283d81c3 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc
|
||||
@@ -503,7 +503,13 @@ void Funcdata::setHighLevel(void)
|
||||
void Funcdata::transferVarnodeProperties(Varnode *vn,Varnode *newVn,int4 lsbOffset)
|
||||
|
||||
{
|
||||
- uintb newConsume = (vn->getConsume() >> 8*lsbOffset) & calc_mask(newVn->getSize());
|
||||
+ uintb newConsume = vn->getConsume();
|
||||
+ if (8*lsbOffset < sizeof(newConsume)) {
|
||||
+ newConsume >>= 8*lsbOffset;
|
||||
+ } else {
|
||||
+ newConsume = 0;
|
||||
+ }
|
||||
+ newConsume &= calc_mask(newVn->getSize());
|
||||
|
||||
uint4 vnFlags = vn->getFlags() & (Varnode::directwrite|Varnode::addrforce);
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc
|
||||
index 0e3decc8..403ec35a 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc
|
||||
@@ -672,7 +672,11 @@ uintb PcodeOp::getNZMaskLocal(bool cliploop) const
|
||||
break;
|
||||
case CPUI_PIECE:
|
||||
resmask = getIn(0)->getNZMask();
|
||||
- resmask <<= 8*getIn(1)->getSize();
|
||||
+ if (8*getIn(1)->getSize() < sizeof(resmask)) {
|
||||
+ resmask <<= 8*getIn(1)->getSize();
|
||||
+ } else {
|
||||
+ resmask = 0;
|
||||
+ }
|
||||
resmask |= getIn(1)->getNZMask();
|
||||
break;
|
||||
case CPUI_INT_MULT:
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/opbehavior.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/opbehavior.cc
|
||||
index fcd75cc7..ed0e005a 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/opbehavior.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/opbehavior.cc
|
||||
@@ -750,7 +750,13 @@ uintb OpBehaviorPiece::evaluateBinary(int4 sizeout,int4 sizein,uintb in1,uintb i
|
||||
uintb OpBehaviorSubpiece::evaluateBinary(int4 sizeout,int4 sizein,uintb in1,uintb in2) const
|
||||
|
||||
{
|
||||
- uintb res = (in1>>(in2*8)) & calc_mask(sizeout);
|
||||
+ uintb res = in1;
|
||||
+ if (in2 < sizeof(in1)) {
|
||||
+ res >>= (in2*8);
|
||||
+ } else {
|
||||
+ res = 0;
|
||||
+ }
|
||||
+ res &= calc_mask(sizeout);
|
||||
return res;
|
||||
}
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodecompile.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/pcodecompile.cc
|
||||
index ca9d71ab..85d4dd28 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodecompile.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/pcodecompile.cc
|
||||
@@ -621,8 +621,10 @@ vector<OpTpl *> *PcodeCompile::assignBitRange(VarnodeTpl *vn,uint4 bitoffset,uin
|
||||
uint4 smallsize = (numbits+7)/8; // Size of input (output of rhs)
|
||||
bool shiftneeded = (bitoffset != 0);
|
||||
bool zextneeded = true;
|
||||
- uintb mask = (uintb)2;
|
||||
- mask = ~(((mask<<(numbits-1))-1) << bitoffset);
|
||||
+ uintb mask = 0;
|
||||
+ const int4 masknumbits = sizeof(mask) * 8;
|
||||
+ if (numbits - 1 < masknumbits && bitoffset < masknumbits)
|
||||
+ mask = ~(((static_cast<uintb>(2) << (numbits - 1)) - 1) << bitoffset);
|
||||
|
||||
if (vn->getSize().getType()==ConstTpl::real) {
|
||||
// If we know the size of the bitranged varnode, we can
|
||||
@@ -726,9 +728,6 @@ ExprTree *PcodeCompile::createBitRange(SpecificSymbol *sym,uint4 bitoffset,uint4
|
||||
}
|
||||
}
|
||||
|
||||
- uintb mask = (uintb)2;
|
||||
- mask = ((mask<<(numbits-1))-1);
|
||||
-
|
||||
if (truncneeded && ((bitoffset % 8)==0)) {
|
||||
truncshift = bitoffset/8;
|
||||
bitoffset = 0;
|
||||
@@ -751,8 +750,13 @@ ExprTree *PcodeCompile::createBitRange(SpecificSymbol *sym,uint4 bitoffset,uint4
|
||||
appendOp(CPUI_INT_RIGHT,res,bitoffset,4);
|
||||
if (truncneeded)
|
||||
appendOp(CPUI_SUBPIECE,res,truncshift,4);
|
||||
- if (maskneeded)
|
||||
- appendOp(CPUI_INT_AND,res,mask,finalsize);
|
||||
+ if (maskneeded) {
|
||||
+ uintb mask = 0;
|
||||
+ if (numbits - 1 < sizeof(mask) * 8)
|
||||
+ mask = static_cast<uintb>(2) << (numbits - 1);
|
||||
+ --mask;
|
||||
+ appendOp(CPUI_INT_AND, res, mask, finalsize);
|
||||
+ }
|
||||
force_size(res->outvn,ConstTpl(ConstTpl::real,finalsize),*res->ops);
|
||||
return res;
|
||||
}
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc
|
||||
index 4851365d..d069d1c9 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc
|
||||
@@ -976,7 +976,12 @@ int4 RulePullsubIndirect::applyOp(PcodeOp *op,Funcdata &data)
|
||||
Varnode *outvn = op->getOut();
|
||||
if (outvn->isPrecisLo()||outvn->isPrecisHi()) return 0; // Don't pull apart double precision object
|
||||
|
||||
- uintb consume = calc_mask(newSize) << 8 * minByte;
|
||||
+ uintb consume = calc_mask(newSize);
|
||||
+ if (8 * minByte < sizeof(consume)) {
|
||||
+ consume <<= 8 * minByte;
|
||||
+ } else {
|
||||
+ consume = 0;
|
||||
+ }
|
||||
consume = ~consume;
|
||||
if ((consume & indir->getIn(0)->getConsume())!=0) return 0;
|
||||
|
||||
@@ -6782,8 +6787,9 @@ int4 RulePtrsubCharConstant::applyOp(PcodeOp *op,Funcdata &data)
|
||||
Varnode *sb = op->getIn(0);
|
||||
Datatype *sbType = sb->getTypeReadFacing(op);
|
||||
if (sbType->getMetatype() != TYPE_PTR) return 0;
|
||||
- TypeSpacebase *sbtype = (TypeSpacebase *)((TypePointer *)sbType)->getPtrTo();
|
||||
- if (sbtype->getMetatype() != TYPE_SPACEBASE) return 0;
|
||||
+ Datatype *sbTypePtr = ((TypePointer *)sbType)->getPtrTo();
|
||||
+ if (sbTypePtr->getMetatype() != TYPE_SPACEBASE) return 0;
|
||||
+ TypeSpacebase *sbtype = (TypeSpacebase *)sbTypePtr;
|
||||
Varnode *vn1 = op->getIn(1);
|
||||
if (!vn1->isConstant()) return 0;
|
||||
Varnode *outvn = op->getOut();
|
||||
@@ -8593,7 +8599,11 @@ int4 RuleSubvarSubpiece::applyOp(PcodeOp *op,Funcdata &data)
|
||||
Varnode *outvn = op->getOut();
|
||||
int4 flowsize = outvn->getSize();
|
||||
uintb mask = calc_mask( flowsize );
|
||||
- mask <<= 8*((int4)op->getIn(1)->getOffset());
|
||||
+ if (8*((int4)op->getIn(1)->getOffset()) < sizeof(mask)) {
|
||||
+ mask <<= 8*((int4)op->getIn(1)->getOffset());
|
||||
+ } else {
|
||||
+ mask = 0;
|
||||
+ }
|
||||
bool aggressive = outvn->isPtrFlow();
|
||||
if (!aggressive) {
|
||||
if ((vn->getConsume() & mask) != vn->getConsume()) return 0;
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc
|
||||
index 2e3531ea..42482be7 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc
|
||||
@@ -22,6 +22,7 @@ ConstTpl::ConstTpl(const_type tp)
|
||||
|
||||
{ // Constructor for relative jump constants and uniques
|
||||
type = tp;
|
||||
+ select = v_space;
|
||||
}
|
||||
|
||||
ConstTpl::ConstTpl(const_type tp,uintb val)
|
||||
@@ -56,6 +57,7 @@ ConstTpl::ConstTpl(AddrSpace *sid)
|
||||
{
|
||||
type = spaceid;
|
||||
value.spaceid = sid;
|
||||
+ select = v_space;
|
||||
}
|
||||
|
||||
bool ConstTpl::isConstSpace(void) const
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh
|
||||
index 8e283dca..652600c1 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh
|
||||
@@ -48,7 +48,7 @@ private:
|
||||
static void printHandleSelector(ostream &s,v_field val);
|
||||
static v_field readHandleSelector(const string &name);
|
||||
public:
|
||||
- ConstTpl(void) { type = real; value_real = 0; }
|
||||
+ ConstTpl(void) { type = real; value_real = 0; select = v_space; }
|
||||
ConstTpl(const ConstTpl &op2) {
|
||||
type=op2.type; value=op2.value; value_real=op2.value_real; select=op2.select; }
|
||||
ConstTpl(const_type tp,uintb val);
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc
|
||||
index b40f7438..3c37958d 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc
|
||||
@@ -2163,8 +2163,8 @@ string SleighCompile::checkSymbols(SymbolScope *scope)
|
||||
ostringstream msg;
|
||||
SymbolTree::const_iterator iter;
|
||||
for(iter=scope->begin();iter!=scope->end();++iter) {
|
||||
+ if ((*iter)->getType() != SleighSymbol::label_symbol) continue;
|
||||
LabelSymbol *sym = (LabelSymbol *)*iter;
|
||||
- if (sym->getType() != SleighSymbol::label_symbol) continue;
|
||||
if (sym->getRefCount() == 0)
|
||||
msg << " Label <" << sym->getName() << "> was placed but not used" << endl;
|
||||
else if (!sym->isPlaced())
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.cc
|
||||
index b308e1b7..af2982ae 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.cc
|
||||
@@ -2569,7 +2569,7 @@ void ContextOp::restoreXml(const Element *el,SleighBase *trans)
|
||||
const List &list(el->getChildren());
|
||||
List::const_iterator iter;
|
||||
iter = list.begin();
|
||||
- patexp = (PatternValue *)PatternExpression::restoreExpression(*iter,trans);
|
||||
+ patexp = PatternExpression::restoreExpression(*iter,trans);
|
||||
patexp->layClaim();
|
||||
}
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
index 30faf0b6..e76a0619 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
@@ -3359,8 +3359,8 @@ void TypeFactory::recalcPointerSubmeta(Datatype *base,sub_metatype sub)
|
||||
top.submeta = sub; // Search on the incorrect submeta
|
||||
iter = tree.lower_bound(&top);
|
||||
while(iter != tree.end()) {
|
||||
+ if ((*iter)->getMetatype() != TYPE_PTR) break;
|
||||
TypePointer *ptr = (TypePointer *)*iter;
|
||||
- if (ptr->getMetatype() != TYPE_PTR) break;
|
||||
if (ptr->ptrto != base) break;
|
||||
++iter;
|
||||
if (ptr->submeta == sub) {
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/unittests/testfloatemu.cc b/Ghidra/Features/Decompiler/src/decompile/unittests/testfloatemu.cc
|
||||
index c35bde87..061e5367 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/unittests/testfloatemu.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/unittests/testfloatemu.cc
|
||||
@@ -346,7 +346,7 @@ TEST(float_opTrunc_to_int) {
|
||||
|
||||
for(float f:float_test_values) {
|
||||
// avoid undefined behavior
|
||||
- if((int64_t)f > std::numeric_limits<int>::max() || (int64_t)f < std::numeric_limits<int>::min())
|
||||
+ if(f > std::numeric_limits<int>::max() || f < std::numeric_limits<int>::min() || std::isnan(f))
|
||||
continue;
|
||||
uintb true_result = ((uintb)(int32_t)f) & 0xffffffff;
|
||||
uintb encoding = format.getEncoding(f);
|
||||
--
|
||||
2.39.2 (Apple Git-143)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
From 95f230f46bdb95aa4aab7f5d320691f87107fb36 Mon Sep 17 00:00:00 2001
|
||||
From: "github-actions[bot]"
|
||||
<41898282+github-actions[bot]@users.noreply.github.com>
|
||||
Date: Wed, 2 Aug 2023 23:20:14 +1000
|
||||
Subject: [PATCH 2/2] Use `stroull` instead of `stroul` to parse address
|
||||
offsets
|
||||
|
||||
---
|
||||
Ghidra/Features/Decompiler/src/decompile/cpp/space.cc | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/space.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/space.cc
|
||||
index bf4e1dc9..594b4583 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/space.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/space.cc
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "space.hh"
|
||||
#include "translate.hh"
|
||||
|
||||
+#include <climits>
|
||||
+
|
||||
namespace ghidra {
|
||||
|
||||
AttributeId ATTRIB_BASE = AttributeId("base",89);
|
||||
@@ -290,7 +292,10 @@ uintb AddrSpace::read(const string &s,int4 &size) const
|
||||
}
|
||||
}
|
||||
catch(LowlevelError &err) { // Name doesn't exist
|
||||
- offset = strtoul(s.c_str(),&tmpdata,0);
|
||||
+ offset = strtoull(s.c_str(),&tmpdata,0);
|
||||
+ if (offset == ULLONG_MAX) {
|
||||
+ throw LowlevelError("Offset outside of valid range");
|
||||
+ }
|
||||
offset = addressToByte(offset,wordsize);
|
||||
enddata = (const char *) tmpdata;
|
||||
if (enddata - s.c_str() == s.size()) { // If no size or offset override
|
||||
--
|
||||
2.39.2 (Apple Git-143)
|
||||
|
||||
+194
-12
@@ -1,42 +1,73 @@
|
||||
#
|
||||
# Copyright (c) 2022-present, Trail of Bits, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed in accordance with the terms specified in
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
# ---- Setup Ghidra Source code ----
|
||||
include_guard(GLOBAL)
|
||||
|
||||
# Set up Ghidra repo human-readable version settings
|
||||
set(sleigh_GHIDRA_RELEASE_TYPE "stable" CACHE
|
||||
STRING "Ghidra release type to use. 'HEAD' is used for active development purposes."
|
||||
set(sleigh_RELEASE_TYPE "stable" CACHE
|
||||
STRING "Release type to use. 'HEAD' is used for active development purposes."
|
||||
)
|
||||
|
||||
# This is just helper for CMake UIs. CMake does not enforce that the value matches one of those listed.
|
||||
set_property(CACHE sleigh_GHIDRA_RELEASE_TYPE PROPERTY STRINGS "stable" "HEAD")
|
||||
set_property(CACHE sleigh_RELEASE_TYPE PROPERTY STRINGS "stable" "HEAD")
|
||||
|
||||
# **** Setup pinned git info ****
|
||||
|
||||
find_package(Git REQUIRED)
|
||||
|
||||
# Ghidra pinned stable version commit
|
||||
set(ghidra_version "10.1.4")
|
||||
set(ghidra_git_tag "Ghidra_10.1.4_build")
|
||||
set(ghidra_version "11.0.2")
|
||||
set(ghidra_git_tag "Ghidra_${ghidra_version}_build")
|
||||
set(ghidra_shallow TRUE)
|
||||
|
||||
set(sleigh_ADDITIONAL_PATCHES "" CACHE STRING
|
||||
"The accepted patch format is git patch files, to be applied via git am. The format of the list is a CMake semicolon separated list.")
|
||||
|
||||
# See this thread for more details https://github.community/t/github-actions-bot-email-address/17204/5
|
||||
set(ghidra_patch_user "github-actions[bot]")
|
||||
set(ghidra_patch_email "41898282+github-actions[bot]@users.noreply.github.com")
|
||||
|
||||
# pinned stable patches list
|
||||
set(ghidra_patches
|
||||
PATCH_COMMAND git am --ignore-space-change --ignore-whitespace --no-gpg-sign
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/patches/stable/0001-Small-improvements-to-C-decompiler-testing-from-CLI.patch"
|
||||
PATCH_COMMAND "${GIT_EXECUTABLE}" config user.name "${ghidra_patch_user}" &&
|
||||
"${GIT_EXECUTABLE}" config user.email "${ghidra_patch_email}" &&
|
||||
"${GIT_EXECUTABLE}" am --ignore-space-change --ignore-whitespace --no-gpg-sign
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/stable/0001-Fix-UBSAN-errors-in-decompiler.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/stable/0002-Use-stroull-instead-of-stroul-to-parse-address-offse.patch"
|
||||
)
|
||||
|
||||
# Ghidra pinned commits used for pinning last known working HEAD commit
|
||||
if("${sleigh_GHIDRA_RELEASE_TYPE}" STREQUAL HEAD)
|
||||
if("${sleigh_RELEASE_TYPE}" STREQUAL "HEAD")
|
||||
# TODO: Try to remember to look at Ghidra/application.properties
|
||||
# TODO: CMake only likes numeric characters in the version string....
|
||||
set(ghidra_head_version "10.2")
|
||||
set(ghidra_head_version "11.1")
|
||||
set(ghidra_version "${ghidra_head_version}")
|
||||
set(ghidra_head_git_tag "7a30cefebb91ddb25a6c4030e67001202fd20936")
|
||||
set(ghidra_head_git_tag "2a7897c3661e03db2e6c1e0e42d2362b654790a2")
|
||||
set(ghidra_git_tag "${ghidra_head_git_tag}")
|
||||
set(ghidra_shallow FALSE)
|
||||
set(ghidra_patches
|
||||
PATCH_COMMAND git am --ignore-space-change --ignore-whitespace --no-gpg-sign
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/patches/HEAD/0001-Small-improvements-to-C-decompiler-testing-from-CLI.patch"
|
||||
PATCH_COMMAND "${GIT_EXECUTABLE}" config user.name "${ghidra_patch_user}" &&
|
||||
"${GIT_EXECUTABLE}" config user.email "${ghidra_patch_email}" &&
|
||||
"${GIT_EXECUTABLE}" am --ignore-space-change --ignore-whitespace --no-gpg-sign
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0001-Fix-UBSAN-errors-in-decompiler.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0002-Use-stroull-instead-of-stroul-to-parse-address-offse.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0003-Fix-sleighexample.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0004-Fix-opening-sla-files-on-Windows.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0005-Add-missing-index-check-to-prevent-errors-in-Windows.patch"
|
||||
)
|
||||
string(SUBSTRING "${ghidra_git_tag}" 0 7 ghidra_short_commit)
|
||||
else()
|
||||
set(ghidra_short_commit "${ghidra_git_tag}")
|
||||
endif()
|
||||
|
||||
list(APPEND ghidra_patches ${sleigh_ADDITIONAL_PATCHES})
|
||||
|
||||
message(STATUS "Using Ghidra version ${ghidra_version} at git ref ${ghidra_short_commit}")
|
||||
|
||||
include(FetchContent)
|
||||
@@ -58,6 +89,157 @@ message(STATUS "Ghidra source located at '${ghidrasource_SOURCE_DIR}'")
|
||||
|
||||
# Sanity check on Ghidra source code checkout
|
||||
set(library_root "${ghidrasource_SOURCE_DIR}/Ghidra/Features/Decompiler/src/decompile/cpp")
|
||||
|
||||
if(NOT EXISTS "${library_root}/sleigh.hh")
|
||||
message(FATAL_ERROR "The Ghidra source directory has not been initialized correctly. Could not find '${library_root}'")
|
||||
endif()
|
||||
|
||||
# Source collection variables
|
||||
set(sleigh_core_source_list
|
||||
"${library_root}/xml.cc"
|
||||
"${library_root}/space.cc"
|
||||
"${library_root}/float.cc"
|
||||
"${library_root}/address.cc"
|
||||
"${library_root}/pcoderaw.cc"
|
||||
"${library_root}/translate.cc"
|
||||
"${library_root}/opcodes.cc"
|
||||
"${library_root}/globalcontext.cc"
|
||||
"${library_root}/marshal.cc"
|
||||
)
|
||||
#if("${sleigh_RELEASE_TYPE}" STREQUAL "HEAD")
|
||||
# list(APPEND sleigh_core_source_list
|
||||
# )
|
||||
#endif()
|
||||
|
||||
set(sleigh_deccore_source_list
|
||||
"${library_root}/capability.cc"
|
||||
"${library_root}/architecture.cc"
|
||||
"${library_root}/options.cc"
|
||||
"${library_root}/graph.cc"
|
||||
"${library_root}/cover.cc"
|
||||
"${library_root}/block.cc"
|
||||
"${library_root}/cast.cc"
|
||||
"${library_root}/typeop.cc"
|
||||
"${library_root}/database.cc"
|
||||
"${library_root}/cpool.cc"
|
||||
"${library_root}/comment.cc"
|
||||
"${library_root}/stringmanage.cc"
|
||||
"${library_root}/fspec.cc"
|
||||
"${library_root}/action.cc"
|
||||
"${library_root}/loadimage.cc"
|
||||
"${library_root}/grammar.cc"
|
||||
"${library_root}/varnode.cc"
|
||||
"${library_root}/op.cc"
|
||||
"${library_root}/type.cc"
|
||||
"${library_root}/variable.cc"
|
||||
"${library_root}/varmap.cc"
|
||||
"${library_root}/jumptable.cc"
|
||||
"${library_root}/emulate.cc"
|
||||
"${library_root}/emulateutil.cc"
|
||||
"${library_root}/flow.cc"
|
||||
"${library_root}/userop.cc"
|
||||
"${library_root}/funcdata.cc"
|
||||
"${library_root}/funcdata_block.cc"
|
||||
"${library_root}/funcdata_op.cc"
|
||||
"${library_root}/funcdata_varnode.cc"
|
||||
"${library_root}/pcodeinject.cc"
|
||||
"${library_root}/heritage.cc"
|
||||
"${library_root}/prefersplit.cc"
|
||||
"${library_root}/rangeutil.cc"
|
||||
"${library_root}/ruleaction.cc"
|
||||
"${library_root}/subflow.cc"
|
||||
"${library_root}/blockaction.cc"
|
||||
"${library_root}/merge.cc"
|
||||
"${library_root}/double.cc"
|
||||
"${library_root}/transform.cc"
|
||||
"${library_root}/coreaction.cc"
|
||||
"${library_root}/condexe.cc"
|
||||
"${library_root}/override.cc"
|
||||
"${library_root}/dynamic.cc"
|
||||
"${library_root}/crc32.cc"
|
||||
"${library_root}/prettyprint.cc"
|
||||
"${library_root}/printlanguage.cc"
|
||||
"${library_root}/printc.cc"
|
||||
"${library_root}/printjava.cc"
|
||||
"${library_root}/memstate.cc"
|
||||
"${library_root}/opbehavior.cc"
|
||||
"${library_root}/paramid.cc"
|
||||
"${library_root}/unionresolve.cc"
|
||||
"${library_root}/modelrules.cc"
|
||||
"${library_root}/signature.cc"
|
||||
)
|
||||
# if("${sleigh_RELEASE_TYPE}" STREQUAL "HEAD")
|
||||
# list(APPEND sleigh_deccore_source_list
|
||||
# )
|
||||
# endif()
|
||||
|
||||
set(sleigh_extra_source_list
|
||||
"${library_root}/callgraph.cc"
|
||||
"${library_root}/ifacedecomp.cc"
|
||||
"${library_root}/ifaceterm.cc"
|
||||
"${library_root}/inject_sleigh.cc"
|
||||
"${library_root}/interface.cc"
|
||||
"${library_root}/libdecomp.cc"
|
||||
"${library_root}/loadimage_xml.cc"
|
||||
"${library_root}/raw_arch.cc"
|
||||
"${library_root}/rulecompile.cc"
|
||||
"${library_root}/sleigh_arch.cc"
|
||||
"${library_root}/testfunction.cc"
|
||||
"${library_root}/unify.cc"
|
||||
"${library_root}/xml_arch.cc"
|
||||
)
|
||||
|
||||
set(sleigh_source_list
|
||||
"${library_root}/sleigh.cc"
|
||||
"${library_root}/pcodeparse.cc"
|
||||
"${library_root}/pcodecompile.cc"
|
||||
"${library_root}/sleighbase.cc"
|
||||
"${library_root}/slghsymbol.cc"
|
||||
"${library_root}/slghpatexpress.cc"
|
||||
"${library_root}/slghpattern.cc"
|
||||
"${library_root}/semantics.cc"
|
||||
"${library_root}/context.cc"
|
||||
"${library_root}/filemanage.cc"
|
||||
)
|
||||
if("${sleigh_RELEASE_TYPE}" STREQUAL "HEAD")
|
||||
list(APPEND sleigh_source_list
|
||||
"${library_root}/slaformat.cc"
|
||||
"${library_root}/compression.cc"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(sleigh_ghidra_source_list
|
||||
"${library_root}/ghidra_arch.cc"
|
||||
"${library_root}/inject_ghidra.cc"
|
||||
"${library_root}/ghidra_translate.cc"
|
||||
"${library_root}/loadimage_ghidra.cc"
|
||||
"${library_root}/typegrp_ghidra.cc"
|
||||
"${library_root}/database_ghidra.cc"
|
||||
"${library_root}/ghidra_context.cc"
|
||||
"${library_root}/cpool_ghidra.cc"
|
||||
"${library_root}/ghidra_process.cc"
|
||||
"${library_root}/comment_ghidra.cc"
|
||||
"${library_root}/string_ghidra.cc"
|
||||
"${library_root}/signature_ghidra.cc"
|
||||
)
|
||||
# if("${sleigh_RELEASE_TYPE}" STREQUAL "HEAD")
|
||||
# list(APPEND sleigh_ghidra_source_list
|
||||
# )
|
||||
# endif()
|
||||
|
||||
set(sleigh_slacomp_source_list
|
||||
"${library_root}/slgh_compile.cc"
|
||||
"${library_root}/slghparse.cc"
|
||||
"${library_root}/slghscan.cc"
|
||||
)
|
||||
|
||||
# Include separate file to make it easier to find user-specified compile
|
||||
# options
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/compile_options.cmake")
|
||||
|
||||
# Sets 'spec_file_list' variable
|
||||
if(sleigh_RELEASE_IS_HEAD)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/spec_files_HEAD.cmake")
|
||||
else()
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/spec_files_stable.cmake")
|
||||
endif()
|
||||
|
||||
@@ -28,11 +28,14 @@ set(spec_file_list
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/ARM/data/languages/ARM7_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/ARM/data/languages/ARM8_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/ARM/data/languages/ARM8_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/ARM/data/languages/ARM8m_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/ARM/data/languages/ARM8m_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Atmel/data/languages/avr32a.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Atmel/data/languages/avr8.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Atmel/data/languages/avr8e.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Atmel/data/languages/avr8eind.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Atmel/data/languages/avr8xmega.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/BPF/data/languages/BPF_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/CR16/data/languages/CR16B.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/CR16/data/languages/CR16C.slaspec"
|
||||
@@ -52,8 +55,14 @@ set(spec_file_list
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/HCS08/data/languages/HC05.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/HCS08/data/languages/HC08.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/HCS08/data/languages/HCS08.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/HCS12/data/languages/HC12.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/HCS12/data/languages/HCS12.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/HCS12/data/languages/HCS12X.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/JVM/data/languages/JVM.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Loongarch/data/languages/loongarch32_f32.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Loongarch/data/languages/loongarch32_f64.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Loongarch/data/languages/loongarch64_f32.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Loongarch/data/languages/loongarch64_f64.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/M8C/data/languages/m8c.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/MC6800/data/languages/6805.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/MC6800/data/languages/6809.slaspec"
|
||||
@@ -82,6 +91,10 @@ set(spec_file_list
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_4xx_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_4xx_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_e500_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_e500_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_e500mc_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_e500mc_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_quicciii_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_quicciii_le.slaspec"
|
||||
@@ -117,8 +130,11 @@ set(spec_file_list
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy_wsz_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy_wsz_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/V850/data/languages/V850.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Xtensa/data/languages/xtensa_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Xtensa/data/languages/xtensa_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Z80/data/languages/z180.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Z80/data/languages/z80.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/eBPF/data/languages/eBPF_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/tricore/data/languages/tricore.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/x86/data/languages/x86-64.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/x86/data/languages/x86.slaspec"
|
||||
@@ -28,11 +28,14 @@ set(spec_file_list
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/ARM/data/languages/ARM7_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/ARM/data/languages/ARM8_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/ARM/data/languages/ARM8_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/ARM/data/languages/ARM8m_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/ARM/data/languages/ARM8m_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Atmel/data/languages/avr32a.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Atmel/data/languages/avr8.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Atmel/data/languages/avr8e.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Atmel/data/languages/avr8eind.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Atmel/data/languages/avr8xmega.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/BPF/data/languages/BPF_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/CR16/data/languages/CR16B.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/CR16/data/languages/CR16C.slaspec"
|
||||
@@ -52,8 +55,14 @@ set(spec_file_list
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/HCS08/data/languages/HC05.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/HCS08/data/languages/HC08.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/HCS08/data/languages/HCS08.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/HCS12/data/languages/HC12.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/HCS12/data/languages/HCS12.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/HCS12/data/languages/HCS12X.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/JVM/data/languages/JVM.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Loongarch/data/languages/loongarch32_f32.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Loongarch/data/languages/loongarch32_f64.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Loongarch/data/languages/loongarch64_f32.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Loongarch/data/languages/loongarch64_f64.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/M8C/data/languages/m8c.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/MC6800/data/languages/6805.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/MC6800/data/languages/6809.slaspec"
|
||||
@@ -82,6 +91,10 @@ set(spec_file_list
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_4xx_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_4xx_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_e500_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_e500_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_e500mc_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_e500mc_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_quicciii_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_quicciii_le.slaspec"
|
||||
@@ -117,8 +130,11 @@ set(spec_file_list
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy_wsz_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy_wsz_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/V850/data/languages/V850.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Xtensa/data/languages/xtensa_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Xtensa/data/languages/xtensa_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Z80/data/languages/z180.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Z80/data/languages/z80.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/eBPF/data/languages/eBPF_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/tricore/data/languages/tricore.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/x86/data/languages/x86-64.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/x86/data/languages/x86.slaspec"
|
||||
+58
-15
@@ -9,7 +9,7 @@
|
||||
# Generate the build and install directories to use in the support helpers
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_LIST_DIR}/SpecFilePaths.h.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/SpecFilePaths.h"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/include/sleigh/SpecFilePaths.h"
|
||||
@ONLY
|
||||
)
|
||||
|
||||
@@ -22,8 +22,10 @@ configure_file(
|
||||
# the source code for watching a git repository.
|
||||
set(PRE_CONFIGURE_FILE "${CMAKE_CURRENT_LIST_DIR}/Version.cpp.in")
|
||||
set(POST_CONFIGURE_FILE "${CMAKE_CURRENT_BINARY_DIR}/Version.cpp")
|
||||
set(GIT_STATE_FILE "${CMAKE_CURRENT_BINARY_DIR}/git-state-sleigh")
|
||||
set(GIT_WORKING_DIR "${PROJECT_SOURCE_DIR}")
|
||||
set(GIT_FAIL_IF_NONZERO_EXIT OFF)
|
||||
include("${PROJECT_SOURCE_DIR}/cmake/git_watcher.cmake")
|
||||
include("../cmake/git_watcher.cmake")
|
||||
|
||||
# Generate GHIDRA version helpers
|
||||
configure_file(
|
||||
@@ -32,26 +34,67 @@ configure_file(
|
||||
@ONLY
|
||||
)
|
||||
|
||||
add_library(support
|
||||
add_library(sleigh_support
|
||||
Support.cpp
|
||||
"${POST_CONFIGURE_FILE}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/GhidraVersion.cpp"
|
||||
)
|
||||
add_library(sleigh::support ALIAS sleigh_support)
|
||||
|
||||
# Need to explicitly add this dependency because BYPRODUCTS doesn't work under
|
||||
# CMake 3.16 with GNU Makefiles
|
||||
add_dependencies(support check_git)
|
||||
add_dependencies(sleigh_support check_git)
|
||||
|
||||
add_library(sleigh::support ALIAS support)
|
||||
|
||||
target_compile_features(support PUBLIC
|
||||
cxx_std_17
|
||||
target_compile_features(sleigh_support PUBLIC cxx_std_17)
|
||||
set_target_properties(sleigh_support PROPERTIES
|
||||
EXPORT_NAME support
|
||||
OUTPUT_NAME slaSupport
|
||||
)
|
||||
target_include_directories(sleigh_support
|
||||
${warning_guard}
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
)
|
||||
target_include_directories(sleigh_support
|
||||
SYSTEM
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
|
||||
# For libconfig.h
|
||||
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>"
|
||||
)
|
||||
|
||||
set_target_properties(support PROPERTIES
|
||||
INTERFACE_POSITION_INDEPENDENT_CODE ON
|
||||
)
|
||||
if(NOT CMAKE_SKIP_INSTALL_RULES)
|
||||
if(PROJECT_IS_TOP_LEVEL)
|
||||
set(CMAKE_INSTALL_INCLUDEDIR include/sleigh CACHE PATH "")
|
||||
endif()
|
||||
|
||||
target_include_directories(support PRIVATE
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>"
|
||||
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/support>"
|
||||
)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
install(
|
||||
TARGETS sleigh_support
|
||||
EXPORT sleighSupportTargets
|
||||
RUNTIME #
|
||||
COMPONENT sleigh_SupportRuntime
|
||||
LIBRARY #
|
||||
COMPONENT sleigh_SupportRuntime
|
||||
NAMELINK_COMPONENT sleigh_SupportDevelopment
|
||||
ARCHIVE #
|
||||
COMPONENT sleigh_SupportDevelopment
|
||||
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY
|
||||
include/
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/include/"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
COMPONENT sleigh_SupportDevelopment
|
||||
)
|
||||
|
||||
install(
|
||||
EXPORT sleighSupportTargets
|
||||
DESTINATION "${sleigh_INSTALL_CMAKEDIR}"
|
||||
NAMESPACE sleigh::
|
||||
COMPONENT sleigh_SupportDevelopment
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
the LICENSE file found in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "Version.h"
|
||||
#include "sleigh/Version.h"
|
||||
|
||||
namespace sleigh {
|
||||
|
||||
@@ -15,7 +15,7 @@ std::string_view GetGhidraVersion(void) { return "@ghidra_version@"; }
|
||||
std::string_view GetGhidraCommitHash(void) { return "@ghidra_git_tag@"; }
|
||||
|
||||
std::string_view GetGhidraReleaseType(void) {
|
||||
return "@sleigh_GHIDRA_RELEASE_TYPE@";
|
||||
return "@sleigh_RELEASE_TYPE@";
|
||||
}
|
||||
|
||||
} // namespace sleigh
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
|
||||
namespace sleigh {
|
||||
|
||||
static const char *kSleighSpecInstallDir = "@sleigh_SPEC_INSTALL_DIR@";
|
||||
static const char *kSleighSpecBuildDir = "@sleigh_SPEC_BUILD_DIR@";
|
||||
static const char *kSleighSpecInstallDir = "@sleigh_INSTALL_SPECDIR@";
|
||||
static const char *kSleighFullSpecInstallDir =
|
||||
"@CMAKE_INSTALL_PREFIX@/@sleigh_INSTALL_SPECDIR@";
|
||||
static const char *kSleighSpecBuildDir = "@spec_files_build_dir@";
|
||||
|
||||
} // namespace sleigh
|
||||
|
||||
+4
-4
@@ -6,9 +6,9 @@
|
||||
the LICENSE file found in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "SpecFilePaths.h"
|
||||
#include "sleigh/Support.h"
|
||||
|
||||
#include "Support.h"
|
||||
#include "sleigh/SpecFilePaths.h"
|
||||
|
||||
namespace sleigh {
|
||||
|
||||
@@ -18,7 +18,7 @@ std::optional<std::filesystem::path>
|
||||
FindSpecFileInSearchPath(std::string_view file_name,
|
||||
std::filesystem::path search_path) {
|
||||
search_path.append("Ghidra").append("Processors");
|
||||
// Check whether a SLEIGH installation exists at this path
|
||||
// Check whether a Sleigh installation exists at this path
|
||||
if (!std::filesystem::is_directory(search_path)) {
|
||||
return {};
|
||||
}
|
||||
@@ -46,7 +46,7 @@ FindSpecFileInSearchPath(std::string_view file_name,
|
||||
|
||||
const std::vector<std::filesystem::path> gDefaultSearchPaths = {
|
||||
// Derived from the installation
|
||||
kSleighSpecInstallDir,
|
||||
kSleighFullSpecInstallDir,
|
||||
// Derived from the build
|
||||
kSleighSpecBuildDir,
|
||||
// Common install locations
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "Version.h"
|
||||
#include "sleigh/Version.h"
|
||||
|
||||
namespace sleigh {
|
||||
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
Copyright (c) 2021-present, Trail of Bits, Inc.
|
||||
All rights reserved.
|
||||
|
||||
This source code is licensed in accordance with the terms specified in
|
||||
the LICENSE file found in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <sleigh/libconfig.h>
|
||||
|
||||
#pragma once
|
||||
#ifndef _MSC_VER
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated"
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#endif
|
||||
#include <ghidra/action.hh>
|
||||
#include <ghidra/address.hh>
|
||||
#include <ghidra/architecture.hh>
|
||||
#include <ghidra/block.hh>
|
||||
#include <ghidra/blockaction.hh>
|
||||
#include <ghidra/callgraph.hh>
|
||||
#include <ghidra/capability.hh>
|
||||
#include <ghidra/cast.hh>
|
||||
#include <ghidra/codedata.hh>
|
||||
#include <ghidra/comment.hh>
|
||||
#include <ghidra/comment_ghidra.hh>
|
||||
#include <ghidra/condexe.hh>
|
||||
#include <ghidra/context.hh>
|
||||
#include <ghidra/coreaction.hh>
|
||||
#include <ghidra/cover.hh>
|
||||
#include <ghidra/cpool.hh>
|
||||
#include <ghidra/cpool_ghidra.hh>
|
||||
#include <ghidra/crc32.hh>
|
||||
#include <ghidra/database.hh>
|
||||
#include <ghidra/database_ghidra.hh>
|
||||
#include <ghidra/doccore.hh>
|
||||
#include <ghidra/docmain.hh>
|
||||
#include <ghidra/double.hh>
|
||||
#include <ghidra/dynamic.hh>
|
||||
#include <ghidra/emulate.hh>
|
||||
#include <ghidra/emulateutil.hh>
|
||||
#include <ghidra/error.hh>
|
||||
#include <ghidra/filemanage.hh>
|
||||
#include <ghidra/float.hh>
|
||||
#include <ghidra/flow.hh>
|
||||
#include <ghidra/fspec.hh>
|
||||
#include <ghidra/funcdata.hh>
|
||||
#include <ghidra/ghidra_arch.hh>
|
||||
#include <ghidra/ghidra_context.hh>
|
||||
#include <ghidra/ghidra_process.hh>
|
||||
#include <ghidra/ghidra_translate.hh>
|
||||
#include <ghidra/globalcontext.hh>
|
||||
#include <ghidra/grammar.hh>
|
||||
#include <ghidra/graph.hh>
|
||||
#include <ghidra/heritage.hh>
|
||||
#include <ghidra/ifacedecomp.hh>
|
||||
#include <ghidra/ifaceterm.hh>
|
||||
#include <ghidra/inject_ghidra.hh>
|
||||
#include <ghidra/inject_sleigh.hh>
|
||||
#include <ghidra/interface.hh>
|
||||
#include <ghidra/jumptable.hh>
|
||||
#include <ghidra/libdecomp.hh>
|
||||
#include <ghidra/loadimage.hh>
|
||||
#include <ghidra/loadimage_ghidra.hh>
|
||||
#include <ghidra/loadimage_xml.hh>
|
||||
#include <ghidra/memstate.hh>
|
||||
#include <ghidra/merge.hh>
|
||||
#include <ghidra/op.hh>
|
||||
#include <ghidra/opbehavior.hh>
|
||||
#include <ghidra/opcodes.hh>
|
||||
#include <ghidra/options.hh>
|
||||
#include <ghidra/override.hh>
|
||||
#include <ghidra/paramid.hh>
|
||||
#include <ghidra/partmap.hh>
|
||||
#include <ghidra/pcodecompile.hh>
|
||||
#include <ghidra/pcodeinject.hh>
|
||||
#include <ghidra/pcodeparse.hh>
|
||||
#include <ghidra/pcoderaw.hh>
|
||||
#include <ghidra/prefersplit.hh>
|
||||
#include <ghidra/prettyprint.hh>
|
||||
#include <ghidra/printc.hh>
|
||||
#include <ghidra/printjava.hh>
|
||||
#include <ghidra/printlanguage.hh>
|
||||
#include <ghidra/rangemap.hh>
|
||||
#include <ghidra/rangeutil.hh>
|
||||
#include <ghidra/raw_arch.hh>
|
||||
#include <ghidra/ruleaction.hh>
|
||||
#include <ghidra/rulecompile.hh>
|
||||
#include <ghidra/semantics.hh>
|
||||
#include <ghidra/sleigh.hh>
|
||||
#include <ghidra/sleigh_arch.hh>
|
||||
#include <ghidra/sleighbase.hh>
|
||||
#include <ghidra/slgh_compile.hh>
|
||||
// This is required because slghparse.hh does not have a namespace block
|
||||
namespace ghidra {
|
||||
#include <ghidra/slghparse.hh>
|
||||
} // End namespace ghidra
|
||||
#include <ghidra/slghpatexpress.hh>
|
||||
#include <ghidra/slghpattern.hh>
|
||||
#include <ghidra/slghsymbol.hh>
|
||||
#include <ghidra/space.hh>
|
||||
#include <ghidra/string_ghidra.hh>
|
||||
#include <ghidra/stringmanage.hh>
|
||||
#include <ghidra/subflow.hh>
|
||||
#include <ghidra/testfunction.hh>
|
||||
#include <ghidra/transform.hh>
|
||||
#include <ghidra/translate.hh>
|
||||
#include <ghidra/type.hh>
|
||||
#include <ghidra/typegrp_ghidra.hh>
|
||||
#include <ghidra/typeop.hh>
|
||||
#include <ghidra/types.h>
|
||||
#include <ghidra/unify.hh>
|
||||
#include <ghidra/userop.hh>
|
||||
#include <ghidra/variable.hh>
|
||||
#include <ghidra/varmap.hh>
|
||||
#include <ghidra/varnode.hh>
|
||||
#include <ghidra/xml.hh>
|
||||
#include <ghidra/xml_arch.hh>
|
||||
#include <ghidra/unionresolve.hh>
|
||||
#include <ghidra/marshal.hh>
|
||||
#include <ghidra/analyzesigs.hh>
|
||||
#include <ghidra/modelrules.hh>
|
||||
#include <ghidra/signature.hh>
|
||||
#include <ghidra/signature_ghidra.hh>
|
||||
|
||||
// #ifdef sleigh_RELEASE_IS_HEAD
|
||||
// #endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#include <sleigh/Support.h>
|
||||
#include <sleigh/Version.h>
|
||||
@@ -0,0 +1,85 @@
|
||||
#
|
||||
# Copyright (c) 2022-present, Trail of Bits, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed in accordance with the terms specified in
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
#
|
||||
# Tests from ghidra repo
|
||||
#
|
||||
|
||||
add_executable(sleigh_ghidra_test
|
||||
${sleigh_core_source_list}
|
||||
${sleigh_deccore_source_list}
|
||||
${sleigh_source_list}
|
||||
${sleigh_extra_source_list}
|
||||
|
||||
"${library_root}/test.cc"
|
||||
|
||||
"${library_root}/../unittests/testcirclerange.cc"
|
||||
"${library_root}/../unittests/testfloatemu.cc"
|
||||
"${library_root}/../unittests/testfuncproto.cc"
|
||||
"${library_root}/../unittests/testtypes.cc"
|
||||
"${library_root}/../unittests/testmarshal.cc"
|
||||
"${library_root}/../unittests/testparamstore.cc"
|
||||
)
|
||||
|
||||
# if(sleigh_RELEASE_IS_HEAD)
|
||||
# target_sources(sleigh_ghidra_test PRIVATE
|
||||
# )
|
||||
# endif()
|
||||
|
||||
target_compile_features(sleigh_ghidra_test PRIVATE cxx_std_11)
|
||||
target_include_directories(sleigh_ghidra_test PRIVATE "${library_root}")
|
||||
include(CheckIncludeFileCXX)
|
||||
check_include_file_cxx(termios.h HAVE_TERMIOS_H)
|
||||
if(HAVE_TERMIOS_H)
|
||||
target_compile_definitions(sleigh_ghidra_test PRIVATE
|
||||
__TERMINAL__
|
||||
)
|
||||
endif()
|
||||
sleigh_add_optional_defines(sleigh_ghidra_test PRIVATE)
|
||||
|
||||
if(sleigh_RELEASE_IS_HEAD)
|
||||
target_link_libraries(sleigh_ghidra_test PRIVATE ZLIB::ZLIB)
|
||||
endif()
|
||||
|
||||
add_test(
|
||||
NAME sleigh_ghidra_unittest
|
||||
COMMAND sleigh_ghidra_test -sleighpath "${PROJECT_BINARY_DIR}" unittests
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME sleigh_ghidra_datatest
|
||||
COMMAND sleigh_ghidra_test -sleighpath "${PROJECT_BINARY_DIR}"
|
||||
-path "${library_root}/../datatests"
|
||||
datatests
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# Test for removal of using namespace std patches
|
||||
#
|
||||
if(sleigh_BUILD_SUPPORT)
|
||||
add_executable(sleigh_namespace_std_test
|
||||
no_using_namespace_std.cpp
|
||||
)
|
||||
target_link_libraries(sleigh_namespace_std_test
|
||||
PRIVATE
|
||||
sleigh::sla
|
||||
sleigh::decomp
|
||||
sleigh::support
|
||||
)
|
||||
if(WIN32)
|
||||
# Ensure no issue with /permissive- and std::byte colliding deeply in the
|
||||
# sleigh headers when compiling against Windows headers
|
||||
target_compile_features(sleigh_namespace_std_test PRIVATE cxx_std_20)
|
||||
endif()
|
||||
# Really only testing that it compiles
|
||||
add_test(
|
||||
NAME sleigh_namespace_std_test
|
||||
COMMAND sleigh_namespace_std_test
|
||||
)
|
||||
endif()
|
||||
@@ -6,10 +6,10 @@
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.15.0)
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
project("sleigh_find_package_test")
|
||||
|
||||
find_package(sleigh REQUIRED)
|
||||
find_package(sleigh REQUIRED COMPONENTS Support)
|
||||
|
||||
add_executable(sleigh_test
|
||||
src/main.cpp
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
struct vector {};
|
||||
struct set {};
|
||||
struct unordered_map {};
|
||||
struct string {};
|
||||
|
||||
#include <sleigh/libsleigh.hh>
|
||||
|
||||
int main() {
|
||||
vector v;
|
||||
set s;
|
||||
unordered_map m;
|
||||
string str;
|
||||
}
|
||||
+28
-2
@@ -1,9 +1,35 @@
|
||||
#
|
||||
# Copyright (c) 2021-present, Trail of Bits, Inc.
|
||||
# Copyright (c) 2022-present, Trail of Bits, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed in accordance with the terms specified in
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
add_subdirectory(sleigh-lift)
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
include(../cmake/prelude.cmake)
|
||||
include(../src/setup-ghidra-source.cmake)
|
||||
|
||||
project(sleigh_tools
|
||||
VERSION "${ghidra_version}"
|
||||
DESCRIPTION "Sleigh tools"
|
||||
HOMEPAGE_URL "https://github.com/lifting-bits/sleigh"
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
option(sleigh_BUILD_SPECCOMPILER "Build the sleigh spec compiler executable (\"sleigh\")" ON)
|
||||
option(sleigh_BUILD_DECOMPILER "Build the decompiler executable (\"decomp\")" ON)
|
||||
option(sleigh_BUILD_GHIDRA "Build the Ghidra executable (\"ghidra\")" ON)
|
||||
|
||||
if(sleigh_BUILD_SPECCOMPILER)
|
||||
add_subdirectory(spec-compiler)
|
||||
endif()
|
||||
|
||||
if(sleigh_BUILD_DECOMPILER)
|
||||
add_subdirectory(decompiler)
|
||||
endif()
|
||||
|
||||
if(sleigh_BUILD_GHIDRA)
|
||||
add_subdirectory(ghidra)
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#
|
||||
# Copyright (c) 2022-present, Trail of Bits, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed in accordance with the terms specified in
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
include(../../cmake/prelude.cmake)
|
||||
include(../../src/setup-ghidra-source.cmake)
|
||||
|
||||
project(sleigh_decompiler
|
||||
VERSION "${ghidra_version}"
|
||||
DESCRIPTION "Sleigh decompiler"
|
||||
HOMEPAGE_URL "https://github.com/lifting-bits/sleigh"
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
include(../../cmake/project-is-top-level.cmake)
|
||||
|
||||
add_executable(sleigh_decompiler
|
||||
${sleigh_core_source_list}
|
||||
${sleigh_deccore_source_list}
|
||||
${sleigh_extra_source_list}
|
||||
${sleigh_source_list}
|
||||
|
||||
"${library_root}/consolemain.cc"
|
||||
)
|
||||
add_executable(sleigh::decompiler ALIAS sleigh_decompiler)
|
||||
|
||||
target_compile_features(sleigh_decompiler PUBLIC cxx_std_11)
|
||||
target_include_directories(sleigh_decompiler PRIVATE "$<BUILD_INTERFACE:${library_root}>")
|
||||
include(CheckIncludeFileCXX)
|
||||
check_include_file_cxx(termios.h HAVE_TERMIOS_H)
|
||||
if(HAVE_TERMIOS_H)
|
||||
target_compile_definitions(sleigh_decompiler PRIVATE
|
||||
__TERMINAL__
|
||||
)
|
||||
endif()
|
||||
target_compile_definitions(sleigh_decompiler PRIVATE
|
||||
$<$<CONFIG:Debug>:CPUI_DEBUG>
|
||||
)
|
||||
sleigh_add_optional_defines(sleigh_decompiler PRIVATE)
|
||||
|
||||
set_target_properties(sleigh_decompiler PROPERTIES
|
||||
EXPORT_NAME decompiler
|
||||
OUTPUT_NAME decomp
|
||||
OUTPUT_NAME_DEBUG decomp_dbg
|
||||
)
|
||||
|
||||
if(sleigh_RELEASE_IS_HEAD)
|
||||
find_package(ZLIB REQUIRED)
|
||||
target_link_libraries(sleigh_decompiler PRIVATE ZLIB::ZLIB)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_SKIP_INSTALL_RULES)
|
||||
include("GNUInstallDirs")
|
||||
|
||||
install(
|
||||
TARGETS sleigh_decompiler
|
||||
EXPORT sleighTargets
|
||||
RUNTIME COMPONENT sleigh_Runtime
|
||||
)
|
||||
|
||||
if(PROJECT_IS_TOP_LEVEL)
|
||||
include(CPack)
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,66 @@
|
||||
#
|
||||
# Copyright (c) 2022-present, Trail of Bits, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed in accordance with the terms specified in
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
include(../../cmake/prelude.cmake)
|
||||
include(../../src/setup-ghidra-source.cmake)
|
||||
|
||||
project(sleigh_ghidra
|
||||
VERSION "${ghidra_version}"
|
||||
DESCRIPTION "Sleigh ghidra service"
|
||||
HOMEPAGE_URL "https://github.com/lifting-bits/sleigh"
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
include(../../cmake/project-is-top-level.cmake)
|
||||
|
||||
add_executable(sleigh_ghidra
|
||||
${sleigh_core_source_list}
|
||||
${sleigh_deccore_source_list}
|
||||
${sleigh_ghidra_source_list}
|
||||
|
||||
"$<$<CONFIG:Debug>:${library_root}/callgraph.cc>"
|
||||
"$<$<CONFIG:Debug>:${library_root}/ifacedecomp.cc>"
|
||||
"$<$<CONFIG:Debug>:${library_root}/ifaceterm.cc>"
|
||||
"$<$<CONFIG:Debug>:${library_root}/interface.cc>"
|
||||
"$<$<CONFIG:Debug>:${library_root}/testfunction.cc>"
|
||||
)
|
||||
add_executable(sleigh::ghidra ALIAS sleigh_ghidra)
|
||||
|
||||
target_compile_features(sleigh_ghidra PUBLIC cxx_std_11)
|
||||
target_include_directories(sleigh_ghidra PRIVATE "$<BUILD_INTERFACE:${library_root}>")
|
||||
target_compile_definitions(sleigh_ghidra PRIVATE
|
||||
$<$<CONFIG:Debug>:CPUI_DEBUG>
|
||||
)
|
||||
sleigh_add_optional_defines(sleigh_ghidra PRIVATE)
|
||||
|
||||
set_target_properties(sleigh_ghidra PROPERTIES
|
||||
EXPORT_NAME ghidra
|
||||
OUTPUT_NAME ghidra
|
||||
OUTPUT_NAME_DEBUG ghidra_dbg
|
||||
)
|
||||
|
||||
if(sleigh_RELEASE_IS_HEAD)
|
||||
find_package(ZLIB REQUIRED)
|
||||
target_link_libraries(sleigh_ghidra PRIVATE ZLIB::ZLIB)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_SKIP_INSTALL_RULES)
|
||||
include("GNUInstallDirs")
|
||||
|
||||
install(
|
||||
TARGETS sleigh_ghidra
|
||||
EXPORT sleighTargets
|
||||
RUNTIME COMPONENT sleigh_Runtime
|
||||
)
|
||||
|
||||
if(PROJECT_IS_TOP_LEVEL)
|
||||
include(CPack)
|
||||
endif()
|
||||
endif()
|
||||
@@ -1,36 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2021-present, Trail of Bits, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed in accordance with the terms specified in
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
add_executable(sleigh-lift
|
||||
src/main.cpp
|
||||
)
|
||||
add_executable(sleigh::sleigh-lift ALIAS sleigh-lift)
|
||||
|
||||
target_link_libraries(sleigh-lift PRIVATE
|
||||
sleigh::sla
|
||||
sleigh::decomp
|
||||
sleigh::support
|
||||
)
|
||||
|
||||
if(NOT CMAKE_SKIP_INSTALL_RULES)
|
||||
install(
|
||||
TARGETS
|
||||
sleigh-lift
|
||||
|
||||
EXPORT
|
||||
"sleigh"
|
||||
|
||||
DESTINATION
|
||||
"${CMAKE_INSTALL_BINDIR}"
|
||||
|
||||
PERMISSIONS
|
||||
OWNER_READ OWNER_WRITE OWNER_EXECUTE
|
||||
GROUP_READ GROUP_EXECUTE
|
||||
WORLD_READ WORLD_EXECUTE
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,56 @@
|
||||
#
|
||||
# Copyright (c) 2022-present, Trail of Bits, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed in accordance with the terms specified in
|
||||
# the LICENSE file found in the root directory of this source tree.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
include(../../cmake/prelude.cmake)
|
||||
include(../../src/setup-ghidra-source.cmake)
|
||||
|
||||
project(sleigh_sleigh
|
||||
VERSION "${ghidra_version}"
|
||||
DESCRIPTION "Sleigh spec compiler"
|
||||
HOMEPAGE_URL "https://github.com/lifting-bits/sleigh"
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
include(../../cmake/project-is-top-level.cmake)
|
||||
|
||||
add_executable(sleigh_sleigh
|
||||
${sleigh_core_source_list}
|
||||
${sleigh_source_list}
|
||||
${sleigh_slacomp_source_list}
|
||||
)
|
||||
add_executable(sleigh::sleigh ALIAS sleigh_sleigh)
|
||||
|
||||
target_compile_features(sleigh_sleigh PUBLIC cxx_std_11)
|
||||
target_include_directories(sleigh_sleigh PRIVATE "$<BUILD_INTERFACE:${library_root}>")
|
||||
sleigh_add_optional_defines(sleigh_sleigh PRIVATE)
|
||||
set_target_properties(sleigh_sleigh PROPERTIES
|
||||
EXPORT_NAME sleigh
|
||||
OUTPUT_NAME sleigh
|
||||
OUTPUT_NAME_DEBUG sleigh_dbg
|
||||
)
|
||||
|
||||
if(sleigh_RELEASE_IS_HEAD)
|
||||
find_package(ZLIB REQUIRED)
|
||||
target_link_libraries(sleigh_sleigh PRIVATE ZLIB::ZLIB)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_SKIP_INSTALL_RULES)
|
||||
include("GNUInstallDirs")
|
||||
|
||||
install(
|
||||
TARGETS sleigh_sleigh
|
||||
EXPORT sleighTargets
|
||||
RUNTIME COMPONENT sleigh_Runtime
|
||||
)
|
||||
|
||||
if(PROJECT_IS_TOP_LEVEL)
|
||||
include(CPack)
|
||||
endif()
|
||||
endif()
|
||||
Reference in New Issue
Block a user