Fact-checked by Grok 2 weeks ago

Dynamic linker

A dynamic linker, also known as a linker or dynamic loader, is the component of an operating system that loads shared libraries and resolves their symbols into the of an executing at , rather than during compilation. This process enables multiple applications to share the same library code in memory, promoting modularity and resource efficiency in modern computing environments. The origins of dynamic linking trace back to early multiprogramming systems like in the 1960s, where it facilitated loading external code segments into running processes without recompilation. However, widespread adoption in systems occurred in the late , with 4.0 introducing a comprehensive for shared libraries in 1988, using (PIC) to allow libraries to be mapped into arbitrary memory locations via the . This design, which required no kernel modifications and was transparent to developers, influenced subsequent implementations in BSD, , and other platforms, emphasizing benefits like reduced disk and memory usage—for instance, saving approximately 24 KB per in typical setups. At runtime, the dynamic linker operates by first being invoked by the operating system kernel upon detecting an executable with a program interpreter entry (e.g., PT_INTERP in ELF format), such as /lib64/ld-linux-x86-64.so.2 on Linux systems. It then parses the executable's dependencies listed in DT_NEEDED entries, loads the required shared objects into memory, and applies relocations to patch symbolic references with actual addresses, often using structures like the Global Offset Table (GOT) and Procedure Linkage Table (PLT) for efficient, lazy binding that defers resolution until a function is first called. Environment variables like LD_LIBRARY_PATH can influence search paths, while features such as LD_PRELOAD allow overriding libraries for debugging or testing, and security mechanisms like Address Space Layout Randomization (ASLR) and RELRO (read-only relocations) enhance protection against exploits by randomizing load addresses and locking modifiable sections post-resolution. Implementations vary across operating systems but follow similar principles. In , the GNU C Library () provides the ld.so dynamic linker for binaries, handling dependency resolution and interposition. On macOS and , dyld serves as the dynamic linker for executables, supporting features like two-level namespaces for symbol lookup and variables prefixed with DYLD_ to control loading behavior. In AIX from , the loader resolves s at load time for shared objects, integrating with the system's runtime to share library pages across processes. Microsoft employs dynamic linking through DLLs, where the loader (part of ntdll.dll and the executive) binds imports at load or run time, though the explicit "dynamic linker" terminology is more common in contexts. Dynamic linking offers significant advantages, including smaller sizes, reduced disk storage by avoiding code duplication, and the ability to update libraries system-wide without relinking applications, which improves and can enhance through shared memory pages that minimize page faults in multi-process environments. Lazy binding further optimizes startup times by postponing non-essential resolutions. However, it introduces challenges such as a minor performance overhead from (e.g., about 8 machine cycles per reference due to ), potential increases in page faults from reduced locality, and runtime dependencies that can lead to compatibility issues if libraries are updated incompatibly or become unavailable. To mitigate these, practices like semantic versioning and symbol versioning—pioneered in in 1995 and adopted in —track /ABI changes, ensuring .

Fundamentals

Definition and Purpose

A dynamic linker, also known as a dynamic loader or runtime linker, is a specialized component of an operating system that loads shared object files—such as .so files on Unix-like systems or .dll files on Windows—into a running process's memory space and resolves references to external symbols at runtime. This process involves interpreting the executable's program headers to identify dependencies, mapping the required libraries into address space, and performing necessary relocations to enable the program to access the shared code and data. Unlike static linking, which embeds all dependencies at compile time, the dynamic linker operates during program execution, typically invoked as the program's interpreter via mechanisms like the PT_INTERP entry in the executable format. The primary purpose of a dynamic linker is to facilitate code and data sharing among multiple processes, thereby reducing overall consumption and requirements in multi-program environments. By loading shared libraries only once into and allowing multiple applications to reference them, it promotes efficient resource utilization, particularly in systems with limited . Additionally, dynamic linking supports modular by enabling independent updates to libraries without necessitating recompilation or relinking of dependent applications, as long as interface is maintained; this eases and fosters architectures like plugins, where extensions can be loaded . Key benefits include enhanced system through lazy symbol resolution—where bindings occur only when functions are first called—and the ability to support that can be shared across processes with varying address mappings. The concept of dynamic linking emerged in the late 1960s as an innovation in early systems to overcome the limitations of monolithic, statically linked executables that duplicated code across processes and hindered efficient sharing. Pioneered in , a collaborative project between , , and starting in 1965, it allowed processes to dynamically incorporate external segments containing routines, resolving symbols via traps upon first reference to enable fine-grained among users. This approach addressed resource constraints in multiprogrammed environments and influenced subsequent systems; by the 1980s, it evolved into mechanisms in Unix variants, notably with in 1988, which extended sharing to library routines like standard I/O functions to further optimize memory and I/O efficiency.

