Changed files: ``` M Ghidra/Features/Decompiler/src/decompile/cpp/address.hh M Ghidra/Features/Decompiler/src/decompile/cpp/constseq.cc M Ghidra/Features/Decompiler/src/decompile/cpp/constseq.hh M Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_op.cc M Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc M Ghidra/Features/Decompiler/src/decompile/cpp/typeop.cc M Ghidra/Processors/8051/data/languages/80251.sinc M Ghidra/Processors/AARCH64/data/languages/AARCH64.pspec M Ghidra/Processors/AARCH64/data/languages/AARCH64neon.sinc M Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc M Ghidra/Processors/CR16/data/languages/CR16C.sinc M Ghidra/Processors/MIPS/data/languages/mips16.sinc M Ghidra/Processors/PIC/data/languages/pic18_instructions.sinc M Ghidra/Processors/PowerPC/data/languages/altivec.sinc M Ghidra/Processors/PowerPC/data/languages/ppc_vle.sinc M Ghidra/Processors/eBPF/data/languages/eBPF.sinc ``` Commit details: ``` [Commit 1/19] Hash: 1660b9ca4718c9907d279653a99c6d4190a1071f Date: 2026-02-09 15:33:05 +0000 Message: GP-6419: Fixed MIPS16 pcodetest failures Files changed: M Ghidra/Processors/MIPS/data/languages/mips16.sinc [Commit 2/19] Hash: a05ba1f778511e92abc29c933cb17da9477cc7c5 Date: 2026-02-05 23:13:56 +0000 Message: GP-6416 Add support for simplifying unequal LEFT then RIGHT shifts Files changed: M Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc [Commit 3/19] Hash: 690a23344f9de200056b8e7af4384e26f42e300b Date: 2026-02-05 19:28:59 +0000 Message: GP-6393 Deduplicate INDIRECT storage for HeapSequence Files changed: M Ghidra/Features/Decompiler/src/decompile/cpp/constseq.cc M Ghidra/Features/Decompiler/src/decompile/cpp/constseq.hh [Commit 4/19] Hash: 6ced49d1d7fd91663e7627b11fc4e68dd06bca1c Date: 2026-02-03 16:08:01 +0000 Message: GP-4241: Discoverable per-arch userop-lib framework and AARCH64 port. Files changed: M Ghidra/Processors/AARCH64/data/languages/AARCH64.pspec [Commit 5/19] Hash: 9a9b6cd063bc830c749804be0ab4213ec8de0010 Date: 2026-01-29 20:26:27 +0000 Message: GP-6388 Adjust getInputCast for TypeOpPtradd and TypeOpPtrsub Files changed: M Ghidra/Features/Decompiler/src/decompile/cpp/typeop.cc [Commit 6/19] Hash: c9be1860c181581ee192cb86e97eeec983a6bf00 Date: 2024-05-28 17:09:24 +0930 Message: AArch32: fixed ldrexd Details: * fixed addr src register aliased as first dest register of a double word load causing second word load at the value of first load Files changed: M Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc [Commit 7/19] Hash: c0bc9a882b7e6c6d3c0549c4410a8ae1abb68f00 Date: 2024-02-08 10:19:47 +0100 Message: PowerPC VLE: Fix se_blrl flow Details: Opcode se_blrl is branch link register and link. Treating it as a return break flow and is wrong. Non VLE is already correct. Files changed: M Ghidra/Processors/PowerPC/data/languages/ppc_vle.sinc [Commit 8/19] Hash: e94681701a89f34cf35edc18085684a8e40fc6b7 Date: 2025-12-02 02:03:52 +0100 Message: CR16: fix CR16C TBIT instruction Files changed: M Ghidra/Processors/CR16/data/languages/CR16C.sinc [Commit 9/19] Hash: af8a3704212b157d21bfddad834f6485fdfabeb1 Date: 2025-12-02 22:00:49 +0100 Message: Fix eBPF compare-and-exchange instruction Details: Linux kernel's documentation tells in https://www.kernel.org/doc/html/v6.0/bpf/instruction-set.html#atomic-operations > The BPF_CMPXCHG operation atomically compares the value addressed by > dst_reg + off with R0. If they match, the value addressed by > dst_reg + off is replaced with src_reg. In either case, the value that > was at dst_reg + off before the operation is zero-extended and loaded > back to R0. If the values don't match, *(dst_reg + off) is not supposed to be modified. Moreover, register R0 is always modified and the 32-bit instruction truncates its value (with a zero-extension). This is also clear in the implementation of BPF_CMPXCHG in https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/bpf/core.c?h=v6.18#n2186 case BPF_CMPXCHG: if (BPF_SIZE(insn->code) == BPF_W) BPF_R0 = (u32) atomic_cmpxchg( (atomic_t *)(unsigned long) (DST + insn->off), (u32) BPF_R0, (u32) SRC); else if (BPF_SIZE(insn->code) == BPF_DW) BPF_R0 = (u64) atomic64_cmpxchg( (atomic64_t *)(unsigned long) (DST + insn->off), (u64) BPF_R0, (u64) SRC); Fix the semantic of the compare-and-exchange instruction accordingly. Files changed: M Ghidra/Processors/eBPF/data/languages/eBPF.sinc [Commit 10/19] Hash: ff6eb2213bca878cdcef0e9cec20e524d8d9f944 Date: 2025-12-02 16:19:37 +0100 Message: Fix disassembly of eBPF atomic instructions Details: eBPF ISA v3 introduced atomic instructions: https://www.kernel.org/doc/html/v6.0/bpf/instruction-set.html#atomic-operations These instructions are encoded using BPF_ATOMIC | BPF_W | BPF_STX and BPF_ATOMIC | BPF_DW | BPF_STX for 32-bit and 64-bit operations, with: BPF_ATOMIC = 0xc0 BPF_DW = 0x18 BPF_W = 0 BPF_STX = 0x03 While Ghidra's semantic section is constructed correctly (atomic add uses an addition ; atomic or uses or ; ...), the disassembly always displays STXXADDW and STXXADDDW. These mnemonics come from the deprecated name BPF_XADD = BPF_ATOMIC | BPF_ADD = 0xc0. Replace the confusing mnemonics with the ones used by binutils and documented in https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gas/doc/c-bpf.texi;h=003cb92a457985038a9abc1ffbf347f636eb0586;hb=2bc7af1ff7732451b6a7b09462a815c3284f9613#l745 Files changed: M Ghidra/Processors/eBPF/data/languages/eBPF.sinc [Commit 11/19] Hash: c1f97cde08ab235c0fe9adb723971a608550fdc2 Date: 2025-12-22 19:47:24 +0100 Message: Fix missing Altivec vadduws instruction Files changed: M Ghidra/Processors/PowerPC/data/languages/altivec.sinc [Commit 12/19] Hash: c981c0b5dd19818117178f3ce4a9d8737c306e65 Date: 2025-12-16 20:07:56 +0000 Message: GP-6004: Refactored out duplicated constructors Files changed: M Ghidra/Processors/PIC/data/languages/pic18_instructions.sinc [Commit 13/19] Hash: 78859d55fdf28dfbe9dac0658948754515d44e36 Date: 2025-12-04 19:25:56 +0000 Message: GP-5905: Fixed issue with 80251 instructions referencing SPX register Files changed: M Ghidra/Processors/8051/data/languages/80251.sinc [Commit 14/19] Hash: 826834c424b631358f06899dfd0203138ba2cb7d Date: 2025-11-25 13:32:37 +0100 Message: decompiler: Fix extreme value checks in Funcdata::replaceLessequal Details: Fixes https://github.com/NationalSecurityAgency/ghidra/issues/8696 The checks for extreme values when transforming <= to < were incomplete and relied on undefined behavior, making compilers optimize them out. Specifically, for SLESS_EQUAL, the decompiler relied on integer overflows. For integers smaller than 8 bytes, no overflow will occur when adding 1, resulting in a missed case and, thus, x <= INT_MAX will become x < INT_MIN. For the signed case when subtracting one, the compiler removes the check due to undefined behavior, resulting in another missed case. To fix this, add helper functions for computing maximum and minimum values for signed and unsigned varnodes and directly check for them. Files changed: M Ghidra/Features/Decompiler/src/decompile/cpp/address.hh M Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_op.cc [Commit 15/19] Hash: 2e3bedf7daf1c5c38cbf1c3f90b6f4cd449f7020 Date: 2025-11-04 13:50:15 +0000 Message: GP-6004: Corrected bit-pattern comments Files changed: M Ghidra/Processors/PIC/data/languages/pic18_instructions.sinc [Commit 16/19] Hash: 49c13a7ba733f2af63f3d33d83cba8103456249e Date: 2025-09-17 10:43:57 +0200 Message: missed one Files changed: M Ghidra/Processors/PIC/data/languages/pic18_instructions.sinc [Commit 17/19] Hash: 48ca4badb7ea2eb18ffd6f9b6ede356932160067 Date: 2025-09-13 16:17:07 -0700 Message: forgot to take out this change Files changed: M Ghidra/Processors/PIC/data/languages/pic18_instructions.sinc [Commit 18/19] Hash: 7fa6bda98ee9a350be49c0b4a8f9cf8c83b39490 Date: 2025-09-10 00:58:15 -0700 Message: remove destREG to fix double inc/dec Files changed: M Ghidra/Processors/PIC/data/languages/pic18_instructions.sinc [Commit 19/19] Hash: 5e4522fc3a2a547c9b1c94ab293890bb9f767ac3 Date: 2024-04-09 16:43:13 +0930 Message: AA64: Change sha1h shift to rotate Files changed: M Ghidra/Processors/AARCH64/data/languages/AARCH64neon.sinc ``` --------- Co-authored-by: Eric Kilmer <eric.d.kilmer@gmail.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sleigh Library
Sleigh 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 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.
Supported Platforms
| Name | Support |
|---|---|
| Linux | Yes |
| macOS | Yes |
| Windows | Yes |
Dependencies and Prerequisites
Required
| Name | Version | Linux Package to Install | macOS Homebrew Package to Install |
|---|---|---|---|
| (HEAD builds) zlib | Recent | zlib1g-dev | zlib |
| Git | Latest | git | N/A |
| CMake | 3.18+ | cmake | cmake |
NOTE: This CMake project pulls the Ghidra source code from the internet during configuration. See the note on Ghidra source code section for more details.
Optional
For building documentation:
| Name | Version | Linux Package to Install | macOS Homebrew Package to Install |
|---|---|---|---|
| Doxygen | Latest | doxygen | doxygen |
| GraphViz | Latest | graphviz | graphviz |
Build and Install the Sleigh Library
# Clone this repository (CMake project for sleigh)
git clone https://github.com/lifting-bits/sleigh.git
cd sleigh
# Configure CMake
cmake -B build -S .
# Build Sleigh
cmake --build build --parallel 8
# Install Sleigh
cmake --install build --prefix ./install
Note on Ghidra source code
The Ghidra source code is not actually included in this git repo, and by default, CMake will automatically pull a stable version from the internet for you.
Please see src/README.md for more information on how to customize which Ghidra source code commit will be used/compiled, including specifying your own local copy of the Ghidra source.
Packaging
The CMake configuration also supports building packages for Sleigh.
For example:
# Package Sleigh
cmake --build build --target package
API Usage
An example program called sleigh-lift has been included to demonstrate how to use the Sleigh API. It takes a hexadecimal string of bytes and can disassemble it or lift it to p-code. The program can be invoked as follows, where the action argument must be either disassemble or pcode:
sleigh-lift [action] [sla_file] [bytes] [-a address] [-p root_sla_dir] [-s pspec_file]
For example, to disassemble the following byte string:
$ sleigh-lift disassemble x86-64.sla 4881ecc00f0000
0x00000000: SUB RSP,0xfc0
And to lift it to p-code:
$ sleigh-lift pcode x86-64.sla 4881ecc00f0000
(register,0x200,1) = INT_LESS (register,0x20,8) (const,0xfc0,8)
(register,0x20b,1) = INT_SBORROW (register,0x20,8) (const,0xfc0,8)
(register,0x20,8) = INT_SUB (register,0x20,8) (const,0xfc0,8)
(register,0x207,1) = INT_SLESS (register,0x20,8) (const,0x0,8)
(register,0x206,1) = INT_EQUAL (register,0x20,8) (const,0x0,8)
(unique,0x12c00,8) = INT_AND (register,0x20,8) (const,0xff,8)
(unique,0x12c80,1) = POPCOUNT (unique,0x12c00,8)
(unique,0x12d00,1) = INT_AND (unique,0x12c80,1) (const,0x1,1)
(register,0x202,1) = INT_EQUAL (unique,0x12d00,1) (const,0x0,1)
If you do not want to build sleigh-lift, you must set the CMake variable sleigh_BUILD_EXTRATOOLS option to OFF during CMake configuration.
Helpers
This repository contains a helper not part of Sleigh/Ghidra, which you can find in the support directory. It has the following signature and can help the user find the location of a given spec file on the system:
std::optional<std::filesystem::path>
FindSpecFile(std::string_view file_name,
const std::vector<std::filesystem::path> &search_paths =
gDefaultSearchPaths);
The sleigh::FindSpecFile function will search the paths provided by the user via the search_paths argument for a spec file with the name file_name. The default argument for search_paths is sleigh::gDefaultSearchPaths which contains the install/build directories generated during CMake configuration and a set of common installation locations.
If you do not want to build the helpers, you must set the CMake variable sleigh_BUILD_SUPPORT option to OFF during CMake configuration.
Integration as a Dependency
An installation of Sleigh provides a CMake interface that you can use when building your project.
You can find an example of how to use the CMake package config file in the find_package example.
We also provide a CMake helper function sleigh_compile to compile your .slaspec files using a sleigh compiler.
You can find a more complex CMake example with compiling Sleigh specifications in the example directory, which uses the upstream-provided sleigh example source code.
Lastly, you can locate the installed compiled sleigh files through the CMake variable sleigh_INSTALL_SPECDIR, which is an absolute path to the root directory for the compiled sleigh files---you should manually inspect this to know what to expect.
Referencing the CMake config file and specfiles CMake file is also suggested for learning more about the exposed CMake variables and modules.
License
See the LICENSE file.