Linking & trust

Bootstrapping & Toolchain Trust

Where the first compiler came from, how a compiler comes to compile itself, and why source code alone does not capture every trust assumption in a toolchain.

Bootstrapping a Compiler

If the compiler for X is written in X, what compiled the first one? Write a minimal version in another language, use it to compile the real one, then use the result to compile itself — and throw the first one away.

Q · If the Rust compiler is written in Rust, what compiled the first Rust compiler?
Self-Hosting and the Three-Stage Build

A self-hosted compiler compiles itself, and that gives you a genuine test for free: stage 2 and stage 3 are built from identical source by compilers that should behave identically, so their binaries must be byte-identical. When they are not, the compiler miscompiled itself.

Q · What does a three-stage build actually prove, and why must stage 2 and stage 3 be identical?
Reflections on Trusting Trust

Ken Thompson's 1984 Turing Award lecture: source code alone does not capture every trust assumption in a toolchain, because the compiler that builds the compiler can carry behavior that appears in no source anywhere. Diverse double-compiling is the known countermeasure.

Q · If I read all the source, do I know what the binary does?
The Toolchain Is Your Trusted Computing Base

Not just the compiler. The preprocessor, assembler, linker, libc, startup objects, build system, every plugin and every downloaded dependency all execute during or inside your build, and a compromise in any of them is a compromise of the output.

Q · What am I actually trusting when I run a build?
Reproducible Compilation

Identical inputs, byte-identical output. What breaks it is mundane — timestamps, absolute paths, hash-map iteration order inside the compiler, parallelism-dependent naming, embedded build IDs — and fixing it is what makes independent verification possible at all.

Q · Why do two builds of the same source produce different binaries, and does it matter?