Comparison to Static Linking

Static linking involves embedding all necessary code directly into the file during the and linking phase, producing a self-contained that requires no external dependencies at . This process resolves all symbols and relocations at link time, ensuring the final includes complete copies of the required functions. In contrast, dynamic linking defers symbol resolution and until , using shared libraries that multiple executables can without duplication. This late allows the operating system loader to map libraries into memory as needed, whereas static linking performs early at , resulting in larger executables but eliminating searches. Key trade-offs include static linking's simplicity and predictability versus dynamic linking's flexibility in resource sharing. Dynamic linking offers advantages over static linking, such as reduced disk space and memory usage through sharing across applications, potentially saving storage when multiple processes run concurrently. It also facilitates easier patching of without recompiling or redistributing executables, as updates to shared propagate system-wide. However, dynamic linking incurs overhead, including additional machine cycles (approximately 8 per reference) for through "" and potential increases in page faults due to reduced code locality. It can also lead to "," where incompatible versions or missing dependencies cause failures, complicating deployment in diverse environments. Static linking suits use cases like embedded systems or standalone applications, where self-containment ensures reliability without external dependencies, as seen in microcontrollers and IoT devices. Dynamic linking is preferred in general-purpose operating system environments, such as systems, to optimize space and enable shared updates across numerous applications.

Operational Mechanism

Library Loading Process

The library loading process in dynamic linking is initiated either at program startup or during runtime. When a dynamically linked is launched, the operating system invokes the dynamic linker as part of the execution , such as through the execve in systems, where the linker is specified in the executable's interpreter section (e.g., .interp in files). Alternatively, libraries can be loaded dynamically at runtime via explicit calls like dlopen(), allowing programs to incorporate additional shared objects on demand. The dynamic linker begins by parsing the executable's dependency list, typically stored in headers such as the DT_NEEDED entries in the ELF dynamic section, which enumerate required shared libraries by name (e.g., libc.so.6). It then searches for these libraries using a prioritized path resolution strategy, starting with embedded paths in the executable (e.g., DT_RPATH), followed by environment variables like LD_LIBRARY_PATH, cached library indices (e.g., /etc/ld.so.cache), and standard directories such as /lib and /usr/lib. To handle recursive dependencies, the linker performs a depth-first or breadth-first traversal, building a complete dependency graph while detecting and avoiding cycles by tracking already-loaded libraries in a link chain, ensuring each unique library is processed only once. Once located, the linker maps the shared libraries into the process's virtual memory space using mechanisms like mmap to load file segments as shared, read-only regions, which promotes efficient memory sharing across processes. It allocates distinct segments for code (text), initialized data, and uninitialized data (BSS), positioning them at preferred base addresses specified in the library's ELF headers to support position-independent code (PIC) and address space layout randomization (ASLR). This mapping occurs in reverse dependency order—loading leaf dependencies before their dependents—to establish a stable foundation before integrating higher-level libraries. Errors during loading are handled by terminating the process with diagnostic messages, such as failures due to missing libraries (e.g., "cannot open shared object file") or invalid paths in LD_LIBRARY_PATH, which may be ignored in secure-execution modes to prevent . mismatches, detected via sonames or symbol versioning in the headers, also trigger failures to ensure compatibility. Following successful loading, the process proceeds to symbol resolution, where references between the executable and libraries are connected.

Symbol Resolution

