2026-09-20

Weekly open source: qld, a parallel linker in pure Rust

The new project this week is qld, a linker, which landed about 550 commits in seven days. Last Sunday's two newcomers kept going: kintane went from a kernel that boots to one that runs Linux programs over TCP, and rsasm picked up more targets and object formats. CatCard turned from hardware bring-up into an actual wallet. rsemu filled in the Amiga line, and purecrypto crossed into v0.9. A Go-to-Rust compiler, rustygo, also started.

qld: a linker that speaks every linker's argv

qld is "a fast, parallel linker (link editor) written in pure Rust", designed as a drop-in replacement for GNU ld, gold, lld and mold. It accepts their command lines, so gcc, clang and rustc can use it unchanged. It is also a library, so tools can link in process. Building it needs no C toolchain. The only foreign code is a compiler's LTO plugin, loaded at run time when asked for. Output is meant to be byte-identical whatever the thread count.

The work was split into numbered workstreams and milestones. Here is what the week's merges recorded:

  • ELF across architectures. Static x86-64 first, then shared objects, PIE and static PIE, then a link pipeline generic over ELF class and byte order. On top of that came AArch64 (with range-extension thunks), RISC-V 64 and 32, LoongArch64, PowerPC64 LE (ELFv2), i386, x32, 32-bit Arm, and s390x, "the first big-endian target".
  • Real programs as the exit criteria. The M2 merge records coreutils, curl, OpenSSL, Python, LLVM, rustc and musl built with qld as the linker. M3 adds a Linux kernel that boots, and byte-identical raw outputs. Kernel modules and vmlinux "link like GNU ld".
  • The other formats. PE/COFF in the MinGW flavour, with auto-import, runtime pseudo-relocations and short import libraries. Mach-O readers, then dylibs, TLS, __unwind_info and C++ exceptions, arm64e pointer authentication, and LTO through libLTO. A macOS CI job builds zlib, Lua, SQLite and {fmt}.
  • Linker features. GNU linker scripts, --gc-sections, ICF, --gdb-index and --debug-names, --separate-debug-file, the GCC/LLVM LTO plugin interface (milestone M6). Undefined-symbol hints point to the library that defines the symbol.
  • Speed, measured. A benchmark suite that captures real links and replays them under GNU ld, lld, mold, wild and qld. It records the speedups that helped and the attempts that didn't ("a dedicated writer thread, tried again, does not help").

kintane: from booting to Linux programs

