Runtime linker
The runtime linker is invoked when a program that was linked against a shared object is started or when a program requests that a shared object be dynamically loaded. This linker is contained within the ldqnx-64.so library, which is separate from libc.
- If the requested shared library isn't already loaded in memory,
the runtime linker loads it:
- If the shared library name is fully qualified (i.e., begins with a slash), it's loaded directly from the specified location. If it can't be found there, no further searches are performed.
- If it's not a fully qualified pathname, the
linker searches for it as follows:
- If the executable's dynamic
section contains a
DT_RPATH
tag, then the path specified byDT_RPATH
is searched. - If the shared library isn't found, the runtime linker
searches for it in the directories specified by
LD_LIBRARY_PATH.
Note:For security reasons, the runtime linker unsets LD_LIBRARY_PATH if the binary has the setuid bit set.
- If the shared library still isn't found, then the linker searches for the default library search path as specified by the LD_LIBRARY_PATH environment variable to procnto (i.e., the CS_LIBPATH configuration string). If none has been specified, then the default library path is set to the image filesystem's path.
- If the executable's dynamic
section contains a
- Once the requested shared library is found, it's loaded into memory. For ELF shared libraries, this is a very efficient operation: the runtime linker simply needs to use the mmap() call twice to map the two load segments into memory.
- The shared library is then added to the internal list of all libraries that the process has loaded. The runtime linker maintains this list.
- The runtime linker then decodes the dynamic section of the shared object.
This dynamic section provides information to the linker
about other libraries that this library was linked against. It also
gives information about the relocations that need to be
applied and the external symbols that need to be resolved.
The runtime linker will first load any other required shared libraries
(which may themselves reference other shared libraries). It will then
process the relocations for each library. Some of these
relocations are local to the library, while others require
the runtime linker to resolve a global symbol. In the latter
case, the linker will search through the list of
libraries for this symbol. In ELF files, hash tables are
used for the symbol lookup, so they're very fast. The order
in which libraries are searched for symbols is very
important, as we'll see in the section on
Symbol name resolution
below.
Once all relocations have been applied, any initialization functions that have been registered in the shared library's init section are called. This is used in some implementations of C++ to call global constructors.