From b6adc0337ac3479a28f1f580ec6ef634f7bc7396 Mon Sep 17 00:00:00 2001 From: Eric Kilmer Date: Wed, 25 Feb 2026 20:55:01 +0000 Subject: [PATCH 1/5] Add ASAN/UBSAN CI testing and fix signed left shift UB Add a sanitizer CI job that builds and tests with AddressSanitizer and UndefinedBehaviorSanitizer using clang on Ubuntu for both stable and HEAD release tracks. Fix three UBSAN signed left shift errors found during sanitizer testing by casting signed values to unsigned before left shifting: - address.hh sign_extend(): left shift of negative value / overflow - slghpatexpress.cc LeftShiftExpression: left shift of negative value Co-Authored-By: Claude Opus 4.6 --- .github/workflows/main.yml | 91 +++++++++++++++++++ ...8-Fix-UBSAN-signed-left-shift-errors.patch | 57 ++++++++++++ ...6-Fix-UBSAN-signed-left-shift-errors.patch | 57 ++++++++++++ src/setup-ghidra-source.cmake | 2 + 4 files changed, 207 insertions(+) create mode 100644 src/patches/HEAD/0008-Fix-UBSAN-signed-left-shift-errors.patch create mode 100644 src/patches/stable/0006-Fix-UBSAN-signed-left-shift-errors.patch diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3543c7a..03259ec 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -254,3 +254,94 @@ jobs: - name: ccache stats run: ccache -s + + sanitizer: + runs-on: ubuntu-latest + permissions: + contents: read + + env: + CXX: clang++ + ASAN_OPTIONS: strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:detect_leaks=1 + UBSAN_OPTIONS: print_stacktrace=1 + + strategy: + fail-fast: false + matrix: + release: [stable, HEAD] + + steps: + - uses: actions/checkout@v6 + + - name: Setup Git User for Applying Patches + run: | + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + + - name: Install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y ccache + + - name: Generate cache key + shell: cmake -P {0} + run: | + string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC) + file(APPEND "$ENV{GITHUB_ENV}" "CACHE_KEY=sanitizer_${{ matrix.release }}\n") + file(APPEND "$ENV{GITHUB_ENV}" "CACHE_TIMESTAMP=${current_date}\n") + + - name: Update the cache (ccache) + uses: actions/cache@v5 + with: + path: "${{ github.workspace }}/ccache" + key: ${{ env.CACHE_KEY }}_ccache_${{ env.CACHE_TIMESTAMP }} + restore-keys: | + ${{ env.CACHE_KEY }}_ccache_ + + - name: Setup ccache + working-directory: "${{ github.workspace }}" + shell: cmake -P {0} + 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") + file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_COMPRESS=true\n") + file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_COMPRESSLEVEL=10\n") + file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_MAXSIZE=400M\n") + file(APPEND "$ENV{GITHUB_ENV}" "CMAKE_CXX_COMPILER_LAUNCHER=ccache\n") + file(APPEND "$ENV{GITHUB_ENV}" "CMAKE_C_COMPILER_LAUNCHER=ccache\n") + execute_process(COMMAND ccache -z) + + - name: Configure the project + run: cmake --preset=ci-sanitize + -Dsleigh_RELEASE_TYPE=${{ matrix.release }} + -Dsleigh_BUILD_DOCUMENTATION=OFF + + - name: Build the project + run: cmake + --build build/sanitize + -j 4 + -v + + - name: Test the project + working-directory: build/sanitize + run: ctest -VV + + - name: Run the example + run: cmake + --build build/sanitize + -j 4 + --target sleigh_example_runner + + - name: Run the install target + run: cmake --install build/sanitize + --prefix install + + - name: Smoketest sleigh lift + run: | + ./install/bin/sleigh-lift --version + ./install/bin/sleigh-lift disassemble x86-64.sla 4881ecc00f0000 + ./install/bin/sleigh-lift pcode x86-64.sla 4881ecc00f0000 + + - name: ccache stats + run: ccache -s diff --git a/src/patches/HEAD/0008-Fix-UBSAN-signed-left-shift-errors.patch b/src/patches/HEAD/0008-Fix-UBSAN-signed-left-shift-errors.patch new file mode 100644 index 0000000..d269a2b --- /dev/null +++ b/src/patches/HEAD/0008-Fix-UBSAN-signed-left-shift-errors.patch @@ -0,0 +1,57 @@ +From 8afa7d89a368b358a5493b87804985ed9ac70a2f Mon Sep 17 00:00:00 2001 +From: "github-actions[bot]" + <41898282+github-actions[bot]@users.noreply.github.com> +Date: Wed, 25 Feb 2026 20:41:10 +0000 +Subject: [PATCH] Fix UBSAN signed left shift errors + +Cast signed values to unsigned before left shifting to avoid undefined +behavior when the signed value is negative or when the result cannot be +represented in the signed type. + +Fixes runtime errors detected by UndefinedBehaviorSanitizer: +- address.hh sign_extend(): left shift of negative value +- address.hh sign_extend(): left shift cannot be represented in type 'intb' +- slghpatexpress.cc LeftShiftExpression: left shift of negative value +--- + Ghidra/Features/Decompiler/src/decompile/cpp/address.hh | 2 +- + .../Features/Decompiler/src/decompile/cpp/slghpatexpress.cc | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh +index 45144daf3..0e75c68b8 100644 +--- a/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh ++++ b/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh +@@ -544,7 +544,7 @@ inline intb sign_extend(intb val,int4 bit) + + { + int4 sa = 8*sizeof(intb) - (bit+1); +- val = (val << sa) >> sa; ++ val = static_cast(static_cast(val) << sa) >> sa; + return val; + } + +diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc +index 941097859..93cce378a 100644 +--- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc ++++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc +@@ -969,7 +969,7 @@ intb LeftShiftExpression::getValue(ParserWalker &walker) const + { + intb leftval = getLeft()->getValue(walker); + intb rightval = getRight()->getValue(walker); +- return leftval << rightval; ++ return static_cast(static_cast(leftval) << rightval); + } + + intb LeftShiftExpression::getSubValue(const vector &replace,int4 &listpos) const +@@ -977,7 +977,7 @@ intb LeftShiftExpression::getSubValue(const vector &replace,int4 &listpos) + { + intb leftval = getLeft()->getSubValue(replace,listpos); // Must be left first + intb rightval = getRight()->getSubValue(replace,listpos); +- return leftval << rightval; ++ return static_cast(static_cast(leftval) << rightval); + } + + void LeftShiftExpression::encode(Encoder &encoder) const +-- +2.51.1 + diff --git a/src/patches/stable/0006-Fix-UBSAN-signed-left-shift-errors.patch b/src/patches/stable/0006-Fix-UBSAN-signed-left-shift-errors.patch new file mode 100644 index 0000000..91b4d8c --- /dev/null +++ b/src/patches/stable/0006-Fix-UBSAN-signed-left-shift-errors.patch @@ -0,0 +1,57 @@ +From 8afa7d89a368b358a5493b87804985ed9ac70a2f Mon Sep 17 00:00:00 2001 +From: "github-actions[bot]" + <41898282+github-actions[bot]@users.noreply.github.com> +Date: Wed, 25 Feb 2026 20:41:10 +0000 +Subject: [PATCH] Fix UBSAN signed left shift errors + +Cast signed values to unsigned before left shifting to avoid undefined +behavior when the signed value is negative or when the result cannot be +represented in the signed type. + +Fixes runtime errors detected by UndefinedBehaviorSanitizer: +- address.hh sign_extend(): left shift of negative value +- address.hh sign_extend(): left shift cannot be represented in type 'intb' +- slghpatexpress.cc LeftShiftExpression: left shift of negative value +--- + Ghidra/Features/Decompiler/src/decompile/cpp/address.hh | 2 +- + .../Features/Decompiler/src/decompile/cpp/slghpatexpress.cc | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh +index 45144daf3..0e75c68b8 100644 +--- a/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh ++++ b/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh +@@ -544,7 +544,7 @@ inline intb sign_extend(intb val,int4 bit) + + { + int4 sa = 8*sizeof(intb) - (bit+1); +- val = (val << sa) >> sa; ++ val = static_cast(static_cast(val) << sa) >> sa; + return val; + } + +diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc +index 941097859..93cce378a 100644 +--- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc ++++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc +@@ -969,7 +969,7 @@ intb LeftShiftExpression::getValue(ParserWalker &walker) const + { + intb leftval = getLeft()->getValue(walker); + intb rightval = getRight()->getValue(walker); +- return leftval << rightval; ++ return static_cast(static_cast(leftval) << rightval); + } + + intb LeftShiftExpression::getSubValue(const vector &replace,int4 &listpos) const +@@ -977,7 +977,7 @@ intb LeftShiftExpression::getSubValue(const vector &replace,int4 &listpos) + { + intb leftval = getLeft()->getSubValue(replace,listpos); // Must be left first + intb rightval = getRight()->getSubValue(replace,listpos); +- return leftval << rightval; ++ return static_cast(static_cast(leftval) << rightval); + } + + void LeftShiftExpression::encode(Encoder &encoder) const +-- +2.51.1 + diff --git a/src/setup-ghidra-source.cmake b/src/setup-ghidra-source.cmake index 5dcd98d..cc1e2ac 100644 --- a/src/setup-ghidra-source.cmake +++ b/src/setup-ghidra-source.cmake @@ -43,6 +43,7 @@ set(ghidra_patches "${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" + "${CMAKE_CURRENT_LIST_DIR}/patches/stable/0006-Fix-UBSAN-signed-left-shift-errors.patch" ) # Ghidra pinned commits used for pinning last known working HEAD commit @@ -65,6 +66,7 @@ if("${sleigh_RELEASE_TYPE}" STREQUAL "HEAD") "${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0005-decompiler-Fix-strict-weak-ordering-TypePartialEnum.patch" "${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0006-decompiler-Fix-strict-weak-ordering-PullRecord.patch" "${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0007-decompiler-Fix-strict-weak-ordering-compareFinalOrde.patch" + "${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0008-Fix-UBSAN-signed-left-shift-errors.patch" ) string(SUBSTRING "${ghidra_git_tag}" 0 7 ghidra_short_commit) else() From 876fc733fb6fa6af2126e64017067354e3df6399 Mon Sep 17 00:00:00 2001 From: Eric Kilmer Date: Wed, 25 Feb 2026 21:01:15 +0000 Subject: [PATCH 2/5] Add libc++ assertions CI job for strict-weak ordering checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a ci-assertions CMake preset that builds with libc++ in debug hardening mode (_LIBCPP_HARDENING_MODE_DEBUG), which catches STL contract violations at runtime — most importantly strict-weak ordering violations in comparators passed to std::sort. Add a corresponding assertions CI job that runs HEAD-only, since new comparator bugs from upstream Ghidra surface there first. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/main.yml | 68 ++++++++++++++++++++++++++++++++++++++ CMakePresets.json | 12 +++++++ 2 files changed, 80 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 03259ec..f920362 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -345,3 +345,71 @@ jobs: - name: ccache stats run: ccache -s + + assertions: + runs-on: ubuntu-latest + permissions: + contents: read + + env: + CXX: clang++ + + steps: + - uses: actions/checkout@v6 + + - name: Setup Git User for Applying Patches + run: | + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + + - name: Install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y ccache libc++-dev libc++abi-dev + + - name: Generate cache key + shell: cmake -P {0} + run: | + string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC) + file(APPEND "$ENV{GITHUB_ENV}" "CACHE_KEY=assertions_HEAD\n") + file(APPEND "$ENV{GITHUB_ENV}" "CACHE_TIMESTAMP=${current_date}\n") + + - name: Update the cache (ccache) + uses: actions/cache@v5 + with: + path: "${{ github.workspace }}/ccache" + key: ${{ env.CACHE_KEY }}_ccache_${{ env.CACHE_TIMESTAMP }} + restore-keys: | + ${{ env.CACHE_KEY }}_ccache_ + + - name: Setup ccache + working-directory: "${{ github.workspace }}" + shell: cmake -P {0} + 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") + file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_COMPRESS=true\n") + file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_COMPRESSLEVEL=10\n") + file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_MAXSIZE=400M\n") + file(APPEND "$ENV{GITHUB_ENV}" "CMAKE_CXX_COMPILER_LAUNCHER=ccache\n") + file(APPEND "$ENV{GITHUB_ENV}" "CMAKE_C_COMPILER_LAUNCHER=ccache\n") + execute_process(COMMAND ccache -z) + + - name: Configure the project + run: cmake --preset=ci-assertions + -Dsleigh_RELEASE_TYPE=HEAD + -Dsleigh_BUILD_DOCUMENTATION=OFF + + - name: Build the project + run: cmake + --build build/assertions + -j 4 + -v + + - name: Test the project + working-directory: build/assertions + run: ctest -VV + + - name: ccache stats + run: ccache -s diff --git a/CMakePresets.json b/CMakePresets.json index 3d9539f..c89345b 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -114,6 +114,18 @@ "CMAKE_CXX_FLAGS_SANITIZE": "-O2 -g -fsanitize=address,undefined -fno-omit-frame-pointer -fno-common" } }, + { + "name": "ci-assertions", + "binaryDir": "${sourceDir}/build/assertions", + "inherits": ["ci-unix", "dev-mode"], + "cacheVariables": { + "CMAKE_CXX_COMPILER": "clang++", + "CMAKE_BUILD_TYPE": "Assertions", + "CMAKE_CXX_FLAGS_ASSERTIONS": "-O0 -g -stdlib=libc++ -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG -fstack-protector-strong", + "CMAKE_EXE_LINKER_FLAGS_ASSERTIONS": "-stdlib=libc++ -lc++abi", + "CMAKE_SHARED_LINKER_FLAGS_ASSERTIONS": "-stdlib=libc++ -lc++abi" + } + }, { "name": "ci-build", "binaryDir": "${sourceDir}/build", From 27289bcc29e40ec4e025be014fc6b7c8fe936ab6 Mon Sep 17 00:00:00 2001 From: Eric Kilmer Date: Wed, 25 Feb 2026 21:20:06 +0000 Subject: [PATCH 3/5] Install LLVM explicitly in sanitizer and assertions CI jobs Use the official LLVM apt script to install clang rather than relying on whichever version happens to ship on the runner. The version is configured via a workflow-level LLVM_VERSION env variable (currently 21) so bumping is a one-line change. The assertions job also installs the matching versioned libc++-dev and libc++abi-dev packages. Remove CMAKE_CXX_COMPILER from the ci-assertions preset so the CXX environment variable is respected by CMake in both CI and local use. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/main.yml | 30 ++++++++++++++++++++++++------ CMakePresets.json | 1 - 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f920362..0e36606 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,6 +13,9 @@ on: branches: - "*" +env: + LLVM_VERSION: 21 + jobs: build: runs-on: ${{ matrix.os }} @@ -261,7 +264,6 @@ jobs: contents: read env: - CXX: clang++ ASAN_OPTIONS: strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:detect_leaks=1 UBSAN_OPTIONS: print_stacktrace=1 @@ -278,6 +280,13 @@ jobs: git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" git config --global user.name "github-actions[bot]" + - name: Install LLVM + run: | + wget -qO /tmp/llvm.sh https://apt.llvm.org/llvm.sh + chmod +x /tmp/llvm.sh + sudo /tmp/llvm.sh $LLVM_VERSION + echo "CXX=clang++-$LLVM_VERSION" >> "$GITHUB_ENV" + - name: Install system dependencies run: | sudo apt-get update @@ -351,8 +360,10 @@ jobs: permissions: contents: read - env: - CXX: clang++ + strategy: + fail-fast: false + matrix: + release: [stable, HEAD] steps: - uses: actions/checkout@v6 @@ -362,16 +373,23 @@ jobs: git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" git config --global user.name "github-actions[bot]" + - name: Install LLVM + run: | + wget -qO /tmp/llvm.sh https://apt.llvm.org/llvm.sh + chmod +x /tmp/llvm.sh + sudo /tmp/llvm.sh $LLVM_VERSION + echo "CXX=clang++-$LLVM_VERSION" >> "$GITHUB_ENV" + - name: Install system dependencies run: | sudo apt-get update - sudo apt-get install -y ccache libc++-dev libc++abi-dev + sudo apt-get install -y ccache libc++-$LLVM_VERSION-dev libc++abi-$LLVM_VERSION-dev - name: Generate cache key shell: cmake -P {0} run: | string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC) - file(APPEND "$ENV{GITHUB_ENV}" "CACHE_KEY=assertions_HEAD\n") + file(APPEND "$ENV{GITHUB_ENV}" "CACHE_KEY=assertions_${{ matrix.release }}\n") file(APPEND "$ENV{GITHUB_ENV}" "CACHE_TIMESTAMP=${current_date}\n") - name: Update the cache (ccache) @@ -398,7 +416,7 @@ jobs: - name: Configure the project run: cmake --preset=ci-assertions - -Dsleigh_RELEASE_TYPE=HEAD + -Dsleigh_RELEASE_TYPE=${{ matrix.release }} -Dsleigh_BUILD_DOCUMENTATION=OFF - name: Build the project diff --git a/CMakePresets.json b/CMakePresets.json index c89345b..7de58c0 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -119,7 +119,6 @@ "binaryDir": "${sourceDir}/build/assertions", "inherits": ["ci-unix", "dev-mode"], "cacheVariables": { - "CMAKE_CXX_COMPILER": "clang++", "CMAKE_BUILD_TYPE": "Assertions", "CMAKE_CXX_FLAGS_ASSERTIONS": "-O0 -g -stdlib=libc++ -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG -fstack-protector-strong", "CMAKE_EXE_LINKER_FLAGS_ASSERTIONS": "-stdlib=libc++ -lc++abi", From f696911f6724ea40afcde0872161738c3cae59c6 Mon Sep 17 00:00:00 2001 From: Eric Kilmer Date: Wed, 25 Feb 2026 22:04:22 +0000 Subject: [PATCH 4/5] Drop Debug builds on Linux and macOS in favor of sanitizer/assertions The sanitizer and assertions CI jobs provide more useful Debug-like coverage on Linux than a plain Debug build. Keep Debug builds only for Windows where sanitizers are not available. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/main.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0e36606..a423b8a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,6 +26,11 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] build_type: [RelWithDebInfo, Debug] release: [stable, HEAD] + exclude: + - os: ubuntu-latest + build_type: Debug + - os: macos-latest + build_type: Debug steps: - uses: actions/checkout@v6 From 0c1eeeae774221e493b2f1b2ab50ca8954edddcf Mon Sep 17 00:00:00 2001 From: Eric Kilmer Date: Wed, 25 Feb 2026 22:23:39 +0000 Subject: [PATCH 5/5] Add compareFinalOrder strict-weak ordering patch to stable Port the existing HEAD patch (0007) to stable as well. FlowBlock::compareFinalOrder returns true when both blocks have index 0, violating strict weak ordering irreflexivity. This is caught by the libc++ assertions CI job. Co-Authored-By: Claude Opus 4.6 --- ...trict-weak-ordering-compareFinalOrde.patch | 29 +++++++++++++++++++ ...-Fix-UBSAN-signed-left-shift-errors.patch} | 0 src/setup-ghidra-source.cmake | 3 +- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 src/patches/stable/0006-decompiler-Fix-strict-weak-ordering-compareFinalOrde.patch rename src/patches/stable/{0006-Fix-UBSAN-signed-left-shift-errors.patch => 0007-Fix-UBSAN-signed-left-shift-errors.patch} (100%) diff --git a/src/patches/stable/0006-decompiler-Fix-strict-weak-ordering-compareFinalOrde.patch b/src/patches/stable/0006-decompiler-Fix-strict-weak-ordering-compareFinalOrde.patch new file mode 100644 index 0000000..c6e1d28 --- /dev/null +++ b/src/patches/stable/0006-decompiler-Fix-strict-weak-ordering-compareFinalOrde.patch @@ -0,0 +1,29 @@ +From c435df4c0dbab80d8ff85e364cea9b59bf7010a1 Mon Sep 17 00:00:00 2001 +From: "github-actions[bot]" + <41898282+github-actions[bot]@users.noreply.github.com> +Date: Wed, 25 Feb 2026 22:22:05 +0000 +Subject: [PATCH] decompiler: Fix strict weak ordering compareFinalOrder + +FlowBlock::compareFinalOrder returns true when both blocks have index 0, +violating strict weak ordering (irreflexivity). This is caught by libc++ +debug mode hardening assertions during BlockGraph::orderBlocks sort. +--- + Ghidra/Features/Decompiler/src/decompile/cpp/block.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/block.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/block.cc +index bf7103d91..2e495d9c3 100644 +--- a/Ghidra/Features/Decompiler/src/decompile/cpp/block.cc ++++ b/Ghidra/Features/Decompiler/src/decompile/cpp/block.cc +@@ -709,7 +709,7 @@ string FlowBlock::typeToName(FlowBlock::block_type bt) + bool FlowBlock::compareFinalOrder(const FlowBlock *bl1,const FlowBlock *bl2) + + { +- if (bl1->getIndex() == 0) return true; // Make sure the entry point comes first ++ if (bl1->getIndex() == 0) return (bl2->getIndex() != 0); // Make sure the entry point comes first + if (bl2->getIndex() == 0) return false; + PcodeOp *op1 = bl1->lastOp(); + PcodeOp *op2 = bl2->lastOp(); +-- +2.51.1 + diff --git a/src/patches/stable/0006-Fix-UBSAN-signed-left-shift-errors.patch b/src/patches/stable/0007-Fix-UBSAN-signed-left-shift-errors.patch similarity index 100% rename from src/patches/stable/0006-Fix-UBSAN-signed-left-shift-errors.patch rename to src/patches/stable/0007-Fix-UBSAN-signed-left-shift-errors.patch diff --git a/src/setup-ghidra-source.cmake b/src/setup-ghidra-source.cmake index cc1e2ac..e34b8b1 100644 --- a/src/setup-ghidra-source.cmake +++ b/src/setup-ghidra-source.cmake @@ -43,7 +43,8 @@ set(ghidra_patches "${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" - "${CMAKE_CURRENT_LIST_DIR}/patches/stable/0006-Fix-UBSAN-signed-left-shift-errors.patch" + "${CMAKE_CURRENT_LIST_DIR}/patches/stable/0006-decompiler-Fix-strict-weak-ordering-compareFinalOrde.patch" + "${CMAKE_CURRENT_LIST_DIR}/patches/stable/0007-Fix-UBSAN-signed-left-shift-errors.patch" ) # Ghidra pinned commits used for pinning last known working HEAD commit