Add REMILL_FETCH_SLEIGH option to allow find_package(sleigh)

This commit is contained in:
Duncan Ogilvie
2026-04-20 14:14:18 +02:00
committed by Kyle Elliott
parent 7055a0c54a
commit 71b1915a7e
21 changed files with 152 additions and 45 deletions
+16 -4
View File
@@ -58,7 +58,10 @@ jobs:
- name: Build dependencies
run: |
cmake -G Ninja -S dependencies -B dependencies/build -DUSE_EXTERNAL_LLVM=ON "-DCMAKE_PREFIX_PATH:PATH=$LLVM_PREFIX"
cmake -G Ninja -S dependencies -B dependencies/build \
-DUSE_EXTERNAL_LLVM=ON \
-DENABLE_SLEIGH=ON \
"-DCMAKE_PREFIX_PATH:PATH=$LLVM_PREFIX"
cmake --build dependencies/build
- name: Python venv for tests
@@ -69,7 +72,10 @@ jobs:
- name: Build remill
run: |
. .venv/bin/activate
cmake -G Ninja -B build "-DCMAKE_PREFIX_PATH:PATH=$PWD/dependencies/install" "-DCMAKE_INSTALL_PREFIX=$PWD/install"
cmake -G Ninja -B build \
-DREMILL_FETCH_SLEIGH=OFF \
"-DCMAKE_PREFIX_PATH:PATH=$PWD/dependencies/install" \
"-DCMAKE_INSTALL_PREFIX=$PWD/install"
cmake --build build
- name: Install remill
@@ -147,7 +153,10 @@ jobs:
- name: Build dependencies
run: |
cmake -G Ninja -S dependencies -B dependencies/build -DUSE_EXTERNAL_LLVM=ON "-DCMAKE_PREFIX_PATH:PATH=$LLVM_PREFIX"
cmake -G Ninja -S dependencies -B dependencies/build \
-DUSE_EXTERNAL_LLVM=ON \
-DENABLE_SLEIGH=ON \
"-DCMAKE_PREFIX_PATH:PATH=$LLVM_PREFIX"
cmake --build dependencies/build
- name: Python venv for tests
@@ -158,7 +167,10 @@ jobs:
- name: Build remill
run: |
. .venv/bin/activate
cmake -G Ninja -B build "-DCMAKE_PREFIX_PATH:PATH=$PWD/dependencies/install" "-DCMAKE_INSTALL_PREFIX=$PWD/install"
cmake -G Ninja -B build \
-DREMILL_FETCH_SLEIGH=OFF \
"-DCMAKE_PREFIX_PATH:PATH=$PWD/dependencies/install" \
"-DCMAKE_INSTALL_PREFIX=$PWD/install"
cmake --build build
- name: Install remill
+51 -35
View File
@@ -88,29 +88,35 @@ find_package(glog CONFIG REQUIRED)
set(GFLAGS_USE_TARGET_NAMESPACE ON)
find_package(gflags CONFIG REQUIRED)
option(REMILL_FETCH_SLEIGH "Fetch and build sleigh as part of remill" ON)
# Sleigh
file(GLOB sleigh_patches "${CMAKE_CURRENT_SOURCE_DIR}/patches/sleigh/*.patch")
set(sleigh_ADDITIONAL_PATCHES "${sleigh_patches}" CACHE STRING "" FORCE)
set(sleigh_ENABLE_TESTS OFF CACHE BOOL "" FORCE)
set(sleigh_RELEASE_TYPE "HEAD" CACHE STRING "" FORCE)
set(sleigh_BUILD_SUPPORT ON CACHE BOOL "" FORCE)
set(sleigh_BUILD_SLEIGHSPECS ON CACHE BOOL "" FORCE)
if(REMILL_FETCH_SLEIGH)
file(GLOB sleigh_patches "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/sleigh_patches/*.patch")
set(sleigh_ADDITIONAL_PATCHES "${sleigh_patches}" CACHE STRING "" FORCE)
set(sleigh_ENABLE_TESTS OFF CACHE BOOL "" FORCE)
set(sleigh_RELEASE_TYPE "HEAD" CACHE STRING "" FORCE)
set(sleigh_BUILD_SUPPORT ON CACHE BOOL "" FORCE)
set(sleigh_BUILD_SLEIGHSPECS ON CACHE BOOL "" FORCE)
# Verbose fetch content updates
set(FETCHCONTENT_QUIET OFF)
# Verbose fetch content updates
set(FETCHCONTENT_QUIET OFF)
# This version of sleigh (HEAD) pins Ghidra somewhere between Ghidra v10.2.3 and v10.3
# https://github.com/lifting-bits/sleigh/blob/7c6b742/src/setup-ghidra-source.cmake#L55-L66
FetchContent_Declare(sleigh
GIT_REPOSITORY https://github.com/lifting-bits/sleigh.git
GIT_TAG 7c6b742
)
FetchContent_MakeAvailable(sleigh)
# This version of sleigh (HEAD) pins Ghidra somewhere between Ghidra v10.2.3 and v10.3
# https://github.com/lifting-bits/sleigh/blob/7c6b742/src/setup-ghidra-source.cmake#L55-L66
FetchContent_Declare(sleigh
GIT_REPOSITORY https://github.com/lifting-bits/sleigh.git
GIT_TAG 7c6b742
)
FetchContent_MakeAvailable(sleigh)
# Get the Ghidra source directory from FetchContent's internal tracking
FetchContent_GetProperties(GhidraSource)
if(NOT ghidrasource_POPULATED)
message(FATAL_ERROR "Expected sleigh to populate GhidraSource")
# Get the Ghidra source directory from FetchContent's internal tracking
FetchContent_GetProperties(GhidraSource)
if(NOT ghidrasource_POPULATED)
message(FATAL_ERROR "Expected sleigh to populate GhidraSource")
endif()
else()
find_package(sleigh CONFIG REQUIRED COMPONENTS Support Specs)
endif()
# For Linux builds, group LLVM libraries into a single group
@@ -219,23 +225,35 @@ target_compile_definitions(remill_settings INTERFACE
"REMILL_BUILD_SEMANTICS_DIR_PPC64_32ADDR=\"${REMILL_BUILD_SEMANTICS_DIR_PPC64_32ADDR}\""
)
if(SLEIGH_EXECUTABLE)
set(sleigh_compiler "${SLEIGH_EXECUTABLE}")
if(REMILL_FETCH_SLEIGH)
if(SLEIGH_EXECUTABLE)
set(sleigh_compiler "${SLEIGH_EXECUTABLE}")
else()
set(sleigh_compiler "$<TARGET_FILE:sleigh::sleigh>")
endif()
sleigh_compile(
TARGET ppc_e200_spec
COMPILER "${sleigh_compiler}"
SLASPEC "${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_e200_be.slaspec"
LOG_FILE "${sleigh_BINARY_DIR}/sleighspecs/spec_build_logs/ppc_32_e200_be.sla.log"
OUT_FILE "${sleigh_BINARY_DIR}/specfiles/Ghidra/Processors/PowerPC/data/languages/ppc_32_e200_be.sla"
)
add_custom_target(sleigh_custom_specs)
add_dependencies(sleigh_custom_specs ppc_e200_spec)
if(REMILL_ENABLE_INSTALL_TARGET)
install(FILES "${sleigh_BINARY_DIR}/specfiles/Ghidra/Processors/PowerPC/data/languages/ppc_32_e200_be.sla"
DESTINATION "${CMAKE_INSTALL_DATADIR}/sleigh/specfiles/Ghidra/Processors/PowerPC/data/languages/")
endif()
else()
set(sleigh_compiler "$<TARGET_FILE:sleigh::sleigh>")
if(NOT EXISTS "${sleigh_INSTALL_SPECDIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_e200_be.sla")
message(FATAL_ERROR "Installed sleigh spec not found: ${sleigh_INSTALL_SPECDIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_e200_be.sla")
endif()
add_custom_target(sleigh_custom_specs)
endif()
sleigh_compile(
TARGET ppc_e200_spec
COMPILER "${sleigh_compiler}"
SLASPEC "${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_32_e200_be.slaspec"
LOG_FILE "${sleigh_BINARY_DIR}/sleighspecs/spec_build_logs/ppc_32_e200_be.sla.log"
OUT_FILE "${sleigh_BINARY_DIR}/specfiles/Ghidra/Processors/PowerPC/data/languages/ppc_32_e200_be.sla"
)
add_custom_target(sleigh_custom_specs)
add_dependencies(sleigh_custom_specs ppc_e200_spec)
target_link_libraries(remill_settings INTERFACE
${llvm_libs}
XED::XED
@@ -295,8 +313,6 @@ if(REMILL_ENABLE_INSTALL_TARGET)
EXPORT remillTargets
)
install(FILES "${sleigh_BINARY_DIR}/specfiles/Ghidra/Processors/PowerPC/data/languages/ppc_32_e200_be.sla" DESTINATION "${CMAKE_INSTALL_DATADIR}/sleigh/specfiles/Ghidra/Processors/PowerPC/data/languages/")
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/remillConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/remillConfig.cmake"
+31
View File
@@ -11,6 +11,7 @@ project(dependencies)
option(USE_EXTERNAL_LLVM "Do not compile LLVM as part of the superbuild, use an external one instead" OFF)
option(USE_SANITIZERS "Use ASan and UBSan" OFF)
option(ENABLE_SLEIGH "Build and install sleigh into the dependencies prefix" OFF)
if(USE_EXTERNAL_LLVM)
if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin" AND NOT CMAKE_PREFIX_PATH)
@@ -70,3 +71,33 @@ else()
file(REMOVE "${LLVM_CONFIG}")
include(llvm.cmake)
endif()
if(ENABLE_SLEIGH)
file(GLOB sleigh_patches LIST_DIRECTORIES FALSE
"${CMAKE_CURRENT_LIST_DIR}/sleigh_patches/*.patch"
)
list(SORT sleigh_patches)
if(NOT sleigh_patches)
message(FATAL_ERROR "ENABLE_SLEIGH did not find any patches in sleigh_patches")
endif()
string(REPLACE ";" "\\;" sleigh_patches_arg "${sleigh_patches}")
simple_git(https://github.com/lifting-bits/sleigh 7c6b742
"-Dsleigh_ADDITIONAL_PATCHES:STRING=${sleigh_patches_arg}"
"-Dsleigh_ENABLE_TESTS:BOOL=OFF"
"-Dsleigh_RELEASE_TYPE:STRING=HEAD"
"-Dsleigh_BUILD_SUPPORT:BOOL=ON"
"-Dsleigh_BUILD_SLEIGHSPECS:BOOL=ON"
)
ExternalProject_Add_Step(sleigh ppc_e200_spec_install
COMMAND
"${CMAKE_COMMAND}"
"-Dinstall_prefix:PATH=${CMAKE_INSTALL_PREFIX}"
"-Dbinary_dir:PATH=<BINARY_DIR>"
-P "${CMAKE_CURRENT_LIST_DIR}/build_ppc_e200_sla.cmake"
DEPENDEES install
)
endif()
+12
View File
@@ -10,3 +10,15 @@ cmake --build build
```
This will create a [CMake prefix](https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure), which you pass to your project with `-DCMAKE_PREFIX_PATH:FILEPATH=/path/to/dependencies/install`. See [presentation.md](https://github.com/LLVMParty/packages/blob/main/presentation.md) and [dependencies.md](https://github.com/LLVMParty/packages/blob/main/dependencies.md) for more information.
## Optional sleigh install
To also build and install `sleigh` into the same prefix, enable `ENABLE_SLEIGH`.
By default it uses Remill's local patch set from `./sleigh_patches`.
```sh
cmake -B build -DCMAKE_BUILD_TYPE=Release -DENABLE_SLEIGH=ON
cmake --build build
```
For the Docker image, pass `--build-arg ENABLE_SLEIGH=ON` to build and install sleigh there as well.
+36
View File
@@ -0,0 +1,36 @@
set(install_prefix "${install_prefix}")
set(binary_dir "${binary_dir}")
set(spec_file
"${binary_dir}/_deps/ghidrasource-src/Ghidra/Processors/PowerPC/data/languages/ppc_32_e200_be.slaspec")
set(out_dir
"${install_prefix}/share/sleigh/specfiles/Ghidra/Processors/PowerPC/data/languages")
set(out_file "${out_dir}/ppc_32_e200_be.sla")
set(log_dir "${binary_dir}/sleighspecs/spec_build_logs")
set(log_file "${log_dir}/ppc_32_e200_be.sla.log")
if(NOT EXISTS "${spec_file}")
message(FATAL_ERROR "Missing ppc_32_e200_be.slaspec: ${spec_file}")
endif()
find_program(sleigh_compiler NAMES sleigh sleigh.exe
PATHS "${install_prefix}/bin"
NO_DEFAULT_PATH
REQUIRED)
get_filename_component(spec_dir "${spec_file}" DIRECTORY)
file(MAKE_DIRECTORY "${out_dir}")
file(MAKE_DIRECTORY "${log_dir}")
execute_process(
COMMAND "${sleigh_compiler}" "${spec_file}" "${out_file}"
WORKING_DIRECTORY "${spec_dir}"
RESULT_VARIABLE sleigh_result
OUTPUT_FILE "${log_file}"
ERROR_FILE "${log_file}"
)
if(NOT sleigh_result EQUAL 0)
message(FATAL_ERROR
"Failed to compile ppc_32_e200_be.sla with ${sleigh_compiler}. See ${log_file}")
endif()
@@ -9,9 +9,9 @@ To update the patches or the sleigh base commit, we need to get a cloned Ghidra
1. Go in `build/_deps/ghidrasource-src` and run `git status` to make sure you are in a clean state. You might need to run `git am --abort` to abort the patching process if you had patch failures.
2. Modify remill's `CMakeLists.txt` to set `sleigh_ADDITIONAL_PATCHES` to be empty and re-configure remill. This will apply just the patches of the sleigh project's tag we pinned.
3. Get the commit hash of the clean Ghidra patches with `git rev-parse HEAD` and note it as `<base-commit>`.
4. Apply the patches in `patches/sleigh/` one by one with `git am ../../../patches/sleigh/0001-xyz.patch`. If you get any errors, manually apply the patch (you can try `git apply ../../../patches/sleigh/0001-xyz.patch`) and then `git add .` followed by `git am --continue`. The goal is to create a commit for every patch.
5. Delete all the old patches: `rm patches/sleigh/*.patch`.
6. Recreate the patch list: `git format-patch remill-sleigh-7c6b742-base -o ../../../patches/sleigh/`.
7. Reconfigure remill's CMake to make sure everything applies correctly and then change `sleigh_ADDITIONAL_PATCHES` batch to include all of the patches in `patches/sleigh/`.
4. Apply the patches in `dependencies/sleigh_patches/` one by one with `git am ../../../dependencies/sleigh_patches/0001-xyz.patch`. If you get any errors, manually apply the patch (you can try `git apply ../../../dependencies/sleigh_patches/0001-xyz.patch`) and then `git add .` followed by `git am --continue`. The goal is to create a commit for every patch.
5. Delete all the old patches: `rm dependencies/sleigh_patches/*.patch`.
6. Recreate the patch list: `git format-patch remill-sleigh-7c6b742-base -o ../../../dependencies/sleigh_patches/`.
7. Reconfigure remill's CMake to make sure everything applies correctly and then change `sleigh_ADDITIONAL_PATCHES` back to include all of the patches in `dependencies/sleigh_patches/`.
**Note**: Sometimes you run into issues where `git am` cannot correctly apply all the patches. This is usually related to whitespace issues. Before exporting the patch list you can run `git rebase <base-commit> --whitespace=fix` to make sure everything is cleaned up correctly and ready to be applied.
+1 -1
View File
@@ -84,7 +84,7 @@
hash = "sha256-7Iv1awZP5lU1LpGqC0nyiMxy0+3WOmM2NTdDYIzKmmk=";
};
patches =
let dir = ./patches/sleigh;
let dir = ./dependencies/sleigh_patches;
in map (f: dir + "/${f}")
(builtins.filter (f: lib.hasSuffix ".patch" f)
(builtins.sort builtins.lessThan
@@ -1,2 +1,2 @@
Example invocation for x86 `python replace_pc_relative_disactions/main.py <target .sinc file> --out_dir <output_directory> --inst_next_size_hint "\$(SIZE)" --pc_def register_definitions/x86.ia`
Example invocation for PowerPC using `python replace_pc_relative_disactions/main.py <ghidra_dir>/Ghidra/Processors/PowerPC/data/languages/{ppc_common,ppc_embedded,ppc_instructions,ppc_isa,ppc_vle,quicciii}.sinc --pc_def ./register_definitions/powerpc.ia --inst_next_size_hint '$(REGISTER_SIZE)' --base_path <ghidra_dir> --out_dir $PWD/../../patches/sleigh`
Example invocation for PowerPC using `python replace_pc_relative_disactions/main.py <ghidra_dir>/Ghidra/Processors/PowerPC/data/languages/{ppc_common,ppc_embedded,ppc_instructions,ppc_isa,ppc_vle,quicciii}.sinc --pc_def ./register_definitions/powerpc.ia --inst_next_size_hint '$(REGISTER_SIZE)' --base_path <ghidra_dir> --out_dir $PWD/../../dependencies/sleigh_patches`