# How Ghidra's SLEIGH Language Works for Defining New Processor Specifications

> Discover how Ghidra's SLEIGH language defines new processor specifications. Learn how it compiles descriptions into binary files for disassembly, p-code generation, and emulation.

- Repository: [National Security Agency/ghidra](https://github.com/NationalSecurityAgency/ghidra)
- Tags: deep-dive
- Published: 2026-03-04

---

**Ghidra's SLEIGH language compiles human-readable processor descriptions into binary `.sla` files, which the `SleighLanguage` class loads at runtime to power disassembly, p-code generation, and emulation without custom Java implementations.**

The NationalSecurityAgency/ghidra repository implements processor support through SLEIGH, a domain-specific language that decouples architectural definitions from the core framework. This system enables reverse engineers to add support for new CPUs by writing declarative text files rather than modifying the Java source code directly.

## Understanding the SLEIGH Specification File (.slaspec)

A SLEIGH specification resides in a `.slaspec` file that declares the fundamental properties of a processor architecture. The skeleton processor shipped with Ghidra demonstrates the essential structure in `GhidraBuild/Skeleton/data/languages/skel.slaspec`.

Key declarations include:

- **Endianness and alignment**: `define endian=little;` and `define alignment=1;` establish byte order and instruction boundaries.
- **Address spaces**: `define space ram type=ram_space size=2 default;` creates distinct memory regions for RAM, registers, and I/O.
- **Registers**: `define register offset=0x00 size=1 [ F A C B E D L H I R ];` maps names to offsets within a register space.
- **Context variables**: `define register offset=0xf0 size=4 contextreg;` allocates bits for processor state flags that affect decoding.
- **Includes**: `@include "skel.sinc"` reuses common macro definitions across multiple specifications.

Real-world implementations like the x86 module compose specifications from multiple included files. The `x86.slaspec` file demonstrates how complex architectures organize definitions across separate `.sinc` files for maintainability.

## The SLEIGH Build Pipeline: From Source to Binary

Before Ghidra can use a specification, the text-based `.slaspec` must transform into a binary `.sla` format through a two-stage build process.

### Preprocessing with SleighPreprocessor

The `SleighPreprocessor` class in [`Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighPreprocessor.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighPreprocessor.java) handles the first stage. This component resolves `@include` directives, expands macro definitions declared with `@define`, and processes conditional compilation blocks.

The preprocessor constructs a `ModuleDefinitionsAdapter` that manages include paths and timestamps for stale-file detection, ensuring that changes to included files trigger recompilation.

### Compilation via SleighCompileLauncher

The `SleighCompileLauncher` class orchestrates the transition from preprocessed text to binary format. Located at [`Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighCompileLauncher.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighCompileLauncher.java), this launcher:

1. Locates the `.slaspec` source file and checks if compilation is necessary via `SleighLanguage.isSLAStale`.
2. Invokes the native `slgh` compiler (a C++ binary) with appropriate flags.
3. Writes the resulting `.sla` file adjacent to the source specification.

The native compiler performs semantic analysis and encodes the specification into an efficient binary representation for runtime consumption.

## Runtime Architecture: Loading and Execution

At runtime, Ghidra's analysis engine loads the compiled `.sla` file to construct an in-memory model of the processor.

### Deserializing the .sla Format

The `SleighLanguage` constructor in [`Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguage.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguage.java) manages the loading process. If the binary is missing or stale, the constructor calls `reloadLanguage` to trigger recompilation.

The actual decoding occurs through `SlaFormat.buildDecoder`, implemented in [`Ghidra/pcode/utils/SlaFormat.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/pcode/utils/SlaFormat.java):

```java
PackedDecode decoder = SlaFormat.buildDecoder(slaFile);
decode(decoder);  // populates SleighLanguage fields

```

The `decode` method populates critical data structures including the address space table (`spacetable`), register hierarchy (`registerBuilder`), context settings (`ContextCache`), and the instruction constructor definitions.

### Pattern Matching and Constructor Resolution

After decoding, the language builds a decision tree of `Constructor` objects to resolve machine code to semantic operations. The `Constructor` class in [`Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/Constructor.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/Constructor.java) encapsulates each instruction pattern and its associated p-code templates.

Pattern matching logic resides in the `pattern` subpackage, with [`Pattern.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Pattern.java) ([`Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/pattern/Pattern.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/pattern/Pattern.java)) defining the base matching infrastructure. During disassembly, Ghidra traverses the decision tree (`DecisionNode`) using `ParserWalker` to identify the first matching constructor, then emits the corresponding p-code operations (`OpTpl` objects) for emulation and decompilation.

## Integrating with Ghidra's Language Service

`SleighLanguage` implements the `Language` interface, allowing seamless integration with Ghidra's analysis framework. The class provides:

- **Register enumeration** via `getRegisters()`
- **Address space factory** via `getAddressFactory()`
- **Instruction prototypes** via `getPrototype()`, which wraps constructors for specific byte sequences

Discovery and instantiation occur through `SleighLanguageProvider` ([`Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguageProvider.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguageProvider.java)). This provider scans the classpath for `.slaspec` files and creates `SleighLanguage` instances on demand.

To load a language programmatically:

```java
LanguageService svc = DefaultLanguageService.getLanguageService();
Language lang = svc.getLanguage(new LanguageID("SLEIGH::Skeleton:LE:64:default"));

```

## Extending Ghidra: Adding a Custom Processor

To implement a new processor architecture using Ghidra SLEIGH language definitions:

1. **Create the directory structure** under `Ghidra/Processors/<MyCPU>/data/languages`.
2. **Write the specification** starting from `skel.slaspec`, defining endianness, spaces, registers, and instruction patterns.
3. **Add include files** (`.sinc`) for reusable macros and common instruction formats.
4. **Declare the processor** in [`ProcessorInfo.xml`](https://github.com/NationalSecurityAgency/ghidra/blob/main/ProcessorInfo.xml) within the processor directory.
5. **Build the project** using the `BuildSleigh` Ant target or allow Ghidra to compile on first load.

When Ghidra loads the new language, it executes the same pipeline: preprocessing, native compilation, binary decoding, and constructor tree generation.

## Summary

- **SLEIGH specifications** use `.slaspec` files to declaratively define processor endianness, memory spaces, registers, and instruction semantics.
- **The build pipeline** involves `SleighPreprocessor` for text expansion and `SleighCompileLauncher` to invoke the native `slgh` compiler, producing `.sla` binaries.
- **Runtime loading** occurs through `SleighLanguage`, which uses `SlaFormat.buildDecoder` to deserialize the binary format into Java objects.
- **Instruction decoding** relies on `Constructor` objects organized into decision trees that map bit patterns to p-code operations.
- **Extension requires** only text file creation and XML registration, enabling new architectures without Java development.

## Frequently Asked Questions

### What is the difference between a .slaspec and a .sla file in Ghidra?

A `.slaspec` file is the human-readable source code written in the SLEIGH language that defines a processor's instruction set and architecture. A `.sla` file is the compiled binary output generated by the `slgh` compiler, which `SleighLanguage` loads at runtime for efficient disassembly and emulation. The `.sla` format is optimized for machine parsing, while the `.slaspec` format prioritizes human maintainability.

### How does Ghidra handle changes to SLEIGH specification files?

Ghidra detects stale specifications through `SleighLanguage.isSLAStale`, which compares timestamps between the `.slaspec` source and the compiled `.sla` binary. When the source is newer, the `SleighLanguage` constructor automatically invokes `reloadLanguage`, triggering `SleighCompileLauncher` to rerun the preprocessor and native compiler before loading the updated binary.

### Can I debug SLEIGH constructor matching during disassembly?

Yes, you can inspect the constructor decision tree programmatically by casting the `Language` object to `SleighLanguage` and iterating over the constructors. Each `Constructor` object (defined in [`Constructor.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Constructor.java)) exposes its mnemonic, bit pattern, and p-code template through methods like `getMnemonic()`, `getPattern()`, and `getPcode()`, allowing verification of how specific byte sequences map to semantic operations.

### What are context variables in SLEIGH and why are they important?

Context variables are special registers defined with the `contextreg` type that store processor state bits affecting instruction decoding, such as current execution mode or privilege level. These variables enable a single specification to handle architecture variations (like ARM/Thumb mode switching) by allowing constructors to match different patterns based on runtime context state, which is essential for accurate disassembly of variable-length instruction sets.