Rui UeyamaandClaude Opus 5.5 1b9e6ecae9 Split create_output_sections into passes, as mold's driver runs them
mold has no one function that lays the output out: its driver bins the
input sections with create_output_sections, makes the linker's own
sections with create_synthetic_sections, and orders and sizes them with
sort_output_sections and compute_section_sizes, one pass at a time.
output_sections::create_output_sections ran all of that in one
function. It is split into those passes now, and the Mach-O-only steps
between them (sort_section_members, rename_synthetic_sections,
add_boundary_sections, create_segments, the order checks and so on)
into passes of their own, which the driver calls one by one in the
order they ran. The stubs, the GOT and the __LINKEDIT tables are added
by create_synthetic_sections, as mold adds its .got and .plt there and
sold its tables in create_synthetic_chunks. The driver finds the symbol
moves, which the input sections' assignment and the method lists'
layout both follow, and hands them to the two passes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 18:18:43 +09:00
2026-10-08 13:21:50 +09:00
2026-09-19 10:48:37 +09:00

mold-macho: mold for macOS

mold-macho is a Mach-O linker for macOS, written in Rust as a port of the mold linker to Apple platforms. It is a drop-in replacement for Apple's ld for common workloads: it accepts ld64's command line, and links working, correctly code-signed executables, dylibs and bundles for arm64 and x86-64 macOS.

C, C++, Objective-C, Swift and Rust programs link and run, including real-world projects (ripgrep builds and passes its full test suite; the C++ mold tree with vendored tbb/zstd/zlib builds at -O3; the linker links itself). Debugging works (stabs for lldb/dsymutil), and so do C++ exceptions, thread-locals, LTO, auto-linking, frameworks and Objective-C selector stubs.

Usage

Build with cargo build --release. The binary is target/release/mold; ./install.sh (PREFIX=/usr/local by default) installs it as mold with an ld64.mold symlink, the same arrangement as mold's ld.mold. Then point your compiler driver at the linker:

clang -o hello hello.c --ld-path=path/to/ld64.mold
swiftc -o hello hello.swift -use-ld=path/to/ld64.mold
RUSTFLAGS="-C link-arg=--ld-path=path/to/ld64.mold" cargo build

Feature highlights

  • Classic dyld info and chained fixups (the default for deployment targets of macOS 13+), ad-hoc code signing, export tries, and content-hash UUIDs
  • Subsections via symbols, -dead_strip, identical code folding (on by default, like ld64's deduplication), literal merging
  • __unwind_info synthesis from compact unwind, __eh_frame re-synthesis for DWARF-only unwind, range-extension thunks
  • Archives with mold's order-insensitive resolution model, .tbd stubs with umbrella reexports, frameworks, auto-linking (LC_LINKER_OPTION), LTO via libLTO
  • Parallel input parsing, output writing and code-signature hashing, following the design described in the mold paper

Architecture

The code mirrors mold's layout: macho/driver.rs runs the passes in order, macho/passes.rs implements them, macho/arch/ isolates the target-dependent relocation handling (arm64 and x86-64 are each instantiated in a crate under arch/ and dispatched by the executable in cli/), and macho/chunks/ builds every piece of the output file. Parsing is decoupled from resolution: all inputs, including every archive member, are parsed in parallel, and symbol resolution ranks competing definitions with a liveness walk deciding which archive members join the link.

The commit history doubles as a reference on the Mach-O file format and dyld: each commit's message explains the structures and loader behavior involved in that change.

Tests

Tests are shell scripts under tests/, one feature per script, driving the real toolchain through cc --ld-path=...; a harness runs each for macOS on arm64 and (under Rosetta) x86-64, and then for the arm64 iOS simulator if its runtime is installed, building the programs with the simulator's SDK and running them on a simulator device it boots. Logs and outputs go under target/<profile>/mold-test/out/test. --all adds the x86-64 iOS simulator (which only the iOS 17 runtime runs) and the tvOS and visionOS simulators; --host runs macOS's alone, and --triple (or TRIPLE) one simulator. The harness is the integration test of the cli crate; name that target to pass it options, which the unit tests would otherwise reject:

cargo test
cargo test --test integration -- dead-strip --native --timeout 120
cargo test --test integration -- --all
cargo test --test integration -- --triple arm64-apple-tvos-simulator
cargo test --test integration -- --list

License

MIT, like mold.

S
Description
mold 🦠: A Modern Linker in Rust 🦀
Readme MIT
43 MiB
0 Stars 1 Watchers 0 Forks
mold 3.0.0
Latest
2026-11-06 16:54:55 -10:00
Languages
Rust 67.4%
Shell 32.1%
C 0.3%
Python 0.2%