# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## What is Remill? Remill is a static binary translator that lifts machine code instructions into LLVM bitcode. It supports x86/amd64 (including AVX/AVX512), AArch64, AArch32, SPARC32/64, and PPC architectures. Remill is designed as a library for binary analysis tools like McSema. ## Build Commands ### Build Dependencies (First Time) ```bash # Build dependencies including LLVM from source cmake -G Ninja -S dependencies -B dependencies/build cmake --build dependencies/build # Or with external LLVM (macOS with Homebrew) brew install llvm@17 cmake -G Ninja -S dependencies -B dependencies/build -DUSE_EXTERNAL_LLVM=ON \ "-DCMAKE_PREFIX_PATH:PATH=$(brew --prefix llvm@17)" cmake --build dependencies/build ``` ### Build Remill ```bash cmake -G Ninja -B build "-DCMAKE_PREFIX_PATH:PATH=$(pwd)/dependencies/install" \ -DCMAKE_BUILD_TYPE=Release cmake --build build ``` ### Run Tests ```bash # Build test dependencies cmake --build build --target test_dependencies # Run all tests cd build && ctest # Run architecture-specific tests ctest -R amd64 ctest -R aarch64 ``` ## Architecture ### Core Concepts **Intrinsics System**: Remill defers memory/control-flow semantics to downstream consumers via intrinsics (`__remill_read_memory_*`, `__remill_write_memory_*`, etc.). This allows tools to implement their own memory models. **SEM (Semantics)**: Generic C++ template functions implementing instruction behavior. Named after the instruction mnemonic (e.g., `AND`, `ADD`). **ISEL (Instruction Selection)**: Specific instantiations of semantics for particular encodings. Named with operand types (e.g., `AND_GPRv_MEMv_32`). **State Structure**: Per-architecture register/flag state (`State.h`). Uniform size across generations enables mixing translated bitcode. **Basic Block Lifting**: Core function `__remill_basic_block(State&, addr_t, Memory*)` - variables correspond to register names, decoder and lifter synchronize via this naming convention. ### Key Directories - `lib/Arch/X86/Semantics/` - x86/amd64 instruction semantics by category (BINARY.cpp, LOGICAL.cpp, AVX.cpp, SSE.cpp, etc.) - `lib/BC/InstructionLifter.cpp` - Converts decoded instructions to LLVM IR - `include/remill/Arch/Runtime/` - State structures, intrinsics, operators, types - `tests/X86/`, `tests/AArch64/` - Architecture-specific test suites ## Writing Instruction Semantics ### Semantic Function Pattern ```cpp template DEF_SEM(INSTR_NAME, D dst, S1 src1, S2 src2) { auto lhs = Read(src1); auto rhs = Read(src2); auto res = UAdd(lhs, rhs); // or UAnd, UMul, etc. WriteZExt(dst, res); // Update flags last return memory; } ``` ### Operator Naming Convention - **Signed**: `SAdd`, `SSub`, `SMul`, `SDiv` - **Unsigned**: `UAdd`, `USub`, `UMul`, `UDiv`, `UAnd`, `UOr`, `UXor` - **Floating-point**: `FAdd`, `FSub`, `FMul`, `FDiv` - **Vector ops**: `UAddV32`, `FMulV64`, `UReadV32`, `FWriteV64` ### ISEL Definition ```cpp // For SCALABLE instructions, suffix with operand size DEF_ISEL(AND_GPRv_MEMv_8) = AND; DEF_ISEL(AND_GPRv_MEMv_16) = AND; DEF_ISEL(AND_GPRv_MEMv_32) = AND; IF_64BIT(DEF_ISEL(AND_GPRv_MEMv_64) = AND;) // Or use shorthand macro DEF_ISEL_RnW_Rn_Mn(AND_GPRv_MEMv, AND); ``` ### Operand Types - `R8`, `R16`, `R32`, `R64` - Register reads - `R8W`, `R16W`, `R32W`, `R64W` - Register writes - `M8`, `M16`, `M32`, `M64` - Memory operands - `V128W` - SIMD destination (always 128-bit for writes) ### Order of Operations in Semantics 1. `Read()` all source operands first 2. Perform computations 3. `Write()`/`WriteZExt()` to destinations 4. Update suppressed operands (flags) last This ordering limits state mutations if memory access violations occur. ## Writing Tests Test files go in `tests/{ARCH}/{CATEGORY}/` and must be included in `Tests.S`. ```asm TEST_BEGIN(ANDr32r32, 2) TEST_IGNORE_FLAGS(AF) TEST_INPUTS( 0, 0, 1, 0, 0xFFFFFFFF, 1, 0x7FFFFFFF, 1) and ARG1_32, ARG2_32 TEST_END ``` - `TEST_BEGIN(name, num_args)` - Start test with N input arguments - `TEST_IGNORE_FLAGS(...)` - Flags left in undefined state - `TEST_INPUTS(...)` - Comma-separated input values (grouped by num_args) - `ARG1_32`, `ARG2_64`, etc. - Input argument registers by size ## Code Style - **Format**: Google style via `.clang-format` (80-char line limit, 2-space indent) - **Standard**: C++17 - Run `clang-format -i ` before committing ## XED Tables Reference For x86 instruction details, consult `docs/XED/xed.txt`. Key fields: - Instruction category (LOGICAL, BINARY, etc.) → determines which `.cpp` file - `SCALABLE` attribute → needs size-suffixed ISELs - `EXPLICIT`/`IMPLICIT`/`SUPPRESSED` → determines semantic function parameters - `R`/`W`/`RW` → operand mutability (RW generates two parameters: write first, read second)