Shared library

Last updated

A shared library is a computer file that contains executable code designed to be used by multiple computer programs or other libraries at runtime.

Contents

Library types

A program that is configured to use a library can use either static-linking or dynamic-linking. Historically, libraries could only be static. [1] For static-linking (.lib), the library is effectively embedded into the programs executable file, while for dynamic-linking the library can be loaded at runtime from a shared location, such as system files.

A program requires a compiler and linker step to access a library. In static-linking, those references are fully resolved at compile-time, [2] whereas in dynamic-linking those references are not fully resolved until runtime by the operating system.

Formats

Many modern operating systems now use a unified format for their shared libraries and executable files. For example:

This offers two main advantages: first, it requires only one loader (building and maintaining a single loader is considered well worth any added complexity). Secondly, it allows an executable file to be used as a shared library (if it has a symbol table).[ citation needed ]

In some older environments such as 16-bit Windows or MPE for the HP 3000, significant restrictions were placed on shared library code, such as only allowing stack-based (local) data.[ citation needed ]

Memory sharing

Library code may be shared in memory by multiple processes, and on disk. If virtual memory is used, processes would execute the same physical page of RAM that is mapped into the different address spaces of the processes. This has advantages. For instance, on the OpenStep system, applications were often only a few hundred kilobytes in size and loaded quickly; most of their code was located in libraries that had already been loaded for other purposes by the operating system.[ citation needed ]

Programs can accomplish RAM sharing by using position-independent code, as in Unix, which leads to a complex but flexible architecture, or by using common virtual addresses, as in Windows and OS/2. These systems ensure, by various means, like pre-mapping the address space and reserving slots for each shared library, that code has a high probability of being shared. A third alternative is single-level store with a single address space, as used by the IBM System/38 and its successors. This allows position-dependent code, with programs and libraries assigned a permanent address in that address space.

In some cases, different versions of shared libraries can cause problems, especially when libraries of different versions have the same file name, and different applications installed on a system each require a specific version. Such a scenario is known as DLL hell, named after the Windows and OS/2 DLL file. Most modern operating systems after 2001 have clean-up methods to eliminate such situations or use application-specific "private" libraries. [3]

Dynamic linking

Dynamic linking or late binding is linking performed while a program is being loaded (load time) or executed (runtime), rather than when the executable file is created. A dynamically linked library (dynamic-link library, or DLL, under Windows and OS/2; shareable image under OpenVMS; [4] dynamic shared object, or DSO, under Unix-like systems) is a library intended for dynamic linking. Only a minimal amount of work is done by the linker when the executable file is created; it only records what library routines the program needs and the index names or numbers of the routines in the library. The majority of the work of linking is done at the time the application is loaded (load time) or during execution (runtime). Usually, the necessary linking program, called a dynamic linker or linking loader, is actually part of the underlying operating system. (However, it is possible, and not exceedingly difficult, to write a program that uses dynamic linking and includes its own dynamic linker, even for an operating system that itself provides no support for dynamic linking.)

Programmers originally developed dynamic linking in the Multics operating system, starting in 1964, and the MTS (Michigan Terminal System), built in the late 1960s. [5]

Optimizations

Since shared libraries on most systems do not change often, systems can compute a likely load address for each shared library on the system before it is needed and store that information in the libraries and executables. If every shared library that is loaded has undergone this process, then each will load at its predetermined address, which speeds up the process of dynamic linking. This optimization is known as prebinding or prelinking on macOS and Linux, respectively. IBM z/VM uses a similar technique, called "Discontinuous Saved Segments" (DCSS). [6] Disadvantages of this technique include the time required to precompute these addresses every time the shared libraries change, the inability to use address space layout randomization, and the requirement of sufficient virtual address space for use (a problem that will be alleviated by the adoption of 64-bit architectures, at least for the time being).

Locating libraries at runtime

Loaders for shared libraries vary widely in functionality. Some depend on the executable storing explicit paths to the libraries. Any change to the library naming or layout of the file system will cause these systems to fail. More commonly, only the name of the library (and not the path) is stored in the executable, with the operating system supplying a method to find the library on disk, based on some algorithm.

If a shared library that an executable depends on is deleted, moved, or renamed, or if an incompatible version of the library is copied to a place that is earlier in the search, the executable would fail to load. This is called dependency hell , existing on many platforms. The (infamous) Windows variant is commonly known as DLL hell. This problem cannot occur if each version of each library is uniquely identified and each program references libraries only by their full unique identifiers. The "DLL hell" problems with earlier Windows versions arose from using only the names of libraries, which were not guaranteed to be unique, to resolve dynamic links in programs. (To avoid "DLL hell", later versions of Windows rely largely on options for programs to install private DLLsessentially a partial retreat from the use of shared librariesalong with mechanisms to prevent replacement of shared system DLLs with earlier versions of them.)