In dynamic linking, symbol resolution is the process by which the dynamic linker identifies and binds undefined references in an or to their corresponding definitions in loaded shared objects. This occurs after libraries are loaded into memory, ensuring that external symbols—such as function calls or variable accesses—are correctly mapped without requiring full static resolution at . The linker traverses the dependency chain, starting from the main 's dependencies listed in the DT_NEEDED entries of the .dynamic section, to locate definitions systematically. Symbols resolved by the dynamic linker primarily include external functions and variables, which are stored in dedicated symbol tables within object files. In ELF-based systems, the .dynsym section holds these dynamic symbols, each entry containing the symbol name (via an offset into the .dynstr string table), type (e.g., STT_FUNC for functions or STT_OBJECT for variables), binding (e.g., STB_GLOBAL for external visibility), and scope information such as section index. These tables enable the linker to distinguish between local symbols (confined to a single object) and global ones (potentially shared across objects), facilitating efficient lookups during runtime. The resolution strategy employs a through the loaded objects' symbol tables, prioritizing dependencies in the order specified by DT_NEEDED tags to avoid circular . For fast lookup, the linker uses hash tables referenced by the DT_HASH tag in the .dynamic section, which map symbol names to table indices, reducing search time from linear to near-constant. When multiple definitions exist, symbols (with STB_GLOBAL binding and non-weak attributes) take precedence over weak symbols (STB_WEAK), which serve as optional placeholders and can be overridden without error; if no definition is found, a weak one is used, or the remains unresolved if none exists. This handling ensures in library updates where weak symbols allow graceful fallbacks. Binding modes determine when and how symbols are resolved: load-time (eager ) processes all undefined symbols immediately upon loading, often enforced via the LD_BIND_NOW for security or predictability, though it increases startup . In contrast, (lazy ) defers resolution until the first reference, typically via the Procedure Linkage Table (PLT) and Global Offset Table (GOT), where an initial indirect call triggers the linker to patch the address on-demand, optimizing performance by skipping unused symbols. Global binding allows symbols to be shared across the process, while local binding restricts them to the defining object, preventing unintended interposition. Programmers can perform manual symbol resolution using APIs like dlsym(), which searches for a symbol by name within a specified handle (e.g., from dlopen()) or the default search order (RTLD_DEFAULT), returning its runtime address or NULL if unresolved. This is useful for plugins or conditional loading, with errors retrievable via dlerror(). To control symbol export and visibility, attributes such as attribute((visibility("hidden"))) in GCC hide symbols from the dynamic symbol table, preventing external resolution and reducing namespace pollution; other modes like "protected" allow local overrides while keeping global visibility. These features enhance modularity and security in shared libraries.

Relocation and Initialization

After symbol resolution, the dynamic linker processes relocation entries to adjust references in the loaded code and data sections, patching them with the actual runtime addresses of symbols. These relocations ensure that the executable and shared libraries function correctly regardless of their load addresses in memory. Relocation types fall into two primary categories: absolute and relative. Absolute relocations, such as R_X86_64_64 on systems, directly fix the target address to a specific absolute location in memory, requiring updates to the loaded object's base address. In contrast, relative relocations, like R_X86_64_PC32, compute offsets relative to the position of the reference itself, avoiding the need for absolute address fixes and enabling (). In ELF-based systems, these entries are stored in tables such as .rela.dyn for dynamic relocations, where each entry specifies the location to patch, the relocation type, the associated symbol, and an addend for offset calculations. The relocation process supports for non-immediate references, such as indirect function calls, deferring patches until the first use to improve startup performance, though full eager relocation can be enforced for . (PIC) is a key technique in dynamic linking, allowing shared libraries to be loaded and shared across multiple processes at arbitrary addresses without modification. This supports features like (ASLR) for and efficient memory sharing. In PIC implementations, the offset table (GOT) stores resolved addresses for data symbols, while the linkage table (PLT) handles function calls through indirect jumps, enabling runtime resolution without altering the code itself. Following relocations, the dynamic linker performs initialization by executing constructors—functions that set up library state—typically stored in sections like .init for legacy code or .init_array for modern binaries. These constructors run in dependency order before transferring control to the main program. On library unload, corresponding destructors in sections such as .fini or .fini_array are invoked in reverse order to clean up resources.

Implementations

Microsoft Windows

In Microsoft Windows, dynamic linking is implemented through the (PE) file format, derived from the Common Object File Format (COFF), which supports both executables (.exe) and dynamic-link libraries (DLLs). The PE format includes sections such as the import directory table in the .idata section, which lists dependencies on external DLLs and the functions imported from them. The operating system's loader, primarily handled by ntdll.dll and kernel32.dll, processes these imports during program execution to resolve and load required modules dynamically. The loading process begins when the Windows loader parses the PE header of an , identifying DLL dependencies via the import table in the .idata . For each listed DLL, the loader calls internal s like LdrLoadDll in ntdll.dll to map the module into the process's , followed by updating the Import Address Table (IAT) with actual addresses using routines such as LdrpSnapIAT. Runtime loading is facilitated by the LoadLibrary in kernel32.dll, which allows explicit loading of DLLs , enabling flexible management beyond initial startup. Windows also supports delay-load imports, where is postponed until the first call, reducing startup time by avoiding unnecessary loads; this is achieved through compiler directives and linker options that wrap imports with stubs calling GetProcAddress for lazy binding. A distinctive feature of Windows dynamic linking is support for side-by-side assemblies, introduced in to enable multiple versions of the same DLL to coexist without conflicts, addressing issues from earlier systems. These assemblies are groups of DLLs, resources, and metadata deployed together, allowing applications to bind to specific versions at runtime. Dependency declaration occurs via manifest files, XML documents embedded in executables or separate files, which specify required assemblies by name, version, and public key token, ensuring the loader selects the correct side-by-side version during resolution. Historically, dynamic linking in Windows evolved with the Win32 subsystem introduced in in 1993, building on earlier 16-bit DLL support in but adopting the PE/COFF format for 32-bit portability across processors. This foundation persisted through subsequent versions, with enhancements like side-by-side assemblies in 2001 and, in modern (UWP) apps introduced in in 2012, integration with AppX packaging for isolated deployment of DLL dependencies within app containers, maintaining PE-based loading while adding sandboxing.

