SPRAB89A September 2011 – March 2014
Static linking is the traditional process of combining relocatable object files and static libraries into a static link unit: either an ELF executable file (.exe) or and ELF shared object (.so). Within this document, we use the term load module (or simply module) to refer to a static link unit and shared library (or library) to refer to a shared object..
A program consists of exactly one executable file and any additional shared libraries that it depends on to satisfy any undefined references. If multiple executables depend on the same library, they can share a single copy of its code (hence the shared in shared object), thereby significantly reducing the memory requirements of the system.
When such a program consisting of multiple objects is loaded, references between its component modules (some of which may already be loaded as part of other applications) must be resolved. This process is called dynamic linking, and is handled by a run-time component known as the dynamic linker. Because the state of the system varies with respect to which objects are loaded at any given time, the dynamic linker may wish to control their memory allocation and placement dynamically. The ability to assign a program's location and relocate it at load time is sometimes referred to as dynamic loading. Although dynamic linking and dynamic loading are somewhat independent capabilities, in that either may be useful without the other, the mechanisms that enable each are tightly related. In this document we use the term dynamic linking to refer to the composite capability, and the terms dynamic linker and dynamic loader interchangeably to refer to the component that performs these operations.
An object's own functions and variables (collectively called symbols) are those that are defined within it. When a module (executable or library) references a symbol that is undefined within that module but defined in another module, it is said to import that symbol. The defining module is said to export the symbol.
In general, the addresses of a dynamically linked module's code and data are not known at static link time. Furthermore, the addresses of any imported symbols are also unknown, until they are resolved by the dynamic linker. Therefore when the dynamic linker loads a module, it may need to patch its code and/or data according to its assigned address, as well as the addresses of any symbols it imports. Relocations performed at dynamic link time are called dynamic relocations. A design goal of most dynamic linking mechanisms is to minimize the number and complexity of dynamic relocations. Dynamic relocations, and the associated symbolic information, are contained in special sections in the ELF object file.
A fundamental issue with shared libraries is that each executable that shares a library must still have its own private (not shared) copy of the library's data. This implies that shared code cannot use absolute addressing to access data. The term Position Independent Data (PID) applies to code that accesses data in a shareable way, typically via either relative or GOT-based addressing.
The broader term Position Independent Code (PIC) refers to code that does not use absolute addressing in any way, and is therefore independent from both its own placement and that of other load modules. Position independent code requires no load-time patching to the code segment, thereby speeding load time and/or allowing it to be located in ROM. Typical approaches for PIC rely on PC-relative addressing, virtual memory, indirection, and/or relative addressing from a base pointer register, such as the C60's DP (B14).
An additional consideration applies to modules that will be located in ROM. Obviously code in ROM cannot be patched at load time, so it has many similar requirements for position independence.