Tag · Linkers
33 articles to explore.
[The World of Linkers—Lab 15] Let Counterexamples Set the Quality Bar
2026-10-06
Build replayable mutation and panic-survey tools, then test earlier backends through native execution, determinism checks, and behavioral comparison with GNU ld.
Read article
[The World of Linkers—Lab 14] Take the Linker Call from rustc
2026-10-06
Add a command-line driver to the cumulative class13 static-PIE backend and let rustc use it to link a no_std program that exercises core::fmt.
Read article
[The World of Linkers—Lab 13] Addresses Have Semantics: Safe ICF and Code Order
2026-10-06
Add conservative ICF and text ordering to class12's ET_EXEC and static-PIE backends, redirect references, and adjust debug information for folded copies.
Read article
[The World of Linkers—Lab 12] Make Debug Information Follow Addresses
2026-10-06
Add debug sections, symbols, and section headers to ET_EXEC and static PIE, keeping image, debug-section, and TLS coordinates distinct.
Read article
[The World of Linkers—Lab 11] Seeing Through Indirection: GOT, Relaxation, and Static TLS
2026-10-06
Extend class9's static PIE with GOT slots, the supported mov relaxation, a TLS template, and supplied startup code that installs main-thread TLS.
Read article
[The World of Linkers—Lab 10] Rewrite Instead of Copy: Constants and Unwind Tables
2026-10-06
Extend class8's ET_EXEC backend with merged constants, input-offset mappings, and rebuilt eh_frame records and search indexes for live code.
Read article
[The World of Linkers—Lab 09] Link Before the Load Address Is Known
2026-10-06
Build a static PIE from class8's frontend and class6's layout, separating static fixups from load-time pointers repaired by supplied startup code.
Read article
[The World of Linkers—Lab 08] Keep What Is Reachable: GC and Link Maps
2026-10-06
Trace live sections from the entry and explicit roots, build an address-independent link plan, and emit deterministic byte-safe maps.
Read article
[The World of Linkers—Lab 07] Archives on Demand: A Fixed Point of Member Extraction
2026-10-06
A static library is a container of object files, not one larger object. This lab parses the ar format, extracts members one at a time for unresolved global names, and rescans each archive until no further member is selected.
Read article
[The World of Linkers—Theory 16] From a Working Linker to One You Can Trust
2026-10-04
A linker must do more than produce a runnable file. Follow the engineering behind parallel passes, deterministic output, useful diagnostics, layered tests, and incremental linking—and see how each optimization changes what must be proved.
Read article
[The World of Linkers—Theory 15] Beyond ELF: The Rules Change with the File Format
2026-10-04
Compare Mach-O and PE/COFF through their headers, directory records and contents. Byte layouts and coordinate conversions explain imports, pointer chains, unwind metadata, duplicate selection and TLS, while separating file structure, link-time interfaces and runtime contracts.
Read article
[The World of Linkers—Theory 14] What C++ and Rust Ask of a Linker
2026-10-04
Decode compiler-generated names, separate weak binding from COMDAT selection, diagnose missing vtables and initialization order, then follow Rust metadata, runtime libraries, panic strategies, and a minimal no_std program into the final link.
Read article
[The World of Linkers—Theory 13] The Library Changed. What Happens to the Old Program?
2026-10-04
Break a library without changing its function names, then examine SONAMEs, symbol versions, old glibc baselines, and ABI analysis tools—including the compatibility failures those tools cannot decide for you.
Read article
[The World of Linkers—Theory 12] What Changes When the Optimizer Can See Across Files?
2026-10-04
Watch a cross-file call disappear, inspect the contract between symbol resolution and LTO, measure ThinLTO caching, then explore identical code folding and function layout without confusing smaller output with correct or faster output.
Read article
[The World of Linkers—Theory 11] Teaching Machine Code to Remember Its Source
2026-10-04
Follow a deleted function through DWARF tombstones, debug relocations, string merging, compression, separate debug files, build IDs, and split DWARF—and test whether the debugger still tells the truth.
Read article
[The World of Linkers—Theory 10] When a Program Must Arrange Its Own Memory
2026-10-04
Linker scripts organize input sections and define the address contract for an image. Distinguish file offsets, VMA, and LMA; explain startup mappings, data copying, and BSS clearing; then examine kernel layouts, embedded data, section retention, alignment, and script assertions.
Read article
[The World of Linkers—Theory 09] One Variable, a Different Address in Every Thread
2026-10-04
Follow a thread-local variable from its ELF initialization template to the current thread's memory. Decode four access models, watch the linker replace general code with fixed offsets, and reproduce the static TLS limit encountered by dynamically loaded libraries.
Read article
[The World of Linkers—Theory 08] Finding the Way Back Up the Stack
2026-10-04
A return address is only the beginning. Decode real CIEs and FDEs, follow a C++ exception through its two phases, and see how the linker makes unwind information survive garbage collection and become searchable at runtime.
Read article
[The World of Linkers—Theory 07] Leave the Last Address to Runtime
2026-10-04
Discover the runtime contract behind shared libraries: PIC, GOT and PLT entries, relocation classes, lazy binding, RELRO, interposition, symbol versions, and loader search paths. Native experiments show which decisions survive until a program actually starts.
Read article
[The World of Linkers—Lab 06] File Bytes, Memory Bytes, and Segment Permissions
2026-10-04
A code-only program is of little use. This lab adds read-only constants, initialized globals, BSS, and COMMON storage, describes them with three load segments of different permissions, and lets the kernel check the result: writing constants or executing data must end in SIGSEGV.
Read article
[The World of Linkers—Theory 06] Before main Gets a Turn
2026-10-04
Follow an ELF file through kernel mappings, zero-filled memory, demand paging, the initial stack, and C runtime startup. Then watch static PIE relocate itself and malformed images reveal the loader's validation boundaries.
Read article
[The World of Linkers—Lab 05] Calls Across Files: Merge the Code, Then Fill In the Displacements
2026-10-04
The previous executable could come only from one object with no relocations. This lab lets an assembly entry point call a C function compiled in another file: merge code sections, compute S+A-P for every field, and never leave a half-written field behind on failure.
Read article
[The World of Linkers—Theory 05] A Place for Every Section—and an Exit for Dead Code
2026-10-04
Build the bridge from input sections to loadable segments. Compare GNU ld and LLD layouts, calculate file offsets and virtual addresses, trace section garbage collection, and test what happens when a linker script gets page permissions wrong.
Read article
[The World of Linkers—Lab 04] The First Executable: Two Program Headers and an Entry Point
2026-10-04
Four stages have only read input. This lab writes output for the first time: plan a minimal executable image, serialize the ELF header and two program headers by hand, and let the Linux kernel run it and return 42.
Read article
[The World of Linkers—Theory 04] Relocation: Four Bytes Between Caller and Callee
2026-10-04
Follow a runnable Linux program from an unresolved call to four final instruction bytes. Distinguish section offsets, file offsets, P, and next RIP before deriving S+A-P; then explore negative displacements, absolute pointers, addends, overflow, and instruction relaxation.
Read article
[The World of Linkers—Lab 03] Who Owns the Name? Global Symbol Resolution
2026-10-04
Select global definitions before binding used references, preserving local identity, weak tie order, and COMMON requirements without assigning addresses.
Read article
[The World of Linkers—Theory 03] One Name, Several Definitions: Who Wins?
2026-10-04
Start with a runnable two-file program, then change only the link inputs to expose missing definitions, duplicate definitions, weak symbols, common storage, archive extraction, and the limits of ordinary type checking.
Read article
[The World of Linkers—Lab 02] Symbols and Relocations: An Object File's Unfinished Business
2026-10-04
Decode symbols and explicit-addend relocations, establish table ownership, and preserve information for definition selection and layout.
Read article
[The World of Linkers—Theory 02] An Object File Is a Program with Unfinished Business
2026-10-04
Follow C through assembly into ELF, decode the actual bytes of sections and symbols, and identify the promises a relocation record leaves for the linker. All examples use a native x86-64 Linux toolchain.
Read article
[The World of Linkers—Lab 01] Sections and Names: Carving Bytes into Regions
2026-10-04
Decode section descriptors, borrow payload bytes, and resolve names so later stages consume named Sections instead of rereading raw fields.
Read article
[The World of Linkers—Theory 01] The Long Road from Names to Addresses
2026-10-04
A linker began as a way to move reusable code. Follow the problems that led to object files, shared libraries, unwind tables, security metadata, and modern parallel linkers—then link a small program by hand.
Read article
[The World of Linkers—Lab 00] Distrust the Input: The ELF Boundary
2026-10-04
Check byte ranges, the supported ELF64 header, and section-header indexes to establish an input boundary without arithmetic wraparound or out-of-bounds reads.
Read article
[The World of Linkers—Theory 00] From a Function Call to a Running Program
2026-10-04
Follow a call across two source files to discover what the compiler, linker, and loader each know. Inspect a real Linux executable, diagnose failures at four stages, and establish the native environment used throughout the series.
Read article