ELF-based Systems

In ELF-based systems, such as those found in various operating systems, dynamic linking is facilitated by the (ELF), which standardizes the structure for executables and shared libraries. The primary dynamic linker, often referred to as ld.so or variants like ld-linux.so, is responsible for loading shared objects, resolving dependencies, and preparing the for execution at . This ensures efficient sharing of and among multiple programs while allowing for modular updates to libraries. The dynamic linker is invoked by the kernel following an exec() system call on an ELF executable that specifies it via the PT_INTERP program header, typically pointing to a path like /lib/ld-linux.so.2. Upon invocation, the linker maps the executable into memory and examines its PT_DYNAMIC program header, which contains the .dynamic section. This section holds an array of dynamic entries (ElfXX_Dyn structures) that provide essential metadata for linking. Key to dependency management in the .dynamic section are the DT_NEEDED tags, which list the names of required shared libraries as offsets into the string table (DT_STRTAB); these entries dictate the order in which dependencies are loaded in a breadth-first manner. Shared libraries are identified and versioned using sonames, specified via the DT_SONAME tag—for instance, libc.so.6 indicates the GNU C Library version 6—allowing the linker to select compatible implementations without embedding full paths. To locate these libraries, the linker interprets search paths from DT_RPATH (a colon-separated list embedded at link time, applicable to the entire dependency tree) or its modern successor DT_RUNPATH (limited to direct dependencies), supplemented by environment variables like LD_LIBRARY_PATH and system caches. This mechanism is implemented in major ELF-based systems, including distributions utilizing the GNU C Library's ld-linux.so (part of ) and with its runtime linker ld.so.1. In , tools like ldd simulate the loading process to list an executable's dependencies by setting the LD_TRACE_LOADED_OBJECTS , aiding in verification without execution. employs similar conventions but integrates with its own linker tools for cache management via /etc/ld.so.conf. These implementations support relocation types for address adjustments, as outlined in the broader operational mechanisms of dynamic linking.

Mach-O in Apple Systems

In Apple systems such as macOS and iOS, the dynamic linker is implemented as dyld (with the current version being dyld3, introduced in 2017 and default since macOS 10.13 for system apps and macOS 10.15 for third-party apps), a standalone binary located at /usr/lib/dyld that serves as the primary loader for Mach-O executables, dynamic libraries, and bundles. dyld3 represents a complete rewrite of the dynamic linker, featuring out-of-process Mach-O parsing, launch closure caching to disk for faster startups, and enhanced security through improved randomization, while maintaining compatibility with prior versions. dyld integrates closely with the Mach kernel's virtual memory management, enabling address space layout randomization (ASLR) through features like image sliding, where loaded modules are mapped at randomized virtual addresses to enhance security. Upon process launch, the kernel passes control to dyld after initial executable loading, at which point dyld parses the Mach-O header and resolves dependencies before transferring execution to the main program entry point. The file format, used exclusively in Apple ecosystems for binaries, incorporates specific load commands to declare dynamic dependencies, primarily through the LC_LOAD_DYLIB command, which specifies the path and compatibility version of required dynamic libraries (dylibs). This command is part of the load command array in the header, allowing dyld to identify and load shared libraries at , with variants like LC_LOAD_WEAK_DYLIB for optional dependencies that do not cause fatal errors if unresolved. also supports modular loading via bundles (MH_BUNDLE file type), which are dynamically loadable code modules often used for plug-ins, and frameworks, which package libraries, headers, and resources into self-contained units for easier distribution and versioning. Symbol resolution in dyld employs a two-level namespace model by default, where symbols are qualified by both their name and the originating library's identifier (e.g., libraryName!symbolName), enabling precise versioning and avoiding flat namespace collisions across multiple libraries. This approach supports by allowing applications to bind to specific library versions at link time, with dyld enforcing these bindings during loading unless overridden by flags like -flat_namespace. To optimize startup , dyld utilizes the dyld_shared_cache, a precomputed, system-wide of commonly used libraries (e.g., system frameworks like and CoreFoundation) that are slide-compacted and mapped once into , reducing load times and memory overhead for multiple processes. Apple systems enforce strict security measures in dynamic linking, particularly through , where all binaries must be digitally signed with a valid to verify origin and integrity before dyld loads them. In macOS, starting from version 10.10.4, policy restricts linking to external dylibs outside the app bundle or standard system paths (e.g., /usr/lib), rejecting unsigned or mismatched signatures to prevent tampering. On , runtime loading of dynamic libraries is further restricted for security; dyld prohibits arbitrary dlopen calls to unsigned or non-embedded code, confining loading to pre-approved, signed frameworks within the app bundle to mitigate jailbreak exploits and unauthorized . These policies integrate with the hardened runtime, ensuring that library validation occurs during dyld's binding phase.

Other and Historical Implementations

In the 1960s and 1970s, pioneered dynamic linking through its segmented system, allowing procedures and data to be loaded on demand and bound at . The operating system used segmentation to enable direct addressing of information across files and memory, with dynamic linking facilitating references between compilation units via entry points and linkage sections. This approach supported shared procedures and data without requiring full relinking, using indirect calls through linkage segments to resolve bindings dynamically. Early systems like OS/360 introduced dynamic loading concepts via the linkage editor, which processed object modules into load modules while supporting overlays for memory-constrained environments. The Batch Loader (BLDL) allowed on-demand loading of overlay segments during execution, evolving in (Multiple Virtual Storage) to more sophisticated mechanisms. By the time of , this had advanced to Dynamic Link Libraries (DLLs) within the Language Environment, where the and loader handle runtime linking of reusable modules, maintaining compatibility with legacy OS/360 formats. AIX employs the XCOFF (eXtended Common Object File Format) for dynamic linking, utilizing the ld command as a to create modules with a dedicated .loader section. This section includes headers, symbol tables, relocation entries, and import file IDs to specify dependencies on shared libraries, enabling the loader to resolve symbols at . Shared libraries are located via the LIBPATH or paths embedded in the loader section, supporting and deferred binding for efficiency. Files flagged with F_DYNLOAD or F_SHROBJ are designed for , with the (TOC) aiding in external reference resolution. BeOS and its successor Haiku adapted the ELF format for dynamic linking, treating add-ons as loadable modules with standard program headers for code (.text), data (.data), and dynamic sections. Haiku's implementation combines segments into loadable units with specific protection flags (read-execute for code, read-write for data), allowing runtime loading of filesystem drivers and other extensions while maintaining ELF compatibility. This variant supports position-independent execution, though early versions addressed architecture-specific issues like combined read-write-execute permissions on PowerPC. Plan 9 from Bell Labs opted for static linking in its binaries to simplify distribution and avoid runtime dependencies, forgoing traditional dynamic libraries in favor of a unified . While it lacks a conventional dynamic linker, libraries like libthread enable thread creation and management, providing a form of modular loading for concurrent programming without full dynamic symbol resolution.

Efficiency and Optimizations

Performance Techniques

Dynamic linkers incorporate several techniques to mitigate the overhead associated with library loading, symbol resolution, and relocation, focusing on reducing startup and memory usage across diverse systems. These optimizations address the inherent costs of dynamic linking, such as disk I/O for loading shared objects and computational expenses in address adjustments, without compromising core functionality. Preloading shared libraries into memory ahead of time serves as a key strategy to bypass repeated disk accesses for commonly used objects. In , the allows loading specified shared libraries before others, primarily to selectively override functions in other shared objects, though this early loading can have the of reducing I/O for those specific libraries. For broader performance benefits in environments with frequent library reuse, system-wide configurations like /etc/ld.so.preload or the are used to preload or index common libraries, minimizing search and I/O bottlenecks during application startup. Address Space Layout Randomization (ASLR) introduces performance trade-offs by randomizing load addresses to enhance security against exploits, necessitating runtime relocations that increase startup costs. Systems mitigate this through (PIC), which compiles libraries to operate at arbitrary addresses with fewer adjustments, though PIC imposes some runtime overhead on 32-bit architectures. Full ASLR without PIC can elevate relocation expenses significantly on resource-constrained setups. Caching mechanisms accelerate symbol resolution by storing lookup results for subsequent use. symbol caches, exemplified by NetBSD's negative symbol cache, track unresolved symbols to skip futile searches in future loads. In legacy macOS implementations, prebinding fixed library addresses during installation, permitting direct symbol references and reducing launch times by pre-resolving relocations, until invalidated by system updates requiring a full rebind. Performance evaluation of dynamic linking relies on specialized tools to quantify overheads like startup delays from the process. On , traces system calls during library loading, revealing I/O and latencies in heavily linked programs. Apple's Instruments profiler, conversely, instruments dyld operations on macOS to dissect and caching phases, aiding identification of bottlenecks in multi-library environments.

Lazy Binding and Loading

Lazy defers the resolution of external symbols until their first use, in contrast to eager , which resolves all symbols at load time. This approach minimizes initial program startup latency by avoiding unnecessary overhead for symbols that may never be referenced. In ELF-based systems, lazy binding is the default behavior and is implemented using the Procedure Linkage Table (PLT) and Global Offset Table (GOT). The PLT contains stubs for external function calls; on the first invocation, these stubs redirect execution to the dynamic linker, which then resolves the symbol's address and updates the corresponding GOT entry for subsequent direct access. Lazy loading extends this deferral to the libraries themselves, loading shared objects only when explicitly required rather than at program startup. In systems, the dlopen function with the RTLD_LAZY flag enables this by performing lazy binding for symbols within the loaded library, resolving them only as they are executed. Similarly, on Windows, the linker supports delay-loaded DLLs through directives like #pragma(comment(lib, "delayimp.lib")), which postpone loading until a function from the DLL is first called, often using LoadLibrary internally. These mechanisms allow applications to avoid loading infrequently used libraries upfront, reducing and initialization time. The implementation relies on indirect jumps and runtime interception: in ELF, the PLT's initial entries point to the dynamic linker's resolver, which handles symbol lookup via the program's symbol table and updates the GOT atomically to prevent race conditions. While some historical or specialized systems use page faults or signal handlers to trap unresolved references and invoke the linker, modern implementations favor explicit PLT/GOT redirection for predictability and efficiency. This deferred strategy offers significant benefits, such as accelerated program launch times—particularly for large applications with many dependencies—by skipping resolution for unused code paths, thereby improving overall resource utilization. However, it introduces drawbacks, including potential runtime pauses during the first resolution, which can affect performance, and the risk of deferred errors surfacing unpredictably if a cannot be resolved later. A similar principle applies in the (JVM), where class loading and linking occur on-demand during execution, analogous to lazy binding to optimize startup and memory use in dynamic environments.

References

  1. [1]
    A look at dynamic linking - LWN.net
    Feb 13, 2024 · The dynamic linker is a critical component of modern Linux systems, being responsible for setting up the address space of most processes.
  2. [2]
    None
    ### Summary of Shared Libraries in SunOS
  3. [3]
    Mac OS X Manual Page For dyld(3) - Apple Developer
    This document is a Mac OS X manual page. Manual pages are a command-line technology for providing documentation. You can view these manual pages locally using ...
  4. [4]
    Dynamic-Link Libraries (Dynamic-Link Libraries) - Win32 apps
    May 31, 2022 · A dynamic-link library (DLL) is a module that contains functions and data that can be used by another module (application or DLL).
  5. [5]
    Dynamic linking best practices - begriffs.com
    Jul 4, 2021 · The design typically used nowadays for dynamic linking (in BSD, MacOS, and Linux) came from SunOS in 1988. The paper Shared Libraries in SunOS ...
  6. [6]
    Dynamic Linking
    ### Summary of Dynamic Linking from https://refspecs.linuxbase.org/elf/gabi4+/ch5.dynamic.html
  7. [7]
    Dynamic Linking (Linker and Libraries Guide) - Oracle Help Center
    The runtime linker determines the destinations' absolute addresses and modifies the global offset table's memory image accordingly. The runtime linker thus ...Missing: history | Show results with:history
  8. [8]
    [PDF] Lecture 7: The Multics Virtual Memory - Berkeley
    Sep 21, 2005 · Dynamic linking: all references to variables and procedures are resolved late, in fact, when first referenced by the program. • Autonomy of ...
  9. [9]
    [PDF] Slinky: Static Linking Reloaded 1 Introduction - Computer Science
    Static linking has many advantages over dynamic linking. It is simple to understand, implement, and use. It ensures that an executable is self-contained.
  10. [10]
    AIX
    ### Summary of Dynamic Linking in AIX
  11. [11]
    [PDF] CS4414 Recitation 8 - Cornell: Computer Science
    When to use static linking vs. dynamic linking. • Static linking disadvantages. • Duplication in the stored executables. • Duplication in the running ...
  12. [12]
    ld.so(8) - Linux manual page - man7.org
    There are various methods of specifying libraries to be preloaded, and these are handled in the following order: (1) The LD_PRELOAD environment variable. (2) ...
  13. [13]
    [PDF] The inside story on shared libraries and dynamic loading - UCSD CSE
    Sep 2, 2025 · When a static library is included during program linking, the linker makes a pass through the library and adds all the code and data ...Missing: history | Show results with:history
  14. [14]
    Dynamic Section - Linker and Libraries Guide
    This book describes the operations of the Solaris Operating System (Solaris OS) link-editor and runtime linker, and the objects on which these link-editors ...
  15. [15]
    Dynamic Linking - Linux Foundation
    The dynamic linker determines the associated symbol values, calculates their absolute addresses, and sets the GOT entries to the proper values.
  16. [16]
    [PDF] Linking II Systems I
    A weak symbol can be overridden by a strong symbol of the same name. ▫ references to the weak symbol resolve to the strong symbol. Rule 3. If there are multiple ...
  17. [17]
    Runtime Dynamic Linking
    You can force the linker to eagerly resolve symbols on program startup by setting the LD_BIND_NOW environment variable.
  18. [18]
    dlsym(3) - Linux manual page
    ### Summary of dlsym for Manual Symbol Resolution in Dynamic Linking
  19. [19]
    Visibility - GCC Wiki
    Dec 17, 2021 · GCC's visibility feature hides unnecessary ELF symbols, improving load times, enabling better code optimization, and reducing DSO size by 5-20%.
  20. [20]
    Part 1 - Introduction to symbol visibility - IBM Developer
    Jun 12, 2013 · The ELF application binary interface (ABI) defines the visibility of symbols. Generally, it defines four classes, but in most cases, only two ...Ways to control symbol visibility · Defining the visibility attribute...
  21. [21]
    Relocation Processing - Linker and Libraries Guide
    After the runtime linker has loaded all the dependencies required by an application, the linker processes each object and performs all necessary relocations.Relocation Symbol Lookup · Default Symbol Lookup · Runtime Interposition
  22. [22]
    Relocation
    Relocation is the process of connecting symbolic references with symbolic definitions. For example, when a program calls a function, the associated call ...
  23. [23]
    elf(5) - Linux manual page - man7.org
    Relocation types are processor- specific. When the text refers to a relocation entry's relocation type or symbol table index, it means the result of applying ...
  24. [24]
    Position Independent Code (PIC) in shared libraries
    Nov 3, 2011 · This article explained what position independent code is, and how it helps create shared libraries with shareable read-only text sections.
  25. [25]
    Support for Position Independent code - Arm Developer
    Position Independent (PI) code allows an executable to load at a different address than its static link time address, useful for address space randomization.
  26. [26]
    .init, .ctors, and .init_array | MaskRay
    Nov 7, 2021 · The initialization functions or constructors are implemented in two schemes. The legacy one uses .init / .ctors while the new one uses .init_array.
  27. [27]
    Initialization (GNU Compiler Collection (GCC) Internals)
    A section is set aside for a list of constructors, and another for a list of destructors. Traditionally these are called ' .ctors ' and ' .dtors '. Each object ...
  28. [28]
    PE Format - Win32 apps - Microsoft Learn
    Jul 14, 2025 · The PE file header consists of a Microsoft MS-DOS stub, the PE signature, the COFF file header, and an optional header. A COFF object file ...
  29. [29]
    What Goes On Inside Windows 2000: Solving the Mysteries of the ...
    This article explores DLL loading and exposes what really goes on inside the Windows 2000 loader. Knowing how DLLs are loaded and where, and how the loader ...
  30. [30]
    LoadLibraryA function (libloaderapi.h) - Win32 apps - Microsoft Learn
    Feb 9, 2023 · Loads the specified module into the address space of the calling process. The specified module may cause other modules to be loaded.
  31. [31]
    GetProcAddress function (libloaderapi.h) - Win32 - Microsoft Learn
    Feb 6, 2024 · Retrieves the address of an exported function (also known as a procedure) or variable from the specified dynamic-link library (DLL).Missing: ntdll | Show results with:ntdll
  32. [32]
    About Side-by-Side Assemblies - Win32 apps - Microsoft Learn
    Jan 7, 2021 · Manifests contain metadata that describes side-by-side assemblies and side-by-side assembly dependencies.
  33. [33]
    Application manifests - Win32 apps - Microsoft Learn
    May 30, 2024 · An application manifest is an XML file that describes and identifies the shared and private side-by-side assemblies that an application ...
  34. [34]
    What's a Universal Windows Platform (UWP) app? - Microsoft Learn
    Aug 21, 2024 · UWP is a way to create apps for Windows 10/11, using a common API, adapting to different devices, and available on the Microsoft Store.Missing: history | Show results with:history
  35. [35]
  36. [36]
  37. [37]
  38. [38]
    Dynamic Linking (Linker and Libraries Guide) - Oracle Help Center
    Dynamic Linking. This section describes the object file information and system actions that create running programs. Most information here applies to all ...
  39. [39]
  40. [40]
    Overview of Dynamic Libraries - Apple Developer
    Jul 23, 2012 · A static linker collects compiled source code, known as object code, and library code into one executable file that is loaded into memory in its ...
  41. [41]
    dylib_command | Apple Developer Documentation
    Common to all load command structures. For this structure, set to either LC_LOAD_DYLIB , LC_LOAD_WEAK_DYLIB , or LC_ID_DYLIB . cmdsize · dylib · See Also ...
  42. [42]
    Compiling Your Code in OS X - Apple Developer
    Jun 11, 2012 · By default, OS X builds libraries and applications with a two-level namespace. In a two-level namespace environment, when you compile a new ...
  43. [43]
    Xcode 13 Release Notes | Apple Developer Documentation
    There's now only one dyld on all platforms. (69400751). The DriverKit runtime now has a dyld shared cache. (70706923). If the DYLD_PRINT_SEARCHING environment ...
  44. [44]
    Technical Note TN2206: macOS Code Signing In Depth
    Sep 13, 2016 · The purpose of this technote is to provide a more in depth view of code signing. It is intended to expand upon the information given in the Code Signing Guide.
  45. [45]
    [PDF] Virtual Memory, Processes, and Sharing in MULTICS - cs.wisc.edu
    Aug 30, 2000 · KEY WORDS AND PHRASES: virtual memory, information sharing, shared procedures, data sharing, dynamic linking, segmentation, paging, multi-.Missing: MADT master
  46. [46]
    [PDF] IBM System/3S0 Ope"rating System Linkage Editor
    This publication provides programmers and systems analysts with the information necessary to make effective use of the linkage editor of IBM System/360 ...Missing: dynamic BLDL DLLs MVS
  47. [47]
    [PDF] z/OS V1R13.0 MVS Program Management: User's ... - Index of / - IBM
    This book is intended to help you learn about and use the end user interfaces provided by the program management component of z/OS®. Program management.
  48. [48]
    XCOFF Object File Format - IBM
    An XCOFF executable file (or "module") must contain an auxiliary header, a loader section header, and a loader section. The loader raw-data section contains ...
  49. [49]
    Anatomy of an elf - Haiku OS
    Jul 8, 2010 · Normally, loading a Haiku add-on means identifying three program headers from the ELF add-on image: the ones corresponding to the .text (code) ...Missing: BeOS | Show results with:BeOS
  50. [50]
    [PDF] CAIN: Silently Breaking ASLR in the Cloud - USENIX
    On 32 bit x86 systems, PIC still incurs major performance overhead [17], making full ASLR costly. ... These relocation entries instruct the dynamic linker to add ...
  51. [51]
    NetBSD runtime linker gains negative symbol cache
    Feb 27, 2010 · The NetBSD runtime linker now has a negative symbol cache. In a nutshell, this has reduced the startup time of the Evolution mail client ...
  52. [52]
    Mac OS X 10.1 Prebinding Notes - MIT
    When an executable or other dynamic library is built against a prebound library, the linker can directly reference symbols in the prebound library by address, ...
  53. [53]
    [PDF] SYSTEM V APPLICATION BINARY INTERFACE Intel386 ... - SCO
    Mar 19, 1997 · unused symbols do not incur the dynamic linking overhead. Nevertheless, two situations make lazy binding undesirable for some applications.<|control11|><|separator|>
  54. [54]
    Linker support for delay-loaded DLLs | Microsoft Learn
    Aug 3, 2021 · The MSVC linker supports the delayed loading of DLLs. This feature relieves you of the need to use the Windows SDK functions LoadLibrary and GetProcAddress to ...