diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000000..41edef2cfd --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,147 @@ +# CLAUDE.md + +Code in this repository follows strict conventions. Read +`docs/coding-guidelines.md` if unfamiliar with any rule below. + +## What is mold + +mold is a fast drop-in replacement for GNU ld. It links ELF object files +into executables and shared libraries. It is a cross-linker — it can +target any architecture from any host. The man page source is +`docs/mold.md`; do not edit `docs/mold.1` (auto-generated). + +## Build and Test + +```bash +cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=clang++ -B build +cmake --build build -j$(nproc) +cd build && ctest --output-on-failure -j$(nproc) +``` + +Quick smoke test — verify mold can link a trivial program: +```bash +echo 'int main() {}' | cc -B. -o /dev/null -xc - +``` + +## Code Style + +- **Integers**: Use `i64` for everything. Use `i32` only when allocating + millions of the same object. Use `ub32`/`ul32`/`il32` from + `lib/integers.h` for file I/O fields (endian-safe, alignment-safe). +- **`auto`**: Use only for: + - Lambdas: `auto fn = [&](i64 val) { ... };` + - Structured bindings: `auto [it, inserted] = map.insert({key, val});` + - Verbose types: `auto flags = std::regex_constants::optimize | ...;` + Never for simple variable declarations — always write the explicit type. +- **`std::tie` vs `auto [x, y]`**: Use `std::tie` when the variables are + already declared. Use `auto [x, y]` for new declarations. +- **`constexpr`**: Use `if constexpr` for template metaprogramming (target + selection, arch-specific code paths). Don't add `constexpr` to functions + unless required. +- **No exceptions**: The build uses `-fno-exceptions`. Use + `Fatal(ctx)` / `Error(ctx)` / `Warn(ctx)` — RAII classes that print + and exit in the destructor. Fatal calls `_exit(1)`. +- **No deep inheritance**: Class hierarchies are at most 2 levels deep. + Prefer composition. +- **Variable names**: Short — `ctx` (Context), `mf` (MappedFile), + `sym` (Symbol), `esym` (ElfSym), `loc` (relocation target address). +- **Helper lambdas**: Define locally for repeated operations within a + function (e.g., `auto check = [&](i64 val, i64 lo, i64 hi) { ... };` + for relocation range checks). +- **`append()`**: Use `append(vec, x)` from `lib/lib.h` instead of + manual loops to append vectors. +- **Direct field access**: Prefer `isec.name` over `isec.name()` when + the field is directly accessible. Remove unnecessary local variables + that just alias a field. +- **Range-based for over index loop**: Prefer `for (Symbol *sym : vec)` + over `for (i64 i = 0; i < vec.size(); i++)` when the index isn't needed. +- **Semantic names over raw checks**: Prefer `ctx.gnu_debuglink` over + `!ctx.arg.separate_debug_file.empty()`. Use meaningful boolean fields + instead of checking argument emptiness. +- **Simplify**: The project values simplification — removing redundant + code, replacing index loops with range-for, extracting complex lambdas + into named functions, using semantic names. Simplification should be + a standalone commit, not mixed with feature work. + +## Architecture + +- **Explicit template instantiation**: Every `.cc` file ends with + `template class Foo;` for the target type `E = MOLD_TARGET`. + This keeps compile times fast. Don't use header-only templates. +- **`Context` is the god object**: Almost every function takes + `Context &ctx`. It owns all linker state. +- **`namespace mold`**: All code lives here. No nested namespaces. +- **Include `mold.h`**: Most `.cc` files include only `mold.h`. + Put `#include "mold.h"` first, then system headers. +- **ELF types**: Use types from `src/elf.h` (e.g. `Elf64_Sym`, + `Elf64_Rela`). The template alias `U32` selects endian-correct + 32-bit integers automatically. +- **Determinism**: mold's output must be bit-for-bit identical given the + same inputs. No host-specific defaults. No non-deterministic iteration + (hash tables, thread scheduling) in output-affecting code. +- **Linker scripts**: Intentionally minimal support — just enough to + read `/usr/lib/x86_64-linux-gnu/libc.so`. No plans to add more. +- **Parallelism**: Uses TBB (`tbb::parallel_for_each`, + `tbb::parallel_sort`). Use simple `for` loops when parallelism isn't + needed. Don't parallelize just because you can — measure first. + Avoid per-operation overhead (e.g., hash table insert per relocation). +- **Comments**: Explain WHY, not WHAT. Use full sentences. Detailed + comments for complex logic (e.g., symbol resolution, .eh_frame parsing). + No section separator lines (`// ====...`, `// ----...`). + +## Writing a Test + +Tests are shell scripts in `test/`. Every test sources `common.inc`: + +```bash +#!/bin/bash +. $(dirname $0)/common.inc + +cat <