kintane, the Rust kernel that started last Sunday, landed nearly 390 commits, recorded round by round in its roadmap (twenty-one rounds by the end of the week). Some of what landed:

  • Storage. A block layer and virtio-blk (its first DMA driver), then a VFS and block cache, FAT16 read and then write through an ordered write-back cache, FAT32 with long names, crash tests, and a standing file server any process can connect to.
  • Isolation. An Intel VT-d IOMMU driver confining the disk's DMA, interrupt remapping, MSI-X, and virtio-blk-core running in a ring-3 driver domain on x86-64 ("Phase 5 exit"). On aarch64 it now finds the SMMUv3 and PCIe host bridge from the device tree.
  • Networking. virtio-net, an IPv4 stack, TCP with congestion control, SACK, fast retransmit and IPv4 reassembly, datagram sockets, and poll / select / epoll. To test the network, kbuild itself plays the peer on the other end of the wire.
  • The Linux personality. It started with a static program run unmodified from disk. By the end of the week it had threads, pipes, fork, execve and wait4 on x86-64 and aarch64, signals (including real-time signals, SIGCHLD, stop and continue), socket calls, getdents64 and statfs.
  • Running long. Stress and soak modes, randomised configurations, and an AML interpreter (fuzzed against QEMU's DSDTs) for PCI interrupt routing. "The 24-hour soak ran, and it found something".

CatCard: from bring-up to a wallet

CatCard, the clean-room Rust firmware for Coldcard hardware, went from USB and SD bring-up to wallet features in about 345 commits. It creates a wallet from the device's own entropy, with every source mixed and "credit only the ones that can be trusted", including SE1's TRNG on the mk3. An Address Explorer browses four address types. Signing covers legacy, nested and taproot PSBT inputs, through a strict, allocation-free PSBT v0 reader. There are registered multisig wallets, RAM-only passphrase wallets, and message signing. Private key work runs with interrupts masked, enforced by type.

On the Q1, the menu became a grid of icons, the QR scanner reads BBQr and BC-UR, and exports go to SD, BBQr or BC-UR. It can read the settings store and Secure Notes that stock firmware wrote, and expose the SD card as a USB drive. It also has two games, Flappy Cat and Block Cutter. The building blocks are shared crates. outscript-rs went no_std and no-alloc, with PSBT, taproot script paths and BBQr / BC-UR transports (v0.1.3 to v0.2.5), and CatCard now uses its codecs instead of its own. The settings JSON is read with emjson, a new streaming JSON parser, writer and in-place editor that runs in a few hundred bytes of RAM.

purecrypto: v0.9

purecrypto went from v0.8.7 to v0.9.1. On the protocol side: every nameConstraints form is enforced, RSA-PSS is honoured in X.509 and TLS, RFC 7250 raw public keys work on TLS 1.2, QUIC offers X25519MLKEM768, and DTLS negotiates ALPN. LMS gained HSS with per-level state and a cached Merkle tree, so signing is O(h). New algorithms in v0.9.1: JOSE (JWK, JWS, JWE), BLS12-381 with RFC 9380 hash-to-curve, FIPS 186-4 DSA, NIST FF1 format-preserving encryption, C2SP chunked encryption, SipHash and VMAC, and a batch of ciphers (AES-EAX, SEED, MORUS, AEGIS-128, Ascon v1.2). Downstream, tsslib-rs moved to purecrypto 0.9 and fixed resharing hangs and a threshold ML-DSA rogue-key attack.

rsemu: the rest of the Amigas

rsemu added the 68010, 68020 and 68030 (with its MMU) and the 68881/68882 FPU, and with them most of the Amiga line: the A500+ and A600 on the Enhanced Chip Set (the A600 with Gayle's IDE port), the A1200 on AGA, with "Kickstart 3.1 booting Workbench 3.1", and a CD32 "that boots to its animated screen", including Akiko and a CD-ROM drive. Paula's audio can be recorded or played in a browser tab. On the PC side came VGA and VBE 2.0, an ATAPI CD-ROM with El Torito boot, and hot-swappable diskettes. There is also a WebAssembly JIT backend, selected with engine = "jit-wasm".

rsasm: more targets, more object formats

rsasm added AVR (checked "form by form" against avr-elf-as), MSP430/MSP430X, the Intel 8051, and the rest of the 680x0 family with its FPU and MMU. Beyond ELF it now writes PE/COFF for x86-64, i386 and ARM64, NASM-style win32 and win64 objects, Mach-O for x86-64 and arm64, and Intel HEX. It also emits .debug_line and .eh_frame from .loc and .cfi_*, and reads conventional 6502, Z80 and 8080 source, checked against ca65 and vasm.

Also this week

  • rustygo, new: a Go to Rust compiler. It compiles Go packages into Rust source with a Rust runtime, so Go and Rust share one binary without cgo or FFI. Within the week it reached M0 (single-goroutine Go checked against gc) and much of M1: slices, maps, closures, interfaces, defer/panic/recover, a precise mark-sweep collector, and strings, strconv, sort and errors compiled from the real standard library. Go's own test/ directory is the measure: 34 of 141 at that point.
  • anydcode, the 1D/2D barcode library, released v0.2.0 after a round of conformance fixes (Aztec, DataBar, DotCode, Code 16K, PDF417) and work on the live-camera detector.
  • oxideav-heif, new: a HEIF / HEIC / MIAF container for oxideav. Its first commits cover the box reader, grid/overlay/identity derivations, HEVC and AV1 items decoded through the registry, sequences, and a writer.
  • minizlib, new: a no_std, no-alloc gzip/zlib/deflate decompressor and a small compressor, built to be as little code as possible (v0.1.0 and v0.1.1).

Next week

qld heads toward a first release. kintane keeps going round by round. rustygo moves on to goroutines and more of the standard library. CatCard has the parity list against stock firmware to work down, and oxideav-heif has a decoder and encoder to finish.