The programs ld.so
and ld-linux.so*
find and load the shared
objects (shared libraries) needed by a program, prepare the
program to run, and then run it.
Linux binaries require dynamic linking (linking at run time)
unless the -static
option was given to ld(1) during compilation.
The program ld.so
handles a.out binaries, a binary format used
long ago. The program ld-linux.so*
(/lib/ld-linux.so.1 for
libc5, /lib/ld-linux.so.2 for glibc2) handles binaries that are
in the more modern ELF format. Both programs have the same
behavior, and use the same support files and programs (ldd(1),
ldconfig(8), and /etc/ld.so.conf).
When resolving shared object dependencies, the dynamic linker
first inspects each dependency string to see if it contains a
slash (this can occur if a shared object pathname containing
slashes was specified at link time). If a slash is found, then
the dependency string is interpreted as a (relative or absolute)
pathname, and the shared object is loaded using that pathname.
If a shared object dependency does not contain a slash, then it
is searched for in the following order:
o Using the directories specified in the DT_RPATH dynamic
section attribute of the binary if present and DT_RUNPATH
attribute does not exist. Use of DT_RPATH is deprecated.
o Using the environment variable LD_LIBRARY_PATH
, unless the
executable is being run in secure-execution mode (see below),
in which case this variable is ignored.
o Using the directories specified in the DT_RUNPATH dynamic
section attribute of the binary if present. Such directories
are searched only to find those objects required by DT_NEEDED
(direct dependencies) entries and do not apply to those
objects' children, which must themselves have their own
DT_RUNPATH entries. This is unlike DT_RPATH, which is applied
to searches for all children in the dependency tree.
o From the cache file /etc/ld.so.cache, which contains a
compiled list of candidate shared objects previously found in
the augmented library path. If, however, the binary was
linked with the -z nodeflib
linker option, shared objects in
the default paths are skipped. Shared objects installed in
hardware capability directories (see below) are preferred to
other shared objects.
o In the default path /lib, and then /usr/lib. (On some 64-bit
architectures, the default paths for 64-bit shared objects are
/lib64, and then /usr/lib64.) If the binary was linked with
the -z nodeflib
linker option, this step is skipped.
Dynamic string tokens
In several places, the dynamic linker expands dynamic string
tokens:
o In the environment variables LD_LIBRARY_PATH
, LD_PRELOAD
, and
LD_AUDIT
,
o inside the values of the dynamic section tags DT_NEEDED
,
DT_RPATH
, DT_RUNPATH
, DT_AUDIT
, and DT_DEPAUDIT
of ELF
binaries,
o in the arguments to the ld.so
command line options --audit
,
--library-path
, and --preload
(see below), and
o in the filename arguments to the dlopen(3) and dlmopen(3)
functions.
The substituted tokens are as follows:
$ORIGIN (or equivalently ${ORIGIN})
This expands to the directory containing the program or
shared object. Thus, an application located in
somedir/app could be compiled with
gcc -Wl,-rpath,'$ORIGIN/../lib'
so that it finds an associated shared object in
somedir/lib no matter where somedir is located in the
directory hierarchy. This facilitates the creation of
"turn-key" applications that do not need to be installed
into special directories, but can instead be unpacked into
any directory and still find their own shared objects.
$LIB (or equivalently ${LIB})
This expands to lib or lib64 depending on the architecture
(e.g., on x86-64, it expands to lib64 and on x86-32, it
expands to lib).
$PLATFORM (or equivalently ${PLATFORM})
This expands to a string corresponding to the processor
type of the host system (e.g., "x86_64"). On some
architectures, the Linux kernel doesn't provide a platform
string to the dynamic linker. The value of this string is
taken from the AT_PLATFORM
value in the auxiliary vector
(see getauxval(3)).
Note that the dynamic string tokens have to be quoted properly
when set from a shell, to prevent their expansion as shell or
environment variables.