lib/tldr/src/root.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 //! The package is an experimental linker: it takes compiled object files and
2 //! static archives, resolves each reference to a symbol against the object that
3 //! defines it, applies the relocations each target architecture defines, and
4 //! writes one executable. On an x86-64 host it can also link objects straight
5 //! into the calling process's memory and return the entry point as a function
6 //! to call, and it inspects object files. Linux x86-64 ELF is the default
7 //! target, and COFF and Mach-O each have their own link path.
8 //!
9 //! Linking should keep pace with editing: a link after a small edit should cost
10 //! little more than the edit. A link's output bytes should depend on its inputs
11 //! and options alone, so a test can pin a whole executable by its hash. On
12 //! request, the output should keep one copy of machine code that two or more
13 //! functions share byte for byte, so the executable is smaller.
14 //!
15 //! The design follows a few constraints from existing linkers: full links still
16 //! need to be fast because symbol resolution can have global effects,
17 //! incremental linking needs an explicit database of input hashes and
18 //! output-section layout, and determinism is a correctness property where
19 //! inputs are processed in command-line order and output sections have stable
20 //! ordering. Patching an edited section in place needs room after it, since a
21 //! section that grows past its space would move everything that follows. Two
22 //! functions that share one copy of code share one address, so distinct
23 //! functions can have equal pointer values and a program that compares function
24 //! pointers can see the merge.
25 //!
26 //! The package names the modern linkers [mold](https://github.com/rui314/mold)
27 //! and [LLD](https://lld.llvm.org/) as its predecessors, and from them it takes
28 //! parallel linking: once a link holds 50,000 or more relocations, it checks
29 //! them across worker threads. From them it also takes the merging of read-only
30 //! executable sections whose bytes and relocations match, which both offer
31 //! under the flag `--icf=all`. Its external benchmark links the same workloads
32 //! through a ReleaseFast `tldr-link` and through each of wild, mold, lld, gold
33 //! and GNU ld found on `PATH`.
34 //!
35 //! A link in prepare mode writes a record beside its output (an *incremental
36 //! manifest*), with each input's name, size, content hash and file identity,
37 //! the output section layout, and where each input section landed. Prepare mode
38 //! is the default of `LinkOptions`, and `tldr-link` prepares only when given
39 //! `--incremental=prepare`. A prepared link also leaves slack after each output
40 //! section (a *reserve*), the larger of the section's alignment and 24 percent
41 //! of its size by default, so an edited section can grow in place. A later link
42 //! in relink mode (a *relink*) compares its inputs with that record, then
43 //! reuses the output, patches the changed sections in place, or falls back to a
44 //! full link and names the reason, such as an input added, removed or
45 //! reordered, or a section grown past its slack. Folding identical code
46 //! (*identical code folding*, or ICF for short, the name LLD and mold use) runs
47 //! only on request, with `--icf=all`, because of that shared address. Patching
48 //! the incremental metadata inside an output exists for ELF, and COFF and
49 //! Mach-O links skip that step.
50 //!
51 //! - *contribution*: one input section or common symbol placed in the output,
52 //! with its address, file offset, size and reserved size.
53
54 pub const model = @import("model.zig");
55 pub const object = @import("object.zig");
56 pub const archive = @import("archive.zig");
57 pub const library = @import("library.zig");
58 pub const incremental = @import("incremental/root.zig");
59 pub const trace = @import("trace.zig");
60 pub const parallel = @import("parallel.zig");
61 pub const formats = @import("formats/root.zig");
62 const linker = @import("link.zig");
63 const loader = @import("load.zig");
64
65 pub const Input = model.Input;
66 pub const InputIdentity = model.InputIdentity;
67 pub const LinkCommitObserver = model.LinkCommitObserver;
68 pub const LinkOptions = model.LinkOptions;
69 pub const Target = model.Target;
70 pub const Diagnostics = model.Diagnostics;
71 pub const Error = model.Error;
72 pub const LinkedImage = object.LinkedImage;
73 pub const LoadError = loader.LoadError;
74 pub const LoadedImage = loader.LoadedImage;
75 pub const Object = object.Object;
76 pub const ObjectSection = object.ObjectSection;
77 pub const ObjectSymbol = object.ObjectSymbol;
78 pub const parseObject = formats.parseObject;
79 pub const detectObjectFormat = formats.detectObjectFormat;
80 pub const link = linker.link;
81 pub const loadExecutable = loader.loadExecutable;
82 pub const applyIncrementalMetadataPatch = linker.applyIncrementalMetadataPatch;
83 pub const finishDirectIncrementalMetadataPatch = linker.finishDirectIncrementalMetadataPatch;
84 pub const directIncrementalEvidenceAlloc = linker.directIncrementalEvidenceAlloc;
85 pub const incrementalBuildIdNoteRange = linker.incrementalBuildIdNoteRange;
86 pub const incrementalMetadataPatchRange = linker.incrementalMetadataPatchRange;
87 pub const MetadataPatchRange = linker.MetadataPatchRange;