Microsoft Windows

Microsoft Windows checks the registry to determine the proper place to load DLLs that implement COM objects, but for other DLLs it will check the directories in a defined order. First, Windows checks the directory where it loaded the program (private DLL [3] ); any directories set by calling the SetDllDirectory() function; the System32, System, and Windows directories; then the current working directory; and finally the directories specified by the PATH environment variable. [7] Applications written for the .NET Framework (since 2002), also check the Global Assembly Cache as the primary store of shared dll files to remove the issue of DLL hell.

OpenStep

OpenStep used a more flexible system, collecting a list of libraries from a number of known locations (similar to the PATH concept) when the system first starts. Moving libraries around causes no problems at all, although users incur a time cost when first starting the system.

Unix-like systems

Most Unix-like systems have a "search path" specifying file-system directories in which to look for dynamic libraries. Some systems specify the default path in a configuration file, others hard-code it into the dynamic loader. Some executable file formats can specify additional directories in which to search for libraries for a particular program. This can usually be overridden with an environment variable, although it is disabled for setuid and setgid programs, so that a user can't force such a program to run arbitrary code with root permissions. Developers of libraries are encouraged to place their dynamic libraries in places in the default search path. On the downside, this can make installation of new libraries problematic, and these "known" locations quickly become home to an increasing number of library files, making management more complex.

Dynamic loading

Dynamic loading, a subset of dynamic linking, involves a dynamically linked library loading and unloading at runtime on request. Such a request may be made implicitly or explicitly. Implicit requests are made when a compiler or static linker adds library references that include file paths or simply file names.[ citation needed ] Explicit requests are made when applications make direct calls to an operating system's API.

Most operating systems that support dynamically linked libraries also support dynamically loading such libraries via a run-time linker API. For instance, Microsoft Windows uses the API functions LoadLibrary, LoadLibraryEx, FreeLibrary and GetProcAddress with Microsoft Dynamic Link Libraries; POSIX-based systems, including most UNIX and UNIX-like systems, use dlopen, dlclose and dlsym. Some development systems automate this process.

Notes

    See also

    Related Research Articles

    <span class="mw-page-title-main">Linker (computing)</span> Program that combines intermediate build files into an executable file

    A linker or link editor is a computer program that combines intermediate software build files such as object and library files into a single executable file such a program or library. A linker is often part of a toolchain that includes a compiler and/or assembler that generates intermediate files that the linker processes. The linker may be integrated with other toolchain tools such that the user does not interact with the linker directly.

    DLL hell is an umbrella term for the complications that arise when one works with dynamic-link libraries (DLLs) used with older Microsoft Windows operating systems, particularly legacy 16-bit editions, which all run in a single memory space. DLL hell can appear in many different ways, wherein affected programs may fail to run correctly, if at all. It is the Windows ecosystem-specific form of the general concept dependency hell.

    The Portable Executable (PE) format is a file format for executables, object code, dynamic-link-libraries (DLLs), and binary files used on 32-bit and 64-bit Windows operating systems, as well as in UEFI environments. It is the standard format for executables on Windows NT-based systems, including files such as .exe, .dll, .sys, and .mui. At its core, the PE format is a structured data container that gives the Windows operating system loader everything it needs to properly manage the executable code it contains. This includes references for dynamically linked libraries, tables for importing and exporting APIs, resource management data and thread-local storage (TLS) information.

    <span class="mw-page-title-main">Library (computing)</span> Collection of resources used to develop a computer program

    In computing, a library is a collection of resources that is leveraged during software development to implement a computer program. Commonly, a library consists of executable code such as compiled functions and classes, or a library can be a collection of source code. A resource library may contain data such as images and text.

    An object file is a file that contains machine code or bytecode, as well as other data and metadata, generated by a compiler or assembler from source code during the compilation or assembly process. The machine code that is generated is known as object code.

    <span class="mw-page-title-main">MinGW</span> Free and open-source software for developing applications in Microsoft Windows

    MinGW, formerly mingw32, is a free and open source software development environment to create Microsoft Windows applications.

    In computer systems a loader is the part of an operating system that is responsible for loading programs and libraries. It is one of the essential stages in the process of starting a program, as it places programs into memory and prepares them for execution. Loading a program involves either memory-mapping or copying the contents of the executable file containing the program instructions into memory, and then carrying out other required preparatory tasks to prepare the executable for running. Once loading is complete, the operating system starts the program by passing control to the loaded program code.

    In computing, position-independent code (PIC) or position-independent executable (PIE) is a body of machine code that executes properly regardless of its memory address. PIC is commonly used for shared libraries, so that the same library code can be loaded at a location in each program's address space where it does not overlap with other memory in use by, for example, other shared libraries. PIC was also used on older computer systems that lacked an MMU, so that the operating system could keep applications away from each other even within the single address space of an MMU-less system.

    Dependency hell is a colloquial term for the frustration of some software users who have installed software packages which have dependencies on specific versions of other software packages.

    A static library or statically linked library contains functions and data that can be included in a consuming computer program at build-time such that the library does not need to be accessible in a separate file at run-time. If all libraries are statically linked, then the resulting executable will be stand-alone, a.k.a. a static build.

    A dynamic-link library (DLL) is a shared library in the Microsoft Windows or OS/2 operating system. A DLL can contain executable code (functions), data, and resources.

    In computer programming, the term hooking covers a range of techniques used to alter or augment the behaviour of an operating system, of applications, or of other software components by intercepting function calls or messages or events passed between software components. Code that handles such intercepted function calls, events or messages is called a hook.

    A dynamic library is a library that contains functions and data that can be consumed by a computer program at run-time as loaded from a file separate from the program executable. Dynamic linking or late binding allows for using a dynamic library by linking program library references with the associated objects in the library either at load-time or run-time. At program build-time, the linker records what library objects the program uses. When the program is run, a dynamic linker or linking loader associates program library references with the associated objects in the library.

    In computing, a dynamic linker is the part of an operating system that loads and links the shared libraries needed by an executable when it is executed, by copying the content of libraries from persistent storage to RAM, filling jump tables and relocating pointers. The specific operating system and executable format determine how the dynamic linker functions and how it is implemented.

    ntoskrnl.exe, also known as the kernel image, contains the kernel and executive layers of the Microsoft Windows NT kernel, and is responsible for hardware abstraction, process handling, and memory management. In addition to the kernel and executive layers, it contains the cache manager, security reference monitor, memory manager, scheduler (Dispatcher), and blue screen of death.

    In computer programming, DLL injection is a technique used for running code within the address space of another process by forcing it to load a dynamic-link library. DLL injection is often used by external programs to influence the behavior of another program in a way its authors did not anticipate or intend. For example, the injected code could hook system function calls, or read the contents of password textboxes, which cannot be done the usual way. A program used to inject arbitrary code into arbitrary processes is called a DLL injector.

    The Microsoft Windows operating system and Microsoft Windows SDK support a collection of shared libraries that software can use to access the Windows API. This article provides an overview of the core libraries that are included with every modern Windows installation, on top of which most Windows applications are built.

    A memory-mapped file is a segment of virtual memory that has been assigned a direct byte-for-byte correlation with some portion of a file or file-like resource. This resource is typically a file that is physically present on disk, but can also be a device, shared memory object, or other resource that an operating system can reference through a file descriptor. Once present, this correlation between the file and the memory space permits applications to treat the mapped portion as if it were primary memory.

    Dynamic loading is a mechanism by which a computer program can, at run time, load a library into memory, retrieve the addresses of functions and variables contained in the library, execute those functions or access those variables, and unload the library from memory. It is one of the three mechanisms by which a computer program can use some other software within the program; the others are static linking and dynamic linking. Unlike static linking and dynamic linking, dynamic loading allows a computer program to start up in the absence of these libraries, to discover available libraries, and to potentially gain additional functionality.

    Side-by-side assembly technology is a standard for executable files in Windows 98 Second Edition, Windows 2000, and later versions of Windows that attempts to alleviate problems that arise from the use of dynamic-link libraries (DLLs) in Microsoft Windows. Such problems include version conflicts, missing DLLs, duplicate DLLs, and incorrect or missing registration. In side-by-side, Windows stores multiple versions of a DLL in the %systemroot%\WinSxS directory, and loads them on demand. This reduces dependency problems for applications that include a side-by-side manifest.

    References

    1. "Difference between Static and Shared libraries". GeeksforGeeks. 2018-10-25. Retrieved 2025-02-02.
    2. Microsoft (2021-10-29). "Walkthrough: Create and use a static library (C++)". learn.microsoft.com. Retrieved 2025-02-01. Using a static library is a great way to reuse code. Rather than reimplementing the same routines in every app that requires the functionality, you write them one time in a static library and then reference it from the apps. Code linked from a static library becomes part of your app—you don't have to install another file to use the code.
    3. 1 2 Anderson, Rick (2000-01-11). "The End of DLL Hell". microsoft.com. Archived from the original on 2001-06-05. Retrieved 2012-01-15. Private DLLs are DLLs that are installed with a specific application and used only by that application.
    4. "VSI OpenVMS Linker Utility Manual" (PDF). VSI. August 2019. Retrieved 2021-01-31.
    5. "A History of MTS". Information Technology Digest. 5 (5).
    6. IBM Corporation (2011). Saved Segments Planning and Administration (PDF). Retrieved Jan 29, 2022.
    7. "Dynamic-Link Library Search Order". Microsoft Developer Network Library. Microsoft. 2012-03-06. Archived from the original on 9 May 2012. Retrieved 2012-05-20.

    Sources