4.8 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Remill is a static binary translator library that converts machine code instructions into LLVM bitcode. It lifts low-level machine instructions to architecture-neutral LLVM IR for analysis, transformation, and execution.
Supported Architectures: x86/x86-64 (with AVX/AVX512), AArch64, AArch32 (in progress), SPARC32/64, PowerPC
Build Commands
# Build dependencies (LLVM, XED, gflags, glog, googletest)
cmake -G Ninja -S dependencies -B dependencies/build
cmake --build dependencies/build
# Build remill
cmake -G Ninja -B build -DCMAKE_PREFIX_PATH=$(pwd)/dependencies/install
cmake --build build
# Run tests
cmake --build build --target test_dependencies
CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test
# Run specific test category (e.g., X86 MOV instructions)
./build/tests/X86/Run --gtest_filter="*MOV*"
# Build and run remill-lift tool
./build/bin/remill-lift --arch x86_64 --os linux --bytes "90 c3" --address 0x1000
Architecture & Key Components
Core Library Structure
Instruction Lifting Pipeline:
- Decode (
lib/Arch/*/Decode.cpp): Machine bytes → Instruction data structure - Lift (
lib/BC/InstructionLifter.cpp): Instruction → LLVM function using semantic functions - Optimize (
lib/BC/Optimizer.cpp): Apply LLVM optimizations - Output: LLVM IR/bitcode
Key Classes:
TraceLifter(lib/BC/TraceLifter.cpp): Recursively decodes and lifts instruction tracesSleighLifter(lib/BC/SleighLifter.cpp): Ghidra Sleigh-based lifting for newer architecturesInstructionLifter(lib/BC/InstructionLifter.cpp): Base class for lifting individual instructionsInstruction(include/remill/Arch/Instruction.h): Decoded instruction representation
Semantics Implementation
Location: lib/Arch/{ARCH}/Semantics/
- X86 has 33 semantic files (MOV, BINARY, LOGICAL, SSE, AVX, X87, etc.)
- Each file contains C++ template functions implementing instruction behavior
- Templates instantiated via ISEL (instruction selection) mechanism
State Structure: include/remill/Arch/{ARCH}/Runtime/State.h
- Represents complete machine state (all registers)
- Passed between lifted basic blocks
- Carefully designed to prevent unwanted compiler optimizations
Intrinsics: include/remill/Arch/Runtime/Intrinsics.h
- Memory operations:
__remill_read_memory_*,__remill_write_memory_* - Control flow:
__remill_function_call,__remill_function_return - Deferred operations for downstream tools to handle
Development Workflow
Adding New Instructions
- Identify instruction category and semantic file location
- Add semantic function template in appropriate file (e.g.,
lib/Arch/X86/Semantics/MOV.cpp) - Register ISEL entries mapping opcodes to semantic functions
- Add test cases in
tests/{ARCH}/following existing patterns - See
docs/ADD_AN_INSTRUCTION.mdfor detailed walkthrough
Testing Changes
# Build test dependencies first
cmake --build build --target test_dependencies
# Run all tests
CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test
# Run specific architecture tests
ctest --test-dir build -R "X86|AArch64|SPARC"
# Run differential tester for X86
./build/bin/differential_tester_x86
Code Formatting
# Format C++ files
./scripts/format-files
Important Files & Locations
- Semantics:
lib/Arch/{ARCH}/Semantics/- Instruction implementations - Tests:
tests/{ARCH}/- Architecture-specific test suites - Lifting Logic:
lib/BC/- Core lifting infrastructure - Public API:
include/remill/- Headers for library users - Documentation:
docs/- Design docs and guides
LLVM Versions
Supported: LLVM 15, 16, 17, 18, 19, 20, 21 CI tests all versions on Ubuntu 22.04 and macOS.
Common Development Tasks
# Debug lifting issues
./build/bin/remill-lift --arch x86_64 --os linux --bytes "48 89 e5" --address 0x1000 --bc_out /tmp/out.bc
# Inspect lifted bitcode
llvm-dis-15 /tmp/out.bc -o -
# Run specific test with verbose output
./build/tests/X86/Run --gtest_filter="*MOVAPD*" --v=1
# Check for memory leaks (Linux)
valgrind --leak-check=full ./build/tests/X86/Run --gtest_filter="*specific_test*"
Architecture-Specific Notes
X86: Most mature implementation with comprehensive AVX/AVX512 support AArch64: Full 64-bit ARMv8 support SPARC: Both 32-bit and 64-bit versions supported PowerPC: Uses Sleigh-based lifting, still in development AArch32/Thumb: Work in progress
Contribution Guidelines
- Create GitHub issue describing your contribution
- Create feature branch:
issue_N_feature_description - Make incremental PRs when milestones complete
- Ensure all tests pass before submitting PR
- Follow existing code patterns in semantic files