mirror of
https://github.com/lifting-bits/sleigh
synced 2026-06-21 13:56:12 +00:00
Compare commits
78 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8243a7b4b4 | |||
| 0664b5c545 | |||
| cd6078bb22 | |||
| fc49d2340e | |||
| 1df5e051d3 | |||
| edc5fabd3a | |||
| 9316045354 | |||
| ec98f45ecf | |||
| e4b6ddb926 | |||
| 9248e9114b | |||
| a020faccb5 | |||
| d74e8e9414 | |||
| f8229f609d | |||
| 4edfcef82e | |||
| 26c6b01b1f | |||
| 563adb57e9 | |||
| 127d913bc9 | |||
| 0ea6de2744 | |||
| 27072f1bca | |||
| 185e34f5e7 | |||
| 1ea24c8b8d | |||
| 572082b008 | |||
| a5496ad829 | |||
| 604cd282a6 | |||
| 14c9c408ca | |||
| 21ed4b78e5 | |||
| d2c42d19ed | |||
| 97f7fd1faf | |||
| cf1dc2bb79 | |||
| a732884632 | |||
| 800a597ff6 | |||
| adcbfb179f | |||
| 64377586f8 | |||
| 19fcb07d42 | |||
| 24e7a85db6 | |||
| 6b8620a8cf | |||
| f398228901 | |||
| d0d9bf5a67 | |||
| 632fa35e36 | |||
| e925db971d | |||
| e590133fc7 | |||
| 760a315270 | |||
| bf13fdebba | |||
| a49bbcc9cf | |||
| 1f41ff02e6 | |||
| 060f42d28c | |||
| eadedecf28 | |||
| 7807d6619a | |||
| 443cfcfdc7 | |||
| d888cdd5ea | |||
| 7a92039e1a | |||
| 4af948df00 | |||
| 95b848e8ed | |||
| 8e27d6ef0a | |||
| 9cc6adc272 | |||
| b763518f2f | |||
| a0a8aa27c0 | |||
| 3efc7415f8 | |||
| 45dc2a0dbb | |||
| b9eef57dee | |||
| f9c852bc57 | |||
| 3e96d296e0 | |||
| 9d4d450551 | |||
| 184fabc5aa | |||
| 4cedffc104 | |||
| 873108dd0e | |||
| 4ddd7f2f89 | |||
| 00f42b7ef7 | |||
| 31868c9d70 | |||
| a96b7fdcc6 | |||
| 78ed150957 | |||
| bc2f60c4b8 | |||
| 85a209708f | |||
| 6f193278c1 | |||
| df49d10291 | |||
| d2f443e358 | |||
| b871c4a6b8 | |||
| 58f4812a02 |
@@ -0,0 +1,161 @@
|
||||
name: Documentation
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch: # manual trigger
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
||||
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
||||
concurrency:
|
||||
group: pages
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Git User for Applying Patches
|
||||
# See this thread for more details https://github.community/t/github-actions-bot-email-address/17204/5
|
||||
run: |
|
||||
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y doxygen graphviz
|
||||
|
||||
# Build stable documentation
|
||||
- name: Configure (stable)
|
||||
run: cmake --preset=ci-ubuntu -Dsleigh_RELEASE_TYPE=stable
|
||||
|
||||
- name: Build documentation (stable)
|
||||
run: cmake --build build --target docs
|
||||
|
||||
- name: Copy stable docs
|
||||
run: |
|
||||
mkdir -p docs-site/stable
|
||||
cp -r build/docs/html/* docs-site/stable/
|
||||
|
||||
# Clean and build HEAD documentation
|
||||
- name: Clean build directory
|
||||
run: rm -rf build
|
||||
|
||||
- name: Configure (HEAD)
|
||||
run: cmake --preset=ci-ubuntu -Dsleigh_RELEASE_TYPE=HEAD
|
||||
|
||||
- name: Build documentation (HEAD)
|
||||
run: cmake --build build --target docs
|
||||
|
||||
- name: Copy HEAD docs
|
||||
run: |
|
||||
mkdir -p docs-site/HEAD
|
||||
cp -r build/docs/html/* docs-site/HEAD/
|
||||
|
||||
# Create landing page
|
||||
- name: Create landing page
|
||||
run: |
|
||||
cat > docs-site/index.html << 'EOF'
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Sleigh Documentation</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg-color: #f5f5f5;
|
||||
--text-color: #333;
|
||||
--text-muted: #666;
|
||||
--card-bg: white;
|
||||
--card-shadow: rgba(0,0,0,0.1);
|
||||
--card-shadow-hover: rgba(0,0,0,0.15);
|
||||
--link-color: #0066cc;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg-color: #1a1a1a;
|
||||
--text-color: #e0e0e0;
|
||||
--text-muted: #a0a0a0;
|
||||
--card-bg: #2d2d2d;
|
||||
--card-shadow: rgba(0,0,0,0.3);
|
||||
--card-shadow-hover: rgba(0,0,0,0.4);
|
||||
--link-color: #4da6ff;
|
||||
}
|
||||
}
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
background: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
}
|
||||
h1 {
|
||||
color: var(--text-color);
|
||||
}
|
||||
.cards {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
.card {
|
||||
flex: 1;
|
||||
background: var(--card-bg);
|
||||
border-radius: 8px;
|
||||
padding: 1.5rem;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
box-shadow: 0 2px 4px var(--card-shadow);
|
||||
transition: box-shadow 0.2s;
|
||||
}
|
||||
.card:hover {
|
||||
box-shadow: 0 4px 8px var(--card-shadow-hover);
|
||||
}
|
||||
.card h2 {
|
||||
margin-top: 0;
|
||||
color: var(--link-color);
|
||||
}
|
||||
.card p {
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Sleigh Documentation</h1>
|
||||
<p>Select a documentation version:</p>
|
||||
<div class="cards">
|
||||
<a href="stable/" class="card">
|
||||
<h2>Stable</h2>
|
||||
<p>Documentation for the latest stable release.</p>
|
||||
</a>
|
||||
<a href="HEAD/" class="card">
|
||||
<h2>HEAD</h2>
|
||||
<p>Documentation for the latest Ghidra HEAD development version.</p>
|
||||
</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
- name: Upload Pages artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: docs-site
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
+27
-22
@@ -25,7 +25,7 @@ jobs:
|
||||
release: [stable, HEAD]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Git User for Applying Patches
|
||||
# See this thread for more details https://github.community/t/github-actions-bot-email-address/17204/5
|
||||
@@ -56,6 +56,7 @@ jobs:
|
||||
max_attempts: 3
|
||||
command: |
|
||||
choco install ccache doxygen.install graphviz
|
||||
Add-Content -Path $env:GITHUB_ENV -Value "CCACHE_EXE=$(Resolve-Path C:\ProgramData\chocolatey\lib\ccache\tools\*\ccache.exe)"
|
||||
vcpkg install zlib:x64-windows-static
|
||||
|
||||
- name: Generate cache key
|
||||
@@ -66,9 +67,9 @@ jobs:
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CACHE_TIMESTAMP=${current_date}\n")
|
||||
|
||||
- name: Update the cache (ccache)
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: "${{ github.workspace }}/ccache"
|
||||
path: ${{ runner.os == 'Windows' && env.TEMP || github.workspace }}/ccache
|
||||
key: ${{ env.CACHE_KEY }}_ccache_${{ env.CACHE_TIMESTAMP }}
|
||||
restore-keys: |
|
||||
${{ env.CACHE_KEY }}_ccache_
|
||||
@@ -79,14 +80,16 @@ jobs:
|
||||
run: |
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/ccache")
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_BASEDIR=${CMAKE_CURRENT_SOURCE_DIR}\n")
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/ccache\n")
|
||||
if(WIN32)
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_DIR=$ENV{TEMP}/ccache\n")
|
||||
else()
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/ccache\n")
|
||||
endif()
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_COMPRESS=true\n")
|
||||
# Trial and error to get all files in here
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_COMPRESSLEVEL=10\n")
|
||||
# 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
|
||||
# These only work for Ninja/Makefiles, not VS generators
|
||||
# But harmless to set for all platforms
|
||||
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
|
||||
@@ -100,12 +103,14 @@ jobs:
|
||||
run: cmake "--preset=ci-$("${{ matrix.os }}".split("-")[0])"
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
|
||||
-Dsleigh_RELEASE_TYPE=${{ matrix.release }}
|
||||
"-DCMAKE_PROJECT_INCLUDE:FILEPATH=${{ github.workspace }}/cmake/ccache-msvc.cmake"
|
||||
-DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=Embedded
|
||||
|
||||
- name: Build the project
|
||||
run: cmake
|
||||
--build build
|
||||
--config ${{ matrix.build_type }}
|
||||
-j 2
|
||||
-j 4
|
||||
-v
|
||||
|
||||
- name: Test the project
|
||||
@@ -122,7 +127,7 @@ jobs:
|
||||
- name: Run the example
|
||||
run: cmake
|
||||
--build build
|
||||
-j 2
|
||||
-j 4
|
||||
--config ${{ matrix.build_type }}
|
||||
--target sleigh_example_runner
|
||||
|
||||
@@ -142,7 +147,7 @@ jobs:
|
||||
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 }}
|
||||
cmake --build build -j 4 --config ${{ matrix.build_type }}
|
||||
cd build
|
||||
ctest -V -C ${{ matrix.build_type }}
|
||||
- name: Test install directory Windows
|
||||
@@ -150,7 +155,7 @@ jobs:
|
||||
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 }}
|
||||
cmake --build build -j 4 --config ${{ matrix.build_type }}
|
||||
cd build
|
||||
ctest -V -C ${{ matrix.build_type }}
|
||||
|
||||
@@ -159,7 +164,7 @@ jobs:
|
||||
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 --build build -j 4 --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
|
||||
@@ -169,7 +174,7 @@ jobs:
|
||||
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 --build build -j 4 --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
|
||||
@@ -178,7 +183,7 @@ jobs:
|
||||
- name: Create the packages
|
||||
run: cmake
|
||||
--build build
|
||||
-j 2
|
||||
-j 4
|
||||
--config ${{ matrix.build_type }}
|
||||
--target package
|
||||
|
||||
@@ -188,7 +193,7 @@ jobs:
|
||||
sudo dpkg -i build/*.deb
|
||||
|
||||
cmake -S tests/find_package -B find_package_build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
|
||||
cmake --build find_package_build -j 2 --config ${{ matrix.build_type }} --verbose
|
||||
cmake --build find_package_build -j 4 --config ${{ matrix.build_type }} --verbose
|
||||
|
||||
- name: Locate the packages (RelWithDebInfo only)
|
||||
if: matrix.build_type == 'RelWithDebInfo'
|
||||
@@ -211,13 +216,13 @@ jobs:
|
||||
# DEB Package
|
||||
- name: Upload the DEB package artifact (RelWithDebInfo only)
|
||||
if: matrix.build_type == 'RelWithDebInfo' && runner.os == 'Linux'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ env.DEB_PACKAGE_NAME }}
|
||||
path: ${{ env.DEB_PACKAGE_PATH }}
|
||||
|
||||
- name: Release DEB package artifact (RelWithDebInfo only)
|
||||
uses: softprops/action-gh-release@v2.2.1
|
||||
uses: softprops/action-gh-release@v2.5.0
|
||||
if: matrix.build_type == 'RelWithDebInfo' && runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/') && matrix.release == 'stable'
|
||||
with:
|
||||
files: ${{ env.DEB_PACKAGE_PATH }}
|
||||
@@ -225,12 +230,12 @@ jobs:
|
||||
# RPM Package
|
||||
- name: Upload the RPM package artifact (RelWithDebInfo only)
|
||||
if: matrix.build_type == 'RelWithDebInfo' && runner.os == 'Linux'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ env.RPM_PACKAGE_NAME }}
|
||||
path: ${{ env.RPM_PACKAGE_PATH }}
|
||||
- name: Release RPM package artifact (RelWithDebInfo only)
|
||||
uses: softprops/action-gh-release@v2.2.1
|
||||
uses: softprops/action-gh-release@v2.5.0
|
||||
if: matrix.build_type == 'RelWithDebInfo' && runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/') && matrix.release == 'stable'
|
||||
with:
|
||||
files: ${{ env.RPM_PACKAGE_PATH }}
|
||||
@@ -238,13 +243,13 @@ jobs:
|
||||
# TGZ Package
|
||||
- name: Upload the TGZ package artifact (RelWithDebInfo only)
|
||||
if: matrix.build_type == 'RelWithDebInfo'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ env.TGZ_PACKAGE_NAME }}
|
||||
path: ${{ env.TGZ_PACKAGE_PATH }}
|
||||
|
||||
- name: Release TGZ package artifact (RelWithDebInfo only)
|
||||
uses: softprops/action-gh-release@v2.2.1
|
||||
uses: softprops/action-gh-release@v2.5.0
|
||||
if: matrix.build_type == 'RelWithDebInfo' && startsWith(github.ref, 'refs/tags/') && matrix.release == 'stable'
|
||||
with:
|
||||
files: ${{ env.TGZ_PACKAGE_PATH }}
|
||||
|
||||
@@ -12,9 +12,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
# Use oldest supported version for maximum script compatibility
|
||||
python-version: '3.10'
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
|
||||
- name: Create PR
|
||||
if: steps.head_update.outputs.did_update
|
||||
uses: peter-evans/create-pull-request@v7
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
with:
|
||||
title: Update Ghidra HEAD to commit ${{ steps.head_update.outputs.short_sha }}
|
||||
commit-message: |
|
||||
@@ -45,10 +45,18 @@ jobs:
|
||||
Changed files:
|
||||
|
||||
${{ steps.head_update.outputs.changed_files }}
|
||||
|
||||
Commit details:
|
||||
|
||||
${{ steps.head_update.outputs.commit_details }}
|
||||
body: |
|
||||
Changed files:
|
||||
|
||||
${{ steps.head_update.outputs.changed_files }}
|
||||
|
||||
Commit details:
|
||||
|
||||
${{ steps.head_update.outputs.commit_details }}
|
||||
branch: cron/update-ghidra-${{ steps.head_update.outputs.short_sha }}
|
||||
delete-branch: true
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
# For MSVC ccache to use /Z7 with CMAKE_MSVC_DEBUG_INFORMATION_FORMAT=Embedded
|
||||
cmake_policy(SET CMP0141 NEW)
|
||||
|
||||
include(cmake/prelude.cmake)
|
||||
|
||||
# Sets "library_root" variable for decompiler cpp root directory
|
||||
@@ -143,6 +146,7 @@ set(public_include_header_list
|
||||
"${library_root}/multiprecision.hh"
|
||||
"${library_root}/slaformat.hh"
|
||||
"${library_root}/constseq.hh"
|
||||
"${library_root}/expression.hh"
|
||||
)
|
||||
#if(sleigh_RELEASE_IS_HEAD)
|
||||
# list(APPEND public_include_header_list
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 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/ghidra_docs/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.
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# This module configures ccache to work with MSVC
|
||||
# Based on: https://github.com/ccache/ccache/wiki/MS-Visual-Studio
|
||||
|
||||
# Only do this for Windows MSVC builds
|
||||
if(NOT WIN32 OR NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Assume the parent environment has this set
|
||||
# Chocolatey creates a shim which doesn't work when renamed
|
||||
set(CCACHE_EXE "$ENV{CCACHE_EXE}")
|
||||
if(NOT CCACHE_EXE)
|
||||
message(STATUS "ccache not found - MSVC ccache support disabled")
|
||||
return()
|
||||
endif()
|
||||
message(STATUS "Found ccache - ${CCACHE_EXE}")
|
||||
|
||||
message(STATUS "Configuring ccache for MSVC")
|
||||
|
||||
file(COPY_FILE
|
||||
"${CCACHE_EXE}" "${CMAKE_BINARY_DIR}/cl.exe"
|
||||
ONLY_IF_DIFFERENT)
|
||||
|
||||
# By default Visual Studio generators will use /Zi which is not compatible
|
||||
# with ccache, so tell Visual Studio to use /Z7 instead.
|
||||
message(STATUS "Setting MSVC debug information format to 'Embedded'")
|
||||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<$<CONFIG:Debug,RelWithDebInfo>:Embedded>")
|
||||
|
||||
set(CMAKE_VS_GLOBALS
|
||||
"CLToolExe=cl.exe"
|
||||
"CLToolPath=${CMAKE_BINARY_DIR}"
|
||||
"TrackFileAccess=false"
|
||||
"UseMultiToolTask=true"
|
||||
"DebugInformationFormat=OldStyle"
|
||||
)
|
||||
@@ -123,8 +123,18 @@ static void PrintAssembly(ghidra::Sleigh &engine, uint64_t addr, size_t len) {
|
||||
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);
|
||||
cur_addr = cur_addr + instr_len;
|
||||
try {
|
||||
int32_t instr_len = engine.printAssembly(asm_emit, cur_addr);
|
||||
cur_addr = cur_addr + instr_len;
|
||||
}
|
||||
catch(ghidra::UnimplError &err) {
|
||||
std::cerr << "UnimplError @ " << cur_addr << " (addr 0x" << addr << ", len 0x" << len << "): " << err.explain << "\n";
|
||||
break;
|
||||
}
|
||||
catch (ghidra::BadDataError &err) {
|
||||
std::cerr << "BadDataError @ " << cur_addr << " (addr 0x" << addr << ", len 0x" << len << "): " << err.explain << "\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,8 +167,18 @@ static void PrintPcode(ghidra::Sleigh &engine, uint64_t addr, size_t len) {
|
||||
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);
|
||||
cur_addr = cur_addr + instr_len;
|
||||
try {
|
||||
int32_t instr_len = engine.oneInstruction(pcode_emit, cur_addr);
|
||||
cur_addr = cur_addr + instr_len;
|
||||
}
|
||||
catch(ghidra::UnimplError &err) {
|
||||
std::cerr << "UnimplError @ " << cur_addr << " (addr 0x" << addr << ", len 0x" << len << "): " << err.explain << "\n";
|
||||
break;
|
||||
}
|
||||
catch(ghidra::BadDataError &err) {
|
||||
std::cerr << "BadDataError @ " << cur_addr << " (addr 0x" << addr << ", len 0x" << len << "): " << err.explain << "\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+453
-220
@@ -1,281 +1,514 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Script to update CMake files for latest Ghidra Sleigh changes"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from typing import AnyStr, Union, List
|
||||
from typing import List, Dict, Optional, Any, Tuple
|
||||
|
||||
|
||||
# Constants
|
||||
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",
|
||||
# Paths in Ghidra repo that affect this repo
|
||||
SLEIGH_PATHS = [
|
||||
"Ghidra/Features/Decompiler/src/decompile", # Source code and tests
|
||||
"Ghidra/Processors", # Sleigh files
|
||||
]
|
||||
|
||||
GIT_EXE = shutil.which("git")
|
||||
assert GIT_EXE is not None
|
||||
# Regex patterns
|
||||
HEAD_COMMIT_PATTERN = r"set\(ghidra_head_git_tag \"([0-9A-Fa-f]+)\"\)"
|
||||
VERSION_PATTERN = r"set\(ghidra_head_version \"([0-9]+(\.[0-9]+)*)\"\)"
|
||||
APP_VERSION_PATTERN = r"application.version=([0-9]+(\.[0-9]+)*)"
|
||||
|
||||
|
||||
def msg(s: str) -> None:
|
||||
print(f"[!] {s}")
|
||||
class GitHelper:
|
||||
"""Helper class for Git operations"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.git_exe = shutil.which("git")
|
||||
if self.git_exe is None:
|
||||
raise RuntimeError("Git executable not found in PATH")
|
||||
|
||||
PathString = Union[AnyStr, Path]
|
||||
def run(
|
||||
self, args: List[str], cwd: Path, capture_output: bool = False
|
||||
) -> subprocess.CompletedProcess:
|
||||
"""Run a git command with the given arguments"""
|
||||
assert self.git_exe is not None
|
||||
cmd = [self.git_exe] + args
|
||||
return subprocess.run(
|
||||
cmd,
|
||||
cwd=cwd,
|
||||
stdout=subprocess.PIPE if capture_output else sys.stdout,
|
||||
stderr=subprocess.PIPE if capture_output else sys.stderr,
|
||||
check=True,
|
||||
text=True if capture_output else False,
|
||||
)
|
||||
|
||||
def clone(self, repo_url: str, target_dir: Path) -> None:
|
||||
"""Clone a git repository"""
|
||||
print(f"Cloning {repo_url} to {target_dir}...")
|
||||
self.run(["clone", repo_url, str(target_dir)], cwd=PROJECT_ROOT)
|
||||
|
||||
def clone_ghidra_git(clone_dir: PathString) -> None:
|
||||
"""Clone the Ghidra git dir at specified directory"""
|
||||
assert GIT_EXE is not None
|
||||
subprocess.run(
|
||||
[
|
||||
GIT_EXE,
|
||||
"clone",
|
||||
"https://github.com/NationalSecurityAgency/ghidra",
|
||||
clone_dir,
|
||||
],
|
||||
stdout=sys.stdout,
|
||||
stderr=sys.stderr,
|
||||
check=True,
|
||||
)
|
||||
def get_head_commit(self, repo_dir: Path) -> str:
|
||||
"""Get the HEAD commit SHA of the repository"""
|
||||
result = self.run(["rev-parse", "HEAD"], cwd=repo_dir, capture_output=True)
|
||||
return result.stdout.strip()
|
||||
|
||||
def check_commit_exists(self, repo_dir: Path, commit: str) -> bool:
|
||||
"""Check if a commit exists in the repository"""
|
||||
try:
|
||||
self.run(["cat-file", "-e", commit], repo_dir, capture_output=True)
|
||||
return True
|
||||
except subprocess.CalledProcessError:
|
||||
return False
|
||||
|
||||
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(
|
||||
def get_commit_info(
|
||||
self, repo_dir: Path, old_commit: str, new_commit: str, paths: List[str]
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""Get detailed information about commits affecting specified paths"""
|
||||
result = self.run(
|
||||
[
|
||||
"log",
|
||||
"--pretty=format:%H%n%ad%n%s%n%b%n====",
|
||||
"--date=iso",
|
||||
f"{old_commit}..{new_commit}",
|
||||
"--",
|
||||
*paths,
|
||||
],
|
||||
cwd=repo_dir,
|
||||
capture_output=True,
|
||||
)
|
||||
|
||||
log_output = result.stdout.strip()
|
||||
commits = []
|
||||
|
||||
if log_output:
|
||||
commit_sections = log_output.split("\n====")
|
||||
|
||||
for section in commit_sections:
|
||||
if not section.strip():
|
||||
continue
|
||||
|
||||
lines = section.strip().split("\n")
|
||||
commit_hash = lines[0]
|
||||
commit_date = lines[1]
|
||||
commit_msg = lines[2]
|
||||
body = "\n".join(lines[3:]) if len(lines) > 3 else ""
|
||||
|
||||
# Get files modified in this commit
|
||||
files_result = self.run(
|
||||
[
|
||||
"diff-tree",
|
||||
"--no-commit-id",
|
||||
"--name-status",
|
||||
"-r",
|
||||
commit_hash,
|
||||
"--",
|
||||
*paths,
|
||||
],
|
||||
cwd=repo_dir,
|
||||
capture_output=True,
|
||||
)
|
||||
|
||||
commit_files = files_result.stdout.strip().splitlines()
|
||||
# Filter out Java files
|
||||
commit_files = [f for f in commit_files if not f.endswith(".java")]
|
||||
|
||||
if commit_files:
|
||||
commits.append(
|
||||
{
|
||||
"hash": commit_hash,
|
||||
"date": commit_date,
|
||||
"message": commit_msg,
|
||||
"body": body,
|
||||
"files": commit_files,
|
||||
}
|
||||
)
|
||||
|
||||
return commits
|
||||
|
||||
def get_changed_files(
|
||||
self, repo_dir: Path, old_commit: str, new_commit: str, paths: List[str]
|
||||
) -> List[str]:
|
||||
"""Get list of files changed between commits"""
|
||||
result = self.run(
|
||||
[
|
||||
GIT_EXE,
|
||||
"diff",
|
||||
"--name-status",
|
||||
f"{old_commit}...{new_commit}",
|
||||
"--",
|
||||
*paths,
|
||||
],
|
||||
cwd=repo,
|
||||
cwd=repo_dir,
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
.stdout.decode()
|
||||
.strip()
|
||||
.splitlines()
|
||||
)
|
||||
changed_files = list(filter(lambda p: not p.endswith(".java"), changed_files))
|
||||
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
|
||||
|
||||
changed_files = result.stdout.strip().splitlines()
|
||||
# Filter out Java files
|
||||
changed_files = [f for f in changed_files if not f.endswith(".java")]
|
||||
|
||||
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
|
||||
class GhidraUpdater:
|
||||
"""Handles updating Ghidra-related CMake files"""
|
||||
|
||||
def __init__(self, ci_mode: bool = False, dry_run: bool = False) -> None:
|
||||
self.git = GitHelper()
|
||||
self.ci_mode = ci_mode
|
||||
self.dry_run = dry_run
|
||||
|
||||
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
|
||||
# Validate required paths
|
||||
if not HEAD_SPEC_FILE.exists():
|
||||
raise FileNotFoundError(f"HEAD spec file not found: {HEAD_SPEC_FILE}")
|
||||
if not SETUP_GHIDRA_FILE.exists():
|
||||
raise FileNotFoundError(f"Setup Ghidra file not found: {SETUP_GHIDRA_FILE}")
|
||||
|
||||
fd, abspath = tempfile.mkstemp()
|
||||
with open(fd, "w") as w:
|
||||
with setup_file.open("r") as r:
|
||||
for line in r:
|
||||
match = re.search(head_commit_line, line)
|
||||
if match is not None:
|
||||
# Set up GitHub Actions outputs if in CI mode
|
||||
if self.ci_mode and "GITHUB_OUTPUT" not in os.environ:
|
||||
raise RuntimeError("CI mode requires GITHUB_OUTPUT environment variable")
|
||||
|
||||
def clone_ghidra_if_needed(
|
||||
self, repo_dir: Optional[Path] = None
|
||||
) -> Tuple[Path, Optional[tempfile.TemporaryDirectory]]:
|
||||
"""Clone Ghidra repo if a directory is not provided"""
|
||||
temp_dir = None
|
||||
|
||||
if repo_dir is None:
|
||||
temp_dir = tempfile.TemporaryDirectory()
|
||||
repo_dir = Path(temp_dir.name) / "ghidra"
|
||||
self.git.clone("https://github.com/NationalSecurityAgency/ghidra", repo_dir)
|
||||
|
||||
return repo_dir, temp_dir
|
||||
|
||||
def log_github_output(self, key: str, value: str) -> None:
|
||||
"""Log output for GitHub Actions"""
|
||||
if self.ci_mode:
|
||||
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
|
||||
f.write(f"{key}={value}\n")
|
||||
|
||||
def log_github_multiline_output(self, key: str, value: str) -> None:
|
||||
"""Log multiline output for GitHub Actions"""
|
||||
if self.ci_mode:
|
||||
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
|
||||
f.write(f"{key}<<EOF\n")
|
||||
f.write(value)
|
||||
f.write("\nEOF\n")
|
||||
|
||||
def display_changes(
|
||||
self, repo_dir: Path, start_commit: str, end_commit: str
|
||||
) -> Tuple[List[str], List[Dict[str, Any]]]:
|
||||
"""Display changes between two commits and return the changed files and commit info"""
|
||||
# Get changed files
|
||||
changed_files = self.git.get_changed_files(
|
||||
repo_dir, start_commit, end_commit, SLEIGH_PATHS
|
||||
)
|
||||
|
||||
if not changed_files:
|
||||
print("No sleigh files were modified between these commits")
|
||||
return [], []
|
||||
|
||||
# Output changes for logging
|
||||
num_changed = len(changed_files)
|
||||
print(f"Found {num_changed} changed sleigh files:")
|
||||
for file in changed_files:
|
||||
print(f" {file}")
|
||||
|
||||
# Get detailed commit info for logging
|
||||
commit_info = self.git.get_commit_info(
|
||||
repo_dir, start_commit, end_commit, SLEIGH_PATHS
|
||||
)
|
||||
|
||||
if commit_info:
|
||||
print(f"\nCommits affecting sleigh files ({len(commit_info)}):\n")
|
||||
for i, commit in enumerate(commit_info, 1):
|
||||
print(f"[Commit {i}/{len(commit_info)}]")
|
||||
print(f"Hash: {commit['hash']}")
|
||||
print(f"Date: {commit['date']}")
|
||||
print(f"Message: {commit['message']}")
|
||||
if commit["body"]:
|
||||
print(f"Details:\n{commit['body']}")
|
||||
print("\nFiles changed:")
|
||||
for file in commit["files"]:
|
||||
print(f" {file}")
|
||||
print("")
|
||||
|
||||
# Log outputs for GitHub Actions
|
||||
if self.ci_mode:
|
||||
self.log_github_output("short_sha", end_commit[:9])
|
||||
self.log_github_output("did_update", "true")
|
||||
|
||||
# Log changed files
|
||||
changed_files_str = "```\n" + "\n".join(changed_files) + "\n```"
|
||||
self.log_github_multiline_output("changed_files", changed_files_str)
|
||||
|
||||
# Log commit details
|
||||
if commit_info:
|
||||
details = ["```"]
|
||||
for i, commit in enumerate(commit_info, 1):
|
||||
details.append(f"[Commit {i}/{len(commit_info)}]")
|
||||
details.append(f"Hash: {commit['hash']}")
|
||||
details.append(f"Date: {commit['date']}")
|
||||
details.append(f"Message: {commit['message']}")
|
||||
if commit["body"]:
|
||||
details.append(f"Details:\n{commit['body']}")
|
||||
details.append("\nFiles changed:")
|
||||
for file in commit["files"]:
|
||||
details.append(f" {file}")
|
||||
details.append("")
|
||||
# Replace trailing newline for last entry
|
||||
details[-1] = "```"
|
||||
|
||||
self.log_github_multiline_output("commit_details", "\n".join(details))
|
||||
|
||||
return changed_files, commit_info
|
||||
|
||||
def update_head_commit(
|
||||
self, repo_dir: Path, setup_file: Path
|
||||
) -> Tuple[bool, str, str]:
|
||||
"""Update the HEAD commit in the setup file if needed"""
|
||||
# Get latest commit hash
|
||||
latest_commit = self.git.get_head_commit(repo_dir)
|
||||
current_commit = None
|
||||
|
||||
# Find current commit hash in setup file
|
||||
with setup_file.open("r") as f:
|
||||
for line in f:
|
||||
match = re.search(HEAD_COMMIT_PATTERN, line)
|
||||
if match:
|
||||
current_commit = match.group(1)
|
||||
if current_commit != latest_commit:
|
||||
msg(f"Found new commit: {latest_commit}")
|
||||
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)
|
||||
break
|
||||
|
||||
# Make the swap with the new content
|
||||
shutil.copymode(setup_file, abspath)
|
||||
os.remove(setup_file)
|
||||
shutil.move(abspath, setup_file)
|
||||
return updated
|
||||
if current_commit is None:
|
||||
raise ValueError("Could not find current commit in setup file")
|
||||
|
||||
# Check if update is needed
|
||||
if current_commit == latest_commit:
|
||||
print(f"Already at the latest commit: {latest_commit}")
|
||||
return False, current_commit, latest_commit
|
||||
|
||||
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]+)?)\"\)"
|
||||
)
|
||||
print(f"Found new commit: {latest_commit}")
|
||||
|
||||
with (ghidra_root_dir / "Ghidra" / "application.properties").open("r") as f:
|
||||
content = f.read()
|
||||
match = re.search(
|
||||
r"application.version=([0-9]+(\.[0-9]+)?(\.[0-9]+)?)", content
|
||||
# Check if sleigh files were updated and display changes
|
||||
changed_files, commit_info = self.display_changes(
|
||||
repo_dir, current_commit, latest_commit
|
||||
)
|
||||
assert match is not None
|
||||
source_version = match.group(1)
|
||||
|
||||
with setup_file.open("r") as f:
|
||||
content = f.read()
|
||||
match = re.search(cmake_head_version_line, content)
|
||||
assert match is not None
|
||||
cmake_version = match.group(1)
|
||||
if not changed_files:
|
||||
return False, current_commit, latest_commit
|
||||
|
||||
if cmake_version == source_version:
|
||||
msg(f"No new version bump")
|
||||
return
|
||||
# Update the setup file if not in dry run mode
|
||||
if not self.dry_run:
|
||||
self._replace_in_file(
|
||||
setup_file,
|
||||
HEAD_COMMIT_PATTERN,
|
||||
f'set(ghidra_head_git_tag "{latest_commit}")',
|
||||
)
|
||||
|
||||
msg(f"Found new version: {source_version}")
|
||||
fd, abspath = tempfile.mkstemp()
|
||||
with open(fd, "w") as w:
|
||||
with setup_file.open("r") as r:
|
||||
for line in r:
|
||||
match = re.search(cmake_head_version_line, line)
|
||||
if match is not None:
|
||||
line = re.sub(
|
||||
cmake_head_version_line,
|
||||
f'set(ghidra_head_version "{source_version}")',
|
||||
line,
|
||||
)
|
||||
w.write(line)
|
||||
return True, current_commit, latest_commit
|
||||
|
||||
# Make the swap with the new content
|
||||
shutil.copymode(setup_file, abspath)
|
||||
os.remove(setup_file)
|
||||
shutil.move(abspath, setup_file)
|
||||
def update_version(self, repo_dir: Path, setup_file: Path) -> None:
|
||||
"""Update the Ghidra version in the setup file if needed"""
|
||||
# Get source version from application.properties
|
||||
app_properties_file = repo_dir / "Ghidra" / "application.properties"
|
||||
|
||||
with app_properties_file.open("r") as f:
|
||||
content = f.read()
|
||||
match = re.search(APP_VERSION_PATTERN, content)
|
||||
if not match:
|
||||
raise ValueError("Could not find version in application.properties")
|
||||
source_version = match.group(1)
|
||||
|
||||
# Get current version from setup file
|
||||
with setup_file.open("r") as f:
|
||||
content = f.read()
|
||||
match = re.search(VERSION_PATTERN, content)
|
||||
if not match:
|
||||
raise ValueError("Could not find version in setup file")
|
||||
cmake_version = match.group(1)
|
||||
|
||||
# Check if update is needed
|
||||
if cmake_version == source_version:
|
||||
print("No new version bump")
|
||||
return
|
||||
|
||||
print(f"Found new version: {source_version}")
|
||||
|
||||
# Update the setup file if not in dry run mode
|
||||
if not self.dry_run:
|
||||
self._replace_in_file(
|
||||
setup_file,
|
||||
VERSION_PATTERN,
|
||||
f'set(ghidra_head_version "{source_version}")',
|
||||
)
|
||||
|
||||
def update_spec_files(self, repo_dir: Path, spec_file: Path) -> None:
|
||||
"""Update the list of spec files in the CMake file"""
|
||||
# Find all .slaspec files
|
||||
spec_files = []
|
||||
processors_dir = repo_dir / "Ghidra" / "Processors"
|
||||
|
||||
for path in processors_dir.glob("**/*.slaspec"):
|
||||
spec_files.append(path.relative_to(repo_dir))
|
||||
|
||||
spec_files.sort()
|
||||
print(f"Found {len(spec_files)} slaspec files")
|
||||
|
||||
# Write the updated spec file list
|
||||
if not self.dry_run and spec_files:
|
||||
with spec_file.open("w") as f:
|
||||
f.write("set(spec_file_list\n")
|
||||
for spec in spec_files:
|
||||
f.write(f' "${{ghidrasource_SOURCE_DIR}}/{spec}"\n')
|
||||
f.write(")\n")
|
||||
|
||||
def _replace_in_file(self, file_path: Path, pattern: str, replacement: str) -> None:
|
||||
"""Replace text in a file matching the pattern with the replacement"""
|
||||
temp_file = tempfile.NamedTemporaryFile(mode="w", delete=False)
|
||||
|
||||
with file_path.open("r") as src, open(temp_file.name, "w") as dst:
|
||||
for line in src:
|
||||
dst.write(re.sub(pattern, replacement, line))
|
||||
|
||||
# Replace the original file with the modified one
|
||||
shutil.copymode(file_path, temp_file.name)
|
||||
os.remove(file_path)
|
||||
shutil.move(temp_file.name, file_path)
|
||||
|
||||
def update(self, repo_dir: Optional[Path] = None) -> bool:
|
||||
"""Main update method to orchestrate the update process"""
|
||||
# Clone repo if not provided
|
||||
repo_dir, temp_dir = self.clone_ghidra_if_needed(repo_dir)
|
||||
|
||||
try:
|
||||
# Update the HEAD commit
|
||||
did_update, _, _ = self.update_head_commit(repo_dir, SETUP_GHIDRA_FILE)
|
||||
|
||||
# If commit was updated, also update version and spec files
|
||||
if did_update:
|
||||
self.update_version(repo_dir, SETUP_GHIDRA_FILE)
|
||||
self.update_spec_files(repo_dir, HEAD_SPEC_FILE)
|
||||
|
||||
return did_update
|
||||
|
||||
finally:
|
||||
# Clean up temp directory if created
|
||||
if temp_dir:
|
||||
temp_dir.cleanup()
|
||||
|
||||
def compare_commits(
|
||||
self, repo_dir: Path, start_commit: str, end_commit: Optional[str] = None
|
||||
) -> None:
|
||||
"""Compare changes between two commits without updating any files"""
|
||||
# If end_commit is not provided, use HEAD
|
||||
if end_commit is None:
|
||||
end_commit = self.git.get_head_commit(repo_dir)
|
||||
print(f"Using HEAD as end commit: {end_commit}")
|
||||
|
||||
print(f"Comparing commits {start_commit} to {end_commit}")
|
||||
|
||||
# Check if the commits exist
|
||||
for commit in [start_commit, end_commit]:
|
||||
if not self.git.check_commit_exists(repo_dir, commit):
|
||||
raise ValueError(f"Commit {commit} does not exist in the repository")
|
||||
|
||||
# Display changes
|
||||
self.display_changes(repo_dir, start_commit, end_commit)
|
||||
|
||||
|
||||
def update_spec_files(ghidra_repo_dir: PathString, cmake_file: PathString):
|
||||
"""Based on the files in the Ghidra repo, write an updated list of spec files."""
|
||||
spec_files = []
|
||||
for dirpath, _, fnames in os.walk(ghidra_repo_dir / "Ghidra" / "Processors"):
|
||||
for file in fnames:
|
||||
if file.endswith(".slaspec"):
|
||||
spec_files.append((Path(dirpath) / file).relative_to(ghidra_repo_dir))
|
||||
assert len(spec_files) > 0
|
||||
spec_files.sort()
|
||||
|
||||
msg(f"Found {len(spec_files)} slaspec files")
|
||||
|
||||
with open(cmake_file, "w") as f:
|
||||
f.write("set(spec_file_list\n")
|
||||
for spec in spec_files:
|
||||
f.write(f' "${{ghidrasource_SOURCE_DIR}}/{spec}"\n')
|
||||
f.write(")\n")
|
||||
|
||||
|
||||
def get_latest_commit(ghidra_repo_dir: PathString) -> str:
|
||||
"""Get the commit SHA that the repo is currently at"""
|
||||
assert GIT_EXE is not None
|
||||
return (
|
||||
subprocess.run(
|
||||
[GIT_EXE, "rev-parse", "HEAD"],
|
||||
cwd=ghidra_repo_dir,
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
.stdout.decode()
|
||||
.strip()
|
||||
)
|
||||
|
||||
|
||||
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 = Path(tmpdirname.name) / "ghidra"
|
||||
clone_ghidra_git(ghidra_repo_dir)
|
||||
|
||||
latest_commit = get_latest_commit(ghidra_repo_dir)
|
||||
did_update_commit = update_head_commit(
|
||||
setup_file, ghidra_repo_dir, latest_commit, ci
|
||||
)
|
||||
if did_update_commit:
|
||||
if ci:
|
||||
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}")
|
||||
|
||||
if tmpdirname is not None:
|
||||
tmpdirname.cleanup()
|
||||
|
||||
if did_update_commit:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse, os
|
||||
|
||||
def dir_path(string):
|
||||
if string is None:
|
||||
return string
|
||||
string = Path(string).expanduser().resolve()
|
||||
if string.is_dir():
|
||||
return string
|
||||
else:
|
||||
raise NotADirectoryError(string)
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
"""Parse command line arguments"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Update CMake files to latest Ghidra commit."
|
||||
description="Find and collect changes between two Ghidra commits. Update CMake files to latest Ghidra commit if specified."
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--ghidra-repo",
|
||||
type=dir_path,
|
||||
type=str,
|
||||
help="Use a specific Ghidra repo directory instead of downloading it from the internet",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--ci",
|
||||
action="store_true",
|
||||
help="Output GitHub Actions commands for recording information in CI",
|
||||
help="Output GitHub Actions commands for recording information in CI. Requires GITHUB_OUTPUT environment variable.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--dry-run",
|
||||
action="store_true",
|
||||
help="Show what would be changed without actually modifying any files",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"start_commit",
|
||||
nargs="?",
|
||||
type=str,
|
||||
help="Starting commit for comparison. When specified, no CMake files will be updated.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"end_commit",
|
||||
nargs="?",
|
||||
type=str,
|
||||
help="Ending commit for comparison. If not specified, uses current HEAD of the repo. Requires start_commit.",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.ci:
|
||||
assert (
|
||||
"GITHUB_OUTPUT" in os.environ
|
||||
), "CI needs `GITHUB_OUTPUT` environment variable set to a file location"
|
||||
# Convert ghidra-repo path if provided
|
||||
if args.ghidra_repo:
|
||||
repo_path = Path(args.ghidra_repo).expanduser().resolve()
|
||||
if not repo_path.is_dir():
|
||||
parser.error(f"Ghidra repo directory does not exist: {repo_path}")
|
||||
args.ghidra_repo = repo_path
|
||||
|
||||
if not update_head(SETUP_GHIDRA_FILE, HEAD_SPEC_FILE, args.ghidra_repo, args.ci):
|
||||
msg("No update required")
|
||||
else:
|
||||
msg("Update required!")
|
||||
# Validate commit arguments
|
||||
if args.end_commit and not args.start_commit:
|
||||
parser.error("Cannot specify end_commit without start_commit")
|
||||
|
||||
# If commits are specified, a Ghidra repo is required
|
||||
if args.start_commit and not args.ghidra_repo:
|
||||
parser.error("--ghidra-repo is required when specifying commits")
|
||||
|
||||
return args
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Main entry point"""
|
||||
args = parse_args()
|
||||
|
||||
try:
|
||||
updater = GhidraUpdater(ci_mode=args.ci, dry_run=args.dry_run)
|
||||
|
||||
# If start_commit is specified, run in comparison mode
|
||||
if args.start_commit:
|
||||
updater.compare_commits(
|
||||
args.ghidra_repo, args.start_commit, args.end_commit
|
||||
)
|
||||
else:
|
||||
# Normal update mode
|
||||
did_update = updater.update(args.ghidra_repo)
|
||||
|
||||
if not did_update:
|
||||
print("No update required")
|
||||
elif args.dry_run:
|
||||
print("Update would be required!")
|
||||
else:
|
||||
print("Update required!")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -1,77 +1,17 @@
|
||||
From 7c6e51dd1234387b98e1ad61d3f88a0565364b28 Mon Sep 17 00:00:00 2001
|
||||
From 9d1e7b00e8f5dca987038a78fbac400c835a78be Mon Sep 17 00:00:00 2001
|
||||
From: Eric Kilmer <eric.d.kilmer@gmail.com>
|
||||
Date: Mon, 12 Aug 2024 12:02:35 -0400
|
||||
Subject: [PATCH 1/6] Fix UBSAN errors in decompiler
|
||||
Subject: [PATCH 1/5] Fix UBSAN errors in decompiler
|
||||
|
||||
Co-authored-by: Alex Cameron <asc@tetsuo.sh>
|
||||
---
|
||||
.../Decompiler/src/decompile/cpp/fspec.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 | 12 +++++++++---
|
||||
.../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 +-
|
||||
10 files changed, 44 insertions(+), 18 deletions(-)
|
||||
5 files changed, 16 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc
|
||||
index d78b78731c..caf4b24d15 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc
|
||||
@@ -2868,8 +2868,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/op.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc
|
||||
index d51460be84..45bf394862 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 aebcfd9103..6c47e6eb15 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 ca9d71ab99..85d4dd281d 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodecompile.cc
|
||||
@@ -115,36 +55,6 @@ index ca9d71ab99..85d4dd281d 100644
|
||||
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 009570af71..72b2a10503 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;
|
||||
|
||||
@@ -7031,8 +7036,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();
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc
|
||||
index cd9b9835b1..8a4616c3b9 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc
|
||||
@@ -192,20 +102,6 @@ index 50d85e22ba..9f3b456229 100644
|
||||
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 fd0ab26fb4..7f654c220b 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
@@ -3728,8 +3728,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 2571f55f1a..fe40e22b1b 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/unittests/testfloatemu.cc
|
||||
@@ -220,5 +116,5 @@ index 2571f55f1a..fe40e22b1b 100644
|
||||
uintb true_result = ((uintb)(int32_t)f) & 0xffffffff;
|
||||
uintb encoding = format.getEncoding(f);
|
||||
--
|
||||
2.48.1
|
||||
2.50.1
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 5e37c51ebc8a3ae0f32a3cb0049aaebafec48d7d Mon Sep 17 00:00:00 2001
|
||||
From 729f72060849dc4f29e89b1c76a980563ffd3e2a 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/6] Use `stroull` instead of `stroul` to parse address
|
||||
Subject: [PATCH 2/5] Use `stroull` instead of `stroul` to parse address
|
||||
offsets
|
||||
|
||||
---
|
||||
@@ -34,5 +34,5 @@ index dbaa2e775f..72927bf379 100644
|
||||
enddata = (const char *) tmpdata;
|
||||
if (enddata - s.c_str() == s.size()) { // If no size or offset override
|
||||
--
|
||||
2.48.1
|
||||
2.50.1
|
||||
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
From 43b0f78ca2ce8e2adbcc4f3b3298940c72dc9b5b Mon Sep 17 00:00:00 2001
|
||||
From 39cfff6f08dad8a85f992e09b3e26716c9173bf7 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Kilmer <eric.d.kilmer@gmail.com>
|
||||
Date: Tue, 29 Oct 2024 17:51:09 -0400
|
||||
Subject: [PATCH 4/6] Ignore floating point test due to compilation differences
|
||||
Subject: [PATCH 3/5] Ignore floating point test due to compilation differences
|
||||
|
||||
This test fails on macOS and Windows. I'm unsure whether it's an OS or
|
||||
compiler issue.
|
||||
@@ -24,5 +24,5 @@ index fe40e22b1b..91440e2510 100644
|
||||
ASSERT_EQUALS(ff.printDecimal(f2, false), "0.33333334");
|
||||
double f3 = doubleFromRawBits(0x3fd0000000000000);
|
||||
--
|
||||
2.48.1
|
||||
2.50.1
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
From 0feb881ef1cbc9aa4639e16914b7d9ed863baadf Mon Sep 17 00:00:00 2001
|
||||
From: Eric Kilmer <eric.d.kilmer@gmail.com>
|
||||
Date: Tue, 29 Oct 2024 15:30:57 -0400
|
||||
Subject: [PATCH 3/6] Use string resize instead of reserve
|
||||
|
||||
assign will fix up the size to hold all of what's copied
|
||||
---
|
||||
Ghidra/Features/Decompiler/src/decompile/cpp/stringmanage.cc | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/stringmanage.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/stringmanage.cc
|
||||
index 5f5fa0c7b3..4cd77156f2 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/stringmanage.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/stringmanage.cc
|
||||
@@ -67,7 +67,6 @@ void StringManager::assignStringData(StringData &data,const uint1 *buf,int4 size
|
||||
|
||||
{
|
||||
if (charsize == 1 && numChars < maximumChars) {
|
||||
- data.byteData.reserve(size);
|
||||
data.byteData.assign(buf,buf+size);
|
||||
}
|
||||
else {
|
||||
@@ -77,9 +76,9 @@ void StringManager::assignStringData(StringData &data,const uint1 *buf,int4 size
|
||||
return;
|
||||
string resString = s.str();
|
||||
int4 newSize = resString.size();
|
||||
- data.byteData.reserve(newSize + 1);
|
||||
const uint1 *ptr = (const uint1 *)resString.c_str();
|
||||
data.byteData.assign(ptr,ptr+newSize);
|
||||
+ data.byteData.resize(newSize + 1, 0);
|
||||
data.byteData[newSize] = 0; // Make sure there is a null terminator
|
||||
}
|
||||
data.isTruncated = (numChars >= maximumChars);
|
||||
--
|
||||
2.48.1
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
From ef11bf80063c80967a6ddb8726e710bd207575f3 Mon Sep 17 00:00:00 2001
|
||||
From 2aa4395ef8874ee9890126f4bdad0d71adf9eacc Mon Sep 17 00:00:00 2001
|
||||
From: Eric Kilmer <eric.d.kilmer@gmail.com>
|
||||
Date: Wed, 30 Oct 2024 14:26:57 -0400
|
||||
Subject: [PATCH 5/6] Allow positive or negative NAN in decompiler floating
|
||||
Subject: [PATCH 4/5] Allow positive or negative NAN in decompiler floating
|
||||
point test
|
||||
|
||||
At least on Apple Silicon, this test reports positive NAN.
|
||||
@@ -33,5 +33,5 @@ index f8108d3d32..1060a3e193 100644
|
||||
<stringmatch name="Float print #14" min="1" max="1">double7 = 3.1415926535897933e-06;</stringmatch>
|
||||
</decompilertest>
|
||||
--
|
||||
2.48.1
|
||||
2.50.1
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
From 5d6886b914c266f0a97941666fda75e0f7311d35 Mon Sep 17 00:00:00 2001
|
||||
From 2a6bd0a0ad7797160db887bba7137b77aa148ba5 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Kilmer <eric.d.kilmer@gmail.com>
|
||||
Date: Sat, 8 Feb 2025 17:59:57 -0500
|
||||
Subject: [PATCH 6/6] decompiler: Fix strict weak ordering TypePartialEnum
|
||||
Subject: [PATCH 5/5] decompiler: Fix strict weak ordering TypePartialEnum
|
||||
|
||||
This fixes Windows Debug error encountered in testing where it was
|
||||
complaining about lack of strict weak ordering.
|
||||
@@ -10,10 +10,10 @@ complaining about lack of strict weak ordering.
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
index f25b019a4f..2f1337a740 100644
|
||||
index 962c525b7f..7db5024b54 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
@@ -2300,6 +2300,7 @@ int4 TypePartialEnum::compareDependency(const Datatype &op) const
|
||||
@@ -2303,6 +2303,7 @@ int4 TypePartialEnum::compareDependency(const Datatype &op) const
|
||||
|
||||
{
|
||||
if (submeta != op.getSubMeta()) return (submeta < op.getSubMeta()) ? -1 : 1;
|
||||
@@ -22,5 +22,5 @@ index f25b019a4f..2f1337a740 100644
|
||||
if (parent != tp->parent) return (parent < tp->parent) ? -1 : 1; // Compare absolute pointers
|
||||
if (offset != tp->offset) return (offset < tp->offset) ? -1 : 1;
|
||||
--
|
||||
2.48.1
|
||||
2.50.1
|
||||
|
||||
@@ -1,77 +1,17 @@
|
||||
From e694ad80e2965178c541a7414e55c76a1e318411 Mon Sep 17 00:00:00 2001
|
||||
From 9d1e7b00e8f5dca987038a78fbac400c835a78be Mon Sep 17 00:00:00 2001
|
||||
From: Eric Kilmer <eric.d.kilmer@gmail.com>
|
||||
Date: Mon, 12 Aug 2024 12:02:35 -0400
|
||||
Subject: [PATCH 1/6] Fix UBSAN errors in decompiler
|
||||
Subject: [PATCH 1/5] Fix UBSAN errors in decompiler
|
||||
|
||||
Co-authored-by: Alex Cameron <asc@tetsuo.sh>
|
||||
---
|
||||
.../Decompiler/src/decompile/cpp/fspec.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 | 12 +++++++++---
|
||||
.../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 +-
|
||||
10 files changed, 44 insertions(+), 18 deletions(-)
|
||||
5 files changed, 16 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc
|
||||
index 3e9f310446..c903810382 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc
|
||||
@@ -2868,8 +2868,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/op.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc
|
||||
index e165951fe6..00169e22e5 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 aebcfd9103..6c47e6eb15 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 ca9d71ab99..85d4dd281d 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodecompile.cc
|
||||
@@ -115,36 +55,6 @@ index ca9d71ab99..85d4dd281d 100644
|
||||
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 b7fda34cc9..a3d164aa2d 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;
|
||||
|
||||
@@ -7288,8 +7293,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();
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc
|
||||
index cd9b9835b1..8a4616c3b9 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc
|
||||
@@ -192,20 +102,6 @@ index 50d85e22ba..9f3b456229 100644
|
||||
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 88ca8e36c8..f25b019a4f 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
@@ -3728,8 +3728,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 2571f55f1a..fe40e22b1b 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/unittests/testfloatemu.cc
|
||||
@@ -220,5 +116,5 @@ index 2571f55f1a..fe40e22b1b 100644
|
||||
uintb true_result = ((uintb)(int32_t)f) & 0xffffffff;
|
||||
uintb encoding = format.getEncoding(f);
|
||||
--
|
||||
2.48.1
|
||||
2.50.1
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From cc36245a600051a66a4ab6c6ffff835d609ae92a Mon Sep 17 00:00:00 2001
|
||||
From 729f72060849dc4f29e89b1c76a980563ffd3e2a 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/6] Use `stroull` instead of `stroul` to parse address
|
||||
Subject: [PATCH 2/5] Use `stroull` instead of `stroul` to parse address
|
||||
offsets
|
||||
|
||||
---
|
||||
@@ -34,5 +34,5 @@ index dbaa2e775f..72927bf379 100644
|
||||
enddata = (const char *) tmpdata;
|
||||
if (enddata - s.c_str() == s.size()) { // If no size or offset override
|
||||
--
|
||||
2.48.1
|
||||
2.50.1
|
||||
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
From 2a8f30f31c24ecc7bd499648b97bb8b0c2705b78 Mon Sep 17 00:00:00 2001
|
||||
From 39cfff6f08dad8a85f992e09b3e26716c9173bf7 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Kilmer <eric.d.kilmer@gmail.com>
|
||||
Date: Tue, 29 Oct 2024 17:51:09 -0400
|
||||
Subject: [PATCH 4/6] Ignore floating point test due to compilation differences
|
||||
Subject: [PATCH 3/5] Ignore floating point test due to compilation differences
|
||||
|
||||
This test fails on macOS and Windows. I'm unsure whether it's an OS or
|
||||
compiler issue.
|
||||
@@ -24,5 +24,5 @@ index fe40e22b1b..91440e2510 100644
|
||||
ASSERT_EQUALS(ff.printDecimal(f2, false), "0.33333334");
|
||||
double f3 = doubleFromRawBits(0x3fd0000000000000);
|
||||
--
|
||||
2.48.1
|
||||
2.50.1
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
From f0ee9c783a7acd850f6565278842a23865441e6a Mon Sep 17 00:00:00 2001
|
||||
From: Eric Kilmer <eric.d.kilmer@gmail.com>
|
||||
Date: Tue, 29 Oct 2024 15:30:57 -0400
|
||||
Subject: [PATCH 3/6] Use string resize instead of reserve
|
||||
|
||||
assign will fix up the size to hold all of what's copied
|
||||
---
|
||||
Ghidra/Features/Decompiler/src/decompile/cpp/stringmanage.cc | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/stringmanage.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/stringmanage.cc
|
||||
index 5f5fa0c7b3..4cd77156f2 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/stringmanage.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/stringmanage.cc
|
||||
@@ -67,7 +67,6 @@ void StringManager::assignStringData(StringData &data,const uint1 *buf,int4 size
|
||||
|
||||
{
|
||||
if (charsize == 1 && numChars < maximumChars) {
|
||||
- data.byteData.reserve(size);
|
||||
data.byteData.assign(buf,buf+size);
|
||||
}
|
||||
else {
|
||||
@@ -77,9 +76,9 @@ void StringManager::assignStringData(StringData &data,const uint1 *buf,int4 size
|
||||
return;
|
||||
string resString = s.str();
|
||||
int4 newSize = resString.size();
|
||||
- data.byteData.reserve(newSize + 1);
|
||||
const uint1 *ptr = (const uint1 *)resString.c_str();
|
||||
data.byteData.assign(ptr,ptr+newSize);
|
||||
+ data.byteData.resize(newSize + 1, 0);
|
||||
data.byteData[newSize] = 0; // Make sure there is a null terminator
|
||||
}
|
||||
data.isTruncated = (numChars >= maximumChars);
|
||||
--
|
||||
2.48.1
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
From 04cca72897d9088713a6e2dadb2774ad20ae7703 Mon Sep 17 00:00:00 2001
|
||||
From 2aa4395ef8874ee9890126f4bdad0d71adf9eacc Mon Sep 17 00:00:00 2001
|
||||
From: Eric Kilmer <eric.d.kilmer@gmail.com>
|
||||
Date: Wed, 30 Oct 2024 14:26:57 -0400
|
||||
Subject: [PATCH 5/6] Allow positive or negative NAN in decompiler floating
|
||||
Subject: [PATCH 4/5] Allow positive or negative NAN in decompiler floating
|
||||
point test
|
||||
|
||||
At least on Apple Silicon, this test reports positive NAN.
|
||||
@@ -33,5 +33,5 @@ index f8108d3d32..1060a3e193 100644
|
||||
<stringmatch name="Float print #14" min="1" max="1">double7 = 3.1415926535897933e-06;</stringmatch>
|
||||
</decompilertest>
|
||||
--
|
||||
2.48.1
|
||||
2.50.1
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
From a7dee0fbb1838e4e22a1c970718b84976ffb2932 Mon Sep 17 00:00:00 2001
|
||||
From 2a6bd0a0ad7797160db887bba7137b77aa148ba5 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Kilmer <eric.d.kilmer@gmail.com>
|
||||
Date: Sat, 8 Feb 2025 17:59:57 -0500
|
||||
Subject: [PATCH 6/6] decompiler: Fix strict weak ordering TypePartialEnum
|
||||
Subject: [PATCH 5/5] decompiler: Fix strict weak ordering TypePartialEnum
|
||||
|
||||
This fixes Windows Debug error encountered in testing where it was
|
||||
complaining about lack of strict weak ordering.
|
||||
@@ -10,10 +10,10 @@ complaining about lack of strict weak ordering.
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
index 7f654c220b..3f10c78c2f 100644
|
||||
index 962c525b7f..7db5024b54 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc
|
||||
@@ -2300,6 +2300,7 @@ int4 TypePartialEnum::compareDependency(const Datatype &op) const
|
||||
@@ -2303,6 +2303,7 @@ int4 TypePartialEnum::compareDependency(const Datatype &op) const
|
||||
|
||||
{
|
||||
if (submeta != op.getSubMeta()) return (submeta < op.getSubMeta()) ? -1 : 1;
|
||||
@@ -22,5 +22,5 @@ index 7f654c220b..3f10c78c2f 100644
|
||||
if (parent != tp->parent) return (parent < tp->parent) ? -1 : 1; // Compare absolute pointers
|
||||
if (offset != tp->offset) return (offset < tp->offset) ? -1 : 1;
|
||||
--
|
||||
2.48.1
|
||||
2.50.1
|
||||
|
||||
@@ -22,7 +22,7 @@ set_property(CACHE sleigh_RELEASE_TYPE PROPERTY STRINGS "stable" "HEAD")
|
||||
find_package(Git REQUIRED)
|
||||
|
||||
# Ghidra pinned stable version commit
|
||||
set(ghidra_version "11.3")
|
||||
set(ghidra_version "12.0.1")
|
||||
set(ghidra_git_tag "Ghidra_${ghidra_version}_build")
|
||||
set(ghidra_shallow TRUE)
|
||||
|
||||
@@ -40,19 +40,18 @@ set(ghidra_patches
|
||||
"${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"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/stable/0003-Use-string-resize-instead-of-reserve.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/stable/0004-Ignore-floating-point-test-due-to-compilation-differ.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/stable/0005-Allow-positive-or-negative-NAN-in-decompiler-floatin.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/stable/0006-decompiler-Fix-strict-weak-ordering-TypePartialEnum.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/stable/0003-Ignore-floating-point-test-due-to-compilation-differ.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/stable/0004-Allow-positive-or-negative-NAN-in-decompiler-floatin.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/stable/0005-decompiler-Fix-strict-weak-ordering-TypePartialEnum.patch"
|
||||
)
|
||||
|
||||
# Ghidra pinned commits used for pinning last known working HEAD commit
|
||||
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 "11.4")
|
||||
set(ghidra_head_version "12.1")
|
||||
set(ghidra_version "${ghidra_head_version}")
|
||||
set(ghidra_head_git_tag "5a3a8c36c8ec3b0f3b81c9d1b6200d5d5b521f2b")
|
||||
set(ghidra_head_git_tag "549735683cce5bd6220a4355de123a825ebff328")
|
||||
set(ghidra_git_tag "${ghidra_head_git_tag}")
|
||||
set(ghidra_shallow FALSE)
|
||||
set(ghidra_patches
|
||||
@@ -61,10 +60,9 @@ if("${sleigh_RELEASE_TYPE}" STREQUAL "HEAD")
|
||||
"${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-Use-string-resize-instead-of-reserve.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0004-Ignore-floating-point-test-due-to-compilation-differ.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0005-Allow-positive-or-negative-NAN-in-decompiler-floatin.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0006-decompiler-Fix-strict-weak-ordering-TypePartialEnum.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0003-Ignore-floating-point-test-due-to-compilation-differ.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0004-Allow-positive-or-negative-NAN-in-decompiler-floatin.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0005-decompiler-Fix-strict-weak-ordering-TypePartialEnum.patch"
|
||||
)
|
||||
string(SUBSTRING "${ghidra_git_tag}" 0 7 ghidra_short_commit)
|
||||
else()
|
||||
@@ -174,6 +172,7 @@ set(sleigh_deccore_source_list
|
||||
"${library_root}/signature.cc"
|
||||
"${library_root}/multiprecision.cc"
|
||||
"${library_root}/constseq.cc"
|
||||
"${library_root}/expression.cc"
|
||||
)
|
||||
#if("${sleigh_RELEASE_TYPE}" STREQUAL "HEAD")
|
||||
# list(APPEND sleigh_deccore_source_list
|
||||
|
||||
@@ -76,6 +76,8 @@ set(spec_file_list
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/MIPS/data/languages/mips32le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/MIPS/data/languages/mips64be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/MIPS/data/languages/mips64le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/NDS32/data/languages/nds32be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/NDS32/data/languages/nds32le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PA-RISC/data/languages/pa-risc32be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PIC/data/languages/PIC24E.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PIC/data/languages/PIC24F.slaspec"
|
||||
@@ -108,6 +110,7 @@ set(spec_file_list
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_64_isa_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_64_isa_vle_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_64_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/RISCV/data/languages/andestar_v5.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/RISCV/data/languages/riscv.ilp32d.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/RISCV/data/languages/riscv.lp64d.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Sparc/data/languages/SparcV9_32.slaspec"
|
||||
@@ -121,6 +124,7 @@ set(spec_file_list
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/TI_MSP430/data/languages/TI_MSP430X.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy64_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy64_be_harvard.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy64_be_harvard_rev.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy64_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy_be_posStack.slaspec"
|
||||
@@ -136,6 +140,7 @@ set(spec_file_list
|
||||
"${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_be.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"
|
||||
|
||||
@@ -76,6 +76,8 @@ set(spec_file_list
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/MIPS/data/languages/mips32le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/MIPS/data/languages/mips64be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/MIPS/data/languages/mips64le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/NDS32/data/languages/nds32be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/NDS32/data/languages/nds32le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PA-RISC/data/languages/pa-risc32be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PIC/data/languages/PIC24E.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PIC/data/languages/PIC24F.slaspec"
|
||||
@@ -108,6 +110,7 @@ set(spec_file_list
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_64_isa_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_64_isa_vle_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/PowerPC/data/languages/ppc_64_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/RISCV/data/languages/andestar_v5.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/RISCV/data/languages/riscv.ilp32d.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/RISCV/data/languages/riscv.lp64d.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Sparc/data/languages/SparcV9_32.slaspec"
|
||||
@@ -121,6 +124,7 @@ set(spec_file_list
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/TI_MSP430/data/languages/TI_MSP430X.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy64_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy64_be_harvard.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy64_be_harvard_rev.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy64_le.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy_be.slaspec"
|
||||
"${ghidrasource_SOURCE_DIR}/Ghidra/Processors/Toy/data/languages/toy_be_posStack.slaspec"
|
||||
@@ -136,6 +140,7 @@ set(spec_file_list
|
||||
"${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_be.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"
|
||||
|
||||
+11
-11
@@ -10,7 +10,7 @@
|
||||
# Tests from ghidra repo
|
||||
#
|
||||
|
||||
add_executable(sleigh_ghidra_test
|
||||
add_executable(sleigh_decomp_test
|
||||
${sleigh_core_source_list}
|
||||
${sleigh_deccore_source_list}
|
||||
${sleigh_source_list}
|
||||
@@ -27,31 +27,31 @@ add_executable(sleigh_ghidra_test
|
||||
)
|
||||
|
||||
# if(sleigh_RELEASE_IS_HEAD)
|
||||
# target_sources(sleigh_ghidra_test PRIVATE
|
||||
# target_sources(sleigh_decomp_test PRIVATE
|
||||
# )
|
||||
# endif()
|
||||
|
||||
target_compile_features(sleigh_ghidra_test PRIVATE cxx_std_11)
|
||||
target_include_directories(sleigh_ghidra_test PRIVATE "${library_root}")
|
||||
target_compile_features(sleigh_decomp_test PRIVATE cxx_std_11)
|
||||
target_include_directories(sleigh_decomp_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
|
||||
target_compile_definitions(sleigh_decomp_test PRIVATE
|
||||
__TERMINAL__
|
||||
)
|
||||
endif()
|
||||
sleigh_add_optional_defines(sleigh_ghidra_test PRIVATE)
|
||||
sleigh_add_optional_defines(sleigh_decomp_test PRIVATE)
|
||||
|
||||
target_link_libraries(sleigh_ghidra_test PRIVATE ZLIB::ZLIB)
|
||||
target_link_libraries(sleigh_decomp_test PRIVATE ZLIB::ZLIB)
|
||||
|
||||
add_test(
|
||||
NAME sleigh_ghidra_unittest
|
||||
COMMAND sleigh_ghidra_test -sleighpath "${PROJECT_BINARY_DIR}" unittests
|
||||
NAME sleigh_decomp_unittest
|
||||
COMMAND sleigh_decomp_test -sleighpath "${PROJECT_BINARY_DIR}" unittests
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME sleigh_ghidra_datatest
|
||||
COMMAND sleigh_ghidra_test -sleighpath "${PROJECT_BINARY_DIR}"
|
||||
NAME sleigh_decomp_datatest
|
||||
COMMAND sleigh_decomp_test -sleighpath "${PROJECT_BINARY_DIR}"
|
||||
-path "${library_root}/../datatests"
|
||||
datatests
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user