mold: A Massively Parallel Linker
Abstract: Linking is a critical step in the software build process that combines compiled object files into a single executable or shared library. Despite decades of engineering effort, link times remain a significant bottleneck in the edit-compile-debug cycle, particularly for large C++ programs. Existing linkers exploit limited parallelism, leaving most CPU cores idle during linking. We present mold, a Unix/Linux linker that applies data parallelism systematically across the entire linking pipeline. We first analyze the architectural constraints that prevent existing linkers from scaling, including entangled symbol resolution and archive processing, and then show how a clean-slate design that decouples them overcomes these limitations. On large real-world programs, mold links multi-gigabyte debug binaries in at most a few seconds, and often in under a second. It is 2.4-16.1x faster than the state-of-the-art lld linker, and up to 112x faster than the traditional GNU ld. An ablation study shows that no single optimization dominates; the speedup comes from the cumulative effect of parallelizing all passes.
Paper Prompts
Sign up for free to create and run prompts on this paper.
Top Community Prompts
Explain it Like I'm 14
1. What is the paper about?
This paper presents mold, a new program called a linker.
When programmers build a large program, the computer first compiles many source files into smaller files containing machine code. The linker then joins all these pieces into one finished program, such as an application or a shared library.
Linking can take a long time, especially for large C++ projects. The paper’s main goal is to show how mold uses many CPU cores at the same time to make linking much faster.
2. What questions does the research ask?
The researchers wanted to answer questions such as:
- Why do older linkers leave many CPU cores unused?
- Can almost every part of the linking process be run in parallel?
- How much faster is mold than existing linkers such as GNU
ld,gold, and LLVMlld? - Does mold remain correct and produce the same result every time?
- Which of mold’s design choices contribute most to its speed?
The central idea is simple: instead of having one worker process a long list of items, mold gives different parts of the list to many workers.
For example, if a linker must inspect 10 million pieces of information, one worker might take a very long time. Sixty-four workers can each inspect a portion of the information at the same time.
3. How was the research carried out?
Understanding the linking process
The paper first explains what a normal linker does:
- Reads input files containing compiled code and data.
- Matches symbols, such as the names of functions and variables, with the places where they are used.
- Removes unnecessary sections of code and data.
- Decides where everything will go in the final program.
- Writes the finished executable or library.
A useful analogy is building a large book from many chapters. The linker checks that chapter references point to the right pages, removes unused pages, decides the final page numbers, and produces the complete book.
Designing mold
Mold was designed from the beginning around data parallelism. This means performing the same operation on many similar items at once.
For example:
- Different input files can be read simultaneously.
- Different symbols can be resolved simultaneously.
- Different relocation records can be checked simultaneously.
- Different sections of the final file can be copied simultaneously.
A relocation is a note saying, “Put the correct address of this function or variable here.” It is similar to leaving blanks in a document and filling them in after the final page numbers are known.
Mold uses special tools for safe cooperation between threads. One example is an atomic operation called compare-and-swap. This allows several workers to try to update shared information without accidentally overwriting one another.
Testing performance
The researchers tested mold using:
- Nine large, real-world software projects.
- A computer with 64 processor cores.
- Different numbers of threads, from 1 to 64.
- Comparisons with GNU
ld,gold, and LLVMlld. - Additional tests that turned individual optimizations on and off.
This last type of test is called an ablation study. It is like removing one part from a racing bicycle to see how much that part contributed to the total speed.
The researchers also checked:
- Whether the linked programs worked correctly.
- Whether mold produced identical output every time.
- How well its speed improved as more CPU cores were used.
4. What were the main findings?
Mold was much faster
On large programs, mold could link multi-gigabyte debug binaries in a few seconds, and sometimes in less than one second.
Compared with other linkers, mold was reported to be:
- 2.4 to 16.1 times faster than LLVM
lld - Up to 112 times faster than GNU
ld
For example, linking a very large TensorFlow-related program with lld took about 52 seconds on a 64-core machine, while mold was designed to use those cores much more effectively.
Parallelizing every stage was important
The researchers found that no single trick explained all of mold’s speed.
Instead, the improvement came from parallelizing many stages:
- Reading files
- Resolving symbols
- Removing unused code
- Merging identical strings
- Finding identical pieces of code
- Calculating file positions
- Creating special jump helpers
- Copying data and applying relocations
- Creating the final build identifier
This is important because speeding up only one stage has limited value. If a journey has ten parts and only one part becomes faster, the total journey may still take almost as long. In the same way, a linker remains slow if most of its work is still done by one thread.
Mold solved a difficult design problem
Older linkers often process files from left to right. This order matters because a library may provide a function only when another file has requested it.
Mold changes this process. It first reads all the files and then separately decides which definitions should be used. This separation makes it easier to process many symbols in parallel.
However, this choice can produce slightly different results in unusual cases. When the researchers built more than 19,000 Gentoo software packages, only two packages failed because of differences in symbol-selection behavior.
Mold preserved reproducibility
Parallel programs can sometimes produce different results depending on which thread finishes first. Mold was designed to avoid this problem.
It guarantees that the same inputs, settings, and mold version produce a bit-for-bit identical output. This is important for software projects because developers need to know that a rebuild has not changed unexpectedly.
Hardware and operating-system improvements also helped
Mold included several additional optimizations:
- Huge pages, which let the computer handle large files in bigger chunks.
- File preallocation, which reserves disk space before many threads begin writing.
- A faster memory allocator, which manages memory efficiently when many threads are working.
- Reusing an existing output file when possible.
- A two-process design that hides some cleanup time from the user.
These improvements made linking even faster, but the study showed that mold’s biggest advantage came from its overall parallel design, not from one operating-system trick.
5. Why are these results important?
Large software projects may need to be rebuilt many times each day. Developers often follow an edit-compile-debug cycle:
- Change the code.
- Build the program.
- Test it.
- Find a problem.
- Repeat.
If linking takes tens of seconds each time, developers spend a lot of time waiting. A much faster linker can make this cycle feel more immediate.
Mold is especially useful for debug builds, which often contain large amounts of extra information that helps programmers find errors. These builds can be much larger than the final version of a program.
The paper also shows an important lesson about computer performance: sometimes it is easier to build a new system with a better design than to slowly modify an old system. Older linkers had years of assumptions based on sequential processing, so making every stage parallel would have required changing much of their internal structure.
6. Possible impact of the research
The research could have several effects:
- Shorter build times for large C and C++ projects.
- Less waiting for programmers, making software development more productive.
- Better use of modern computers, especially machines with many CPU cores.
- Encouragement for other compiler and build-system tools to use parallel processing more fully.
- Potential improvements in continuous integration systems, where software is built repeatedly on servers.
There are also limitations. Mold is mainly designed for Unix and Linux systems, and its different handling of some unusual linking situations may cause compatibility problems. Link-Time Optimization can also reduce its advantage because compiling the program’s intermediate code may take more time than linking itself.
Overall, the paper argues that linking does not have to be a slow, mostly single-threaded part of building software. By redesigning the linker so that nearly every stage can use many CPU cores, mold can make building very large programs dramatically faster.
Knowledge Gaps
The paper leaves the following knowledge gaps, limitations, and open questions unresolved:
- Incomplete evaluation evidence: The provided paper text ends during the experimental setup, so the reported end-to-end results, scalability measurements, ablation results, per-pass comparisons, and compatibility analysis are not fully presented or independently assessable.
- Limited hardware diversity: Most evaluation is performed on one 64-core AMD x86-64 system, with only a secondary Apple M1 Ultra system; behavior on other NUMA systems, multi-socket servers, lower-core-count machines, cloud instances, and non-NVMe storage remains unclear.
- Unclear scalability beyond 64 cores: The paper does not establish whether mold continues to scale on machines with more than 64 physical cores, nor whether synchronization, memory bandwidth, or allocator contention becomes a bottleneck at higher thread counts.
- Insufficient characterization of memory consumption: Although mold uses compact metadata and reports some allocator effects, the paper does not provide comprehensive peak-memory measurements or quantify memory overhead relative to lld, GNU ld, and gold across workloads.
- Unresolved behavior under memory pressure: It is not evaluated how mold performs when available RAM is insufficient to hold all eagerly parsed archive members and metadata, or whether it degrades gracefully through paging, throttling, or controlled resource usage.
- Eager archive parsing may waste substantial work: Parsing every member of every archive in parallel can process many files that are ultimately discarded; the paper does not quantify this overhead across archive-heavy workloads or identify when eager parsing becomes slower than demand-driven extraction.
- Compatibility is tested too narrowly: The Gentoo repository experiment reports only two failed packages, but the paper does not explain the failures in depth or evaluate compatibility across other ecosystems, build systems, distributions, proprietary codebases, or unusual linker scripts.
- Heuristic symbol-resolution semantics remain underspecified: The precedence rules are explicitly heuristic, and the paper does not provide a formal specification, exhaustive corner-case analysis, or a principled guarantee of equivalence with established linkers.
- Archive-order semantics are changed: Because mold's liveness walk makes
-start-groupand-end-groupineffective and is largely insensitive to-lordering, the consequences for builds that intentionally depend on traditional left-to-right archive semantics remain unexplored. - No systematic differential testing is reported: The paper does not describe large-scale automated comparison of mold's outputs and diagnostics against GNU ld, gold, and lld over generated ELF inputs and adversarial linking scenarios.
- Correctness of concurrent symbol resolution needs stronger validation: Atomic compare-and-swap establishes a parallel winner-selection mechanism, but the paper does not prove that it preserves all required ELF, ABI, visibility, versioning, weak-symbol, common-symbol, or interposition semantics.
- Dynamic linking semantics are insufficiently evaluated: The treatment of shared libraries, symbol versioning, copy relocations,
IFUNC, TLS relocations, symbol interposition, and dynamic loader interactions is not detailed enough to determine coverage and correctness. - Linker-script support is not discussed: The paper does not establish whether mold's parallel layout and order-independent resolution are compatible with complex GNU linker scripts,
SORTdirectives,KEEP, memory regions, overlays, orphan-section rules, and script-defined symbol behavior. - Non-ELF and platform portability is limited: mold is presented as a Unix/Linux ELF linker; applicability to Mach-O, PE/COFF, other object formats, and non-Linux Unix systems remains unexamined.
- Architecture-specific correctness evidence is sparse: Although 14 architectures are supported, most examples and detailed evaluation concern x86-64 and ARM64. The paper does not report systematic performance and correctness results for all supported targets, particularly architectures with complex relocation and thunk behavior.
- Range-extension thunk correctness lacks formal proof: The single-pass thunk algorithm is argued to be safe informally, but the paper does not provide a formal proof covering all relocation types, section arrangements, branch directions, alignment constraints, or architecture-specific range rules.
- Thunk overhead and failure cases are underexplored: The impact of pessimistic cross-section assumptions, overallocated thunks, very large code models, pathological layouts, and links that approach architectural branch-range limits is not quantified.
- Identical Code Folding may depend on hash assumptions: The ICF algorithm treats cryptographic hash equality as sufficient for equivalence; the paper does not quantify collision-risk assumptions in the threat model or compare its correctness and performance with exact partition-refinement methods.
- ICF semantic safety is not fully addressed: The paper does not examine cases involving address-taking, function-pointer equality, debug information, exception handling, sanitizers, profile-guided optimizations, or language-level assumptions that can make folding observably unsafe.
- Parallel garbage collection lacks detailed determinism and overhead analysis: The paper describes a feeder-based traversal but does not report work-queue contention, load imbalance, graph-shape sensitivity, or performance on highly connected or highly fragmented section graphs.
- Determinism guarantees are conditional: Bit-identical output is claimed for identical inputs, options, and linker versions, but the paper does not clarify behavior across different thread counts, CPU architectures, filesystem states, locale settings, allocator configurations, or nondeterministic inputs.
- Reproducibility is not evaluated end to end: The paper does not test whether mold preserves reproducible-build properties when timestamps, build paths, debug metadata, UUIDs, build IDs, or external tools are involved.
- I/O optimizations are environment-dependent: Huge pages and
fallocateare evaluated primarily on ext4/NVMe Linux systems; their effectiveness, compatibility, and possible costs on other filesystems, network storage, encrypted storage, containers, and macOS remain unknown. - File reuse raises failure-consistency questions: Overwriting existing executable files in place is described as an optimization, but crash consistency, power loss, concurrent readers, backup tools, hard links, permissions, and partial-output recovery are not analyzed.
- The two-process architecture may affect tooling and resource accounting: The paper does not evaluate interactions with debuggers, profilers, job schedulers, sandboxing, process supervisors, signal handling, exit status propagation, or build systems that track child processes.
- LTO workloads are largely excluded from the main performance claim: Because LTO compilation dominates link time, mold's advantage under LTO is described qualitatively rather than measured across GCC and LLVM versions, thread configurations, cache states, and realistic release builds.
- Incremental and distributed builds are not examined: The paper focuses on full links and does not investigate incremental linking, remote execution, distributed filesystems, build caches, or interactions with modern build systems such as Bazel, Buck, Ninja, and distributed CI.
- Power and energy efficiency are unmeasured: Faster linking may require substantial parallel CPU power; the paper reports elapsed time and CPU cost only insofar as available in the missing evaluation, leaving energy per link and thermal effects unresolved.
- Performance variability is not characterized: The methodology does not indicate whether results include repeated trials, confidence intervals, cold-cache measurements, contention with other processes, or sensitivity to input ordering and thread scheduling.
- The cumulative optimization story lacks broader causal validation: The ablation design is said to show that no single optimization dominates, but it remains unclear whether interactions among optimizations are additive, workload-specific, or responsible for the reported speedups.
- Developer-facing trade-offs are underexplored: The paper does not evaluate diagnostic quality, error-reporting latency, warning compatibility, debuggability, maintainability, or the difficulty of extending mold with new ELF features.
- Security implications are not analyzed: Eager parsing, large parallel allocations, concurrent hash tables, memory mapping, and file reuse may affect denial-of-service resistance, malformed-input handling, and attack surfaces, but these issues are not evaluated.
- No formal complexity or contention model is provided: The paper motivates data parallelism empirically but does not derive bounds or predictive models for synchronization costs, memory traffic, cache behavior, or pass-level scalability across different input distributions.
Practical Applications
Immediate Applications
The paper’s findings are already applicable to Unix/Linux software-development workflows, particularly where large C/C++ codebases, multi-gigabyte binaries, and multi-core build machines make linking a bottleneck.
- Faster edit–compile–debug cycles for large C/C++ projects — software development
- Replace GNU
ld,gold, or, where compatible,lldwithmoldin build systems such as CMake, Bazel, Ninja, Make, and Meson. - This can substantially reduce the time required to produce debug executables and shared libraries for projects such as browsers, compilers, machine-learning frameworks, operating systems, and game engines.
- Faster linking enables developers to perform more build–test–debug iterations per day and reduces idle time on continuous integration workers.
- Dependencies: Linux/Unix ELF compatibility, sufficient RAM and storage bandwidth, a compatible target architecture, and acceptance of mold’s differences in some obscure symbol-resolution and archive-ordering corner cases.
- Replace GNU
- Acceleration of large-scale continuous integration and release pipelines — DevOps and cloud computing
- Integrate
moldinto CI images and build containers to shorten final link stages that otherwise leave many CPU cores idle. - Build farms can use the same hardware more efficiently, potentially increasing throughput without proportionally increasing the number of workers.
- A practical workflow is to use mold for developer and debug builds while retaining a reference linker for compatibility validation or selected release artifacts.
- Dependencies: Build scripts must select the linker consistently; parallel linking may increase peak memory consumption and can make storage I/O a limiting factor.
- Integrate
- Faster production of debug binaries and crash-analysis artifacts — software maintenance and cybersecurity
- Use mold when generating binaries containing extensive DWARF debugging information, such as browser builds, kernel components, embedded firmware, and large server applications.
- Its concurrent
.gdb_indexconstruction can reduce the delay before binaries are usable with GDB, while the reproducible-output design supports reliable symbol-file matching and incident investigation. - Dependencies: The workflow must use ELF binaries and compatible DWARF/GDB tooling. The reported advantage is smaller when LTO compilation dominates the total build time.
- Lower binary size through parallel section garbage collection and identical code folding — software optimization
- Enable compiler options such as
-ffunction-sectionsand-fdata-sections, together with linker garbage collection and ICF where safe. - This can remove unreachable functions and merge duplicate code, reducing executable size, download time, storage requirements, and memory pressure.
- Relevant sectors include mobile applications, cloud services, browsers, embedded systems, and edge devices.
- Dependencies: Fine-grained sections must be generated by the compiler; ICF may be inappropriate where address identity or subtle language/runtime assumptions matter. Size reductions are workload-dependent.
- Enable compiler options such as
- More efficient generation of position-independent executables and shared libraries — operating systems and application security
- Use mold’s parallel relocation scanning to accelerate construction of GOT, PLT, and related dynamic-linking structures for PIE and shared-library builds.
- This supports standard security practices such as ASLR and position-independent code without making large builds unnecessarily slow.
- Dependencies: The target platform, ABI, relocation model, and dynamic loader must be supported. The paper focuses on ELF/Unix-like systems rather than Windows PE or macOS Mach-O workflows.
- Faster builds for heterogeneous multi-architecture software — embedded systems and hardware platforms
- Use mold’s architecture-parametric implementation for cross-compilation targeting ARM, RISC-V, PowerPC, x86, s390x, LoongArch, and other supported architectures.
- This is useful for firmware SDKs, Linux distributions, mobile platforms, robotics software, and products shipping one codebase across multiple processor families.
- Dependencies: Architecture-specific relocation behavior, range-extension thunks, ABI conventions, and toolchain integration must be correctly supported for the selected target.
- Adoption of system-level linker optimizations by existing toolchains — compiler and operating-system engineering
- Independently apply the paper’s low-risk optimizations to other linkers and build tools:
- memory-map output files using
madvise(MADV_HUGEPAGE); - preallocate output files with
fallocate; - use scalable allocators such as mimalloc;
- reuse existing executable output files when safe;
- release file mappings before process exit;
- hide teardown latency with a two-process design.
- These techniques can improve output-copy performance even without adopting mold’s complete architecture.
- Dependencies: Benefits depend on Linux kernel behavior, filesystem support, available huge pages, allocator characteristics, and output-file safety. Shared libraries generally cannot be overwritten in place while running processes may still have them mapped.
- More reproducible and cache-friendly builds — academia, industry, and open-source distribution
- Use mold’s deterministic output behavior in reproducible-build pipelines and binary caches.
- Bit-identical results can improve cache hit rates, simplify artifact verification, support supply-chain audits, and make experimental results easier to reproduce.
- Dependencies: Reproducibility is conditional on identical inputs, command-line options, linker version, compiler behavior, and environmental factors that affect the build.
- Teaching and benchmarking parallel systems techniques — academia
- Use mold as a concrete case study for applying parallel-for loops, atomic compare-and-swap, monotonic flags, concurrent hash tables, graph reachability, prefix scans, Merkle trees, and hash-based equivalence refinement in a production system.
- Compiler-construction and parallel-algorithms courses can reproduce smaller versions of its symbol-resolution, section-layout, or identical-code-folding algorithms.
- Dependencies: Full reproduction requires substantial ELF, ABI, compiler, and systems expertise; simplified educational implementations will not capture all compatibility corner cases.
- Shorter local feedback loops for individual developers — daily professional use
- Configure local development toolchains to invoke mold for debug builds, particularly when compiling template-heavy C++ applications or projects with millions of sections and symbols.
- Developers can combine this with incremental compilation, build caching, and parallel test execution to reduce end-to-end feedback latency.
- Dependencies: The project must tolerate mold’s linking semantics and must not be dominated by compilation, code generation, or LTO time.
Long-Term Applications
The paper also suggests broader applications that require additional standardization, validation, or adaptation beyond the demonstrated Unix/Linux linker.
- A formally specified, fully parallel ELF linking standard — policy and systems research
- Develop a normative specification for archive extraction, symbol precedence, COMDAT selection, weak/common symbols, circular dependencies, and ordering semantics.
- Such a specification would allow competing linkers to implement aggressive parallel algorithms while providing users with predictable cross-linker behavior.
- Dependencies: Agreement among compiler, operating-system, distribution, and toolchain communities is required. The current reliance on GNU
ldas a de facto reference makes semantic changes difficult.
- Portable massively parallel linking across non-ELF platforms — software tooling
- Extend the data-parallel architecture to Windows PE/COFF, macOS Mach-O, mobile binary formats, and proprietary embedded formats.
- This could produce platform-specific linkers or a common parallel linking framework for major operating systems.
- Dependencies: Object-file formats, relocation rules, archive semantics, dynamic loaders, code-signing requirements, and platform-specific compatibility behavior differ substantially from ELF.
- GPU- or accelerator-assisted linking — high-performance computing and cloud infrastructure
- Offload suitable operations—string hashing, symbol-name interning, relocation classification, cryptographic build-ID computation, graph refinement, and prefix scans—to GPUs or other accelerators.
- This could be valuable for exceptionally large monolithic builds or centralized build services.
- Dependencies: Data-transfer overhead, irregular memory access, synchronization, host-device memory capacity, and the inherently sequential boundaries between linker passes may limit practical gains. CPU parallelism should be saturated first.
- Distributed linking for very large monorepos — cloud build systems
- Partition parsing, symbol indexing, relocation analysis, or section processing across build-service nodes, followed by deterministic aggregation.
- A distributed linker could reduce wall-clock time for applications whose object files and debug artifacts exceed the memory or I/O capacity of one machine.
- Dependencies: Global symbol resolution and deterministic layout require efficient distributed data structures and communication. Reproducibility, failure recovery, security, and network transfer costs are unresolved challenges.
- Incremental and persistent parallel linking — interactive development environments
- Preserve parsed ELF metadata, symbol tables, interned strings, section graphs, and layout information across builds.
- When only a small set of object files changes, the linker could recompute affected regions rather than rerunning every pass over the complete program.
- This could enable near-instant relinking for large IDE projects and live-debugging workflows.
- Dependencies: Correct invalidation is difficult because a changed definition can affect archive liveness, COMDAT selection, GOT/PLT requirements, section reachability, layout, and range-extension thunks throughout the binary.
- Parallel linking for robotics, automotive, and embedded software — robotics and edge computing
- Apply the techniques to large safety-critical or resource-constrained software stacks, including autonomous vehicles, robot operating systems, industrial controllers, and edge AI devices.
- Parallel garbage collection, code folding, and deterministic output could reduce build time while producing smaller firmware images.
- Dependencies: Safety certification may require validation against a trusted linker, exact binary reproducibility, conservative optimization settings, and proof that linker transformations preserve required behavior.
- Build-energy reduction through shorter link phases — energy and sustainability
- Use faster parallel linking to reduce the duration of high-power build jobs in developer workstations, CI clusters, and cloud build farms.
- At scale, shorter jobs could lower energy consumption per build and improve utilization of existing infrastructure.
- Dependencies: Energy savings are not guaranteed: running many cores at high utilization may increase instantaneous power, and total energy depends on CPU efficiency, memory traffic, storage behavior, and whether faster builds lead to more frequent builds.
- Security and supply-chain products based on deterministic build identity — cybersecurity and policy
- Combine deterministic linking and parallel Merkle-tree build-ID computation with artifact signing, provenance systems, reproducible-build verification, and vulnerability databases.
- A toolchain could automatically verify that a deployed executable corresponds exactly to audited source, compiler inputs, and a recorded build environment.
- Dependencies: Linker determinism alone does not guarantee whole-build reproducibility; compilers, archives, timestamps, generated files, dependencies, and signing infrastructure must also be controlled.
- General-purpose parallelization patterns for other toolchain components — compiler research
- Transfer the paper’s central architectural lesson—serially ordered passes with data-parallel work over homogeneous arrays—to assemblers, binary rewriters, static analyzers, debuggers, package indexers, and code-signing pipelines.
- Candidate methods include atomic monotonic state updates, parallel graph traversal, two-level scans, canonical sorting after nondeterministic work, and specialized concurrent hash tables.
- Dependencies: The approach is most effective when workloads contain large collections of mostly independent elements. Tools dominated by fine-grained dependencies, global ordering, or complex mutable state may require different designs.
Glossary
- Ablation study: An experiment that removes or isolates individual components to measure their separate contributions. “An ablation study shows that no single optimization dominates”
- Amdahl’s law: A principle stating that the maximum speedup of a parallelized system is limited by its remaining sequential portion. “By Amdahl's law~\cite{amdahl1967}, parallelizing only a subset of passes leaves the serial remainder as a hard ceiling on speedup”
- Archive: A file, typically a static library, containing multiple object files that can be selectively extracted during linking. “An archive (or static library, with the #1{.a} file extension) is a bundle of object files.”
- Atomic compare-and-swap: An indivisible operation that updates a value only if it still equals an expected value, enabling lock-free synchronization. “using an atomic compare-and-swap on the owner field of the shared symbol object”
- Bisimulation equivalence: A relation identifying graph nodes that exhibit indistinguishable behavior through corresponding transitions. “This is equivalent to computing bisimulation equivalence over a directed graph”
- BLAKE3: A fast cryptographic hash function designed for efficient parallel execution and modern processor instructions. “For the hash function, mold uses BLAKE3~\cite{blake3}, a cryptographic hash function designed to take advantage of SIMD instructions on modern processors.”
- Build ID: A unique identifier embedded in a binary, commonly computed from a cryptographic hash of the output. “The last piece of the output is the build ID.”
- Bump-pointer allocator: A memory allocator that advances a pointer through a buffer to allocate objects rapidly, usually without individually freeing them. “we also implemented a simple bump-pointer allocator that allocates from large per-thread buffers and never frees individual objects.”
- COMDAT group: A linker-marked group of sections for which multiple equivalent definitions may exist but only one copy should be retained. “These duplicate definitions are placed in COMDAT groups”
- Concurrent data structure: A data structure designed to support safe access and modification by multiple threads simultaneously. “using concurrent data structures and atomic operations for the few points requiring synchronization”
- Cryptographic hash: A hash function designed to make it computationally infeasible to reconstruct inputs or deliberately produce collisions. “a cryptographic hash of the output file is typically used.”
- Data parallelism: Parallel execution of the same operation independently across many elements of a data collection. “structure every major pass as a data-parallel loop over homogeneous arrays of elements”
- De facto reference implementation: A practical implementation treated as authoritative despite not being formally designated as a standard. “GNU ld is widely considered the de facto reference implementation.”
- DWARF: A standardized debugging-information format describing source-level constructs, symbols, and machine-code locations in compiled binaries. “A #1{.gdb_index} section indexes symbol names and address ranges in DWARF~\cite{dwarfspec} debug information”
- ELF (Executable and Linkable Format): A binary format used for executable files, object files, shared libraries, and core dumps on Unix-like systems. “An ELF object file is divided into named regions called sections”
- Embarrassingly parallel: Describing computations whose tasks require little or no communication or synchronization. “Each iteration is embarrassingly parallel and needs no synchronization.”
- Fixed-point algorithm: An iterative algorithm that repeatedly applies transformations until a subsequent iteration produces no further changes. “the same sequential fixed-point algorithm”
- Garbage collection (section GC): The removal of sections that are unreachable from required program components. “the linker can perform garbage collection (GC) to discard unreferenced sections.”
- Global Offset Table (GOT): A table of addresses used to access variables and other objects indirectly in position-independent code. “Accesses to such global variables go through the \emph{Global Offset Table} (GOT)”
- Hash collision: An occurrence in which distinct inputs produce the same hash value. “Cryptographic hashing makes erroneous merges due to hash collisions negligibly unlikely.”
- HyperLogLog: A probabilistic cardinality-estimation algorithm for approximating the number of distinct elements in a set. “we first estimate the number of distinct strings using the HyperLogLog algorithm”
- Identical Code Folding (ICF): A linking optimization that merges sections containing equivalent machine code and relocation information. “Identical Code Folding (ICF) is an optional size optimization that merges read-only sections with identical contents and relocations.”
- Interning: The replacement of equal values with a shared canonical object so that identity can be tested by reference equality. “Symbol names are interned so that files that define or reference the same name share one symbol object”
- Link-Time Optimization (LTO): Optimization performed across compilation units during linking rather than independently within each source-file compilation. “mold supports GCC and LLVM Link-Time Optimization (LTO).”
- Memory mapping: Mapping file contents into a process’s virtual address space so they can be accessed as memory. “In the final phase, mold memory-maps the output file”
- Merkle tree: A tree of cryptographic hashes in which parent hashes summarize the hashes of child blocks. “mold parallelizes the hash computation using a two-level Merkle tree”
- Monotonic operation: An operation whose state progresses in one direction and does not revert to an earlier state. “Since each symbol's flag is set monotonically”
- Multi-core hardware: A processor containing multiple independent execution cores capable of running threads concurrently. “prevent existing linkers from exploiting modern multi-core hardware”
- Page fault: An operating-system exception raised when a process accesses a virtual-memory page that is not currently available in physical memory or has not yet been initialized. “every page of a fresh output file is created on first touch by a minor page fault”
- Parallel-for loop: A loop construct that distributes iterations of the same operation among multiple threads. “mold executes passes serially but parallelizes within each pass using parallel-for loops.”
- Partition refinement: An iterative method for dividing sets into increasingly finer equivalence classes. “Unlike classical partition refinement algorithms such as Hopcroft's”
- Position-independent code (PIC): Machine code that can execute correctly regardless of the address at which it is loaded. “They are instead compiled as position-independent code (PIC)”
- Position-independent executable (PIE): An executable constructed so that it can be loaded at a variable address, typically supporting address-space randomization. “even executables are often built as position-independent (PIE)”
- Procedure Linkage Table (PLT): A table of call stubs used to resolve and invoke functions dynamically at runtime. “Calls to such functions go through the Procedure Linkage Table (PLT)”
- Prefix sum: A scan operation that computes cumulative totals over an ordered sequence. “This is essentially a prefix sum over section sizes”
- Reachability traversal: A graph traversal that identifies nodes accessible from one or more starting nodes. “performs a parallel reachability traversal.”
- Relocation: Metadata specifying how the linker must modify machine-code or data locations once final addresses are known. “Relocations are metadata instructing the linker to patch specific locations in section data”
- Range extension thunk: A small code sequence inserted to reach a branch target outside the instruction’s directly encodable displacement range. “When a target is out of reach, it inserts a range extension thunk”
- SIMD (Single Instruction, Multiple Data): A hardware execution model in which one instruction operates simultaneously on multiple data values. “designed to take advantage of SIMD instructions on modern processors.”
- Sparse file: A file whose logical size includes unallocated regions that consume disk space only when written. “A freshly created output file is sparse.”
- Symbol resolution: The process of determining which definition satisfies each symbol reference in the linked program. “Symbol resolution determines, for each symbol, which definition prevails.”
- Synthetic section: A section created by the linker rather than copied directly from an input object file. “Construct synthetic sections (GOT, PLT, dynamic symbol tables)”
- Task parallelism: Parallel execution of different tasks or phases, often coordinated through dependencies. “gold took the opposite approach, employing task parallelism through a work queue with dependency tokens”
- Trampoline: A small intermediate code sequence that transfers control to another location, often when a direct branch cannot reach its destination. “range extension thunk (also called a veneer or trampoline)”
- Virtual address space: The process-specific address range through which a program accesses memory. “Each process has its own virtual address space”
- Weak symbol: A symbol definition that has lower precedence than a strong definition during linking. “The ELF specification defines basic precedence rules (e.g., strong definitions override weak ones)”
- Work queue: A shared or coordinated queue of pending tasks from which worker threads obtain work. “most tasks are serialized by their dependency chains”