The four functions dlopen(),
dlsym(), dlclose(), dlerror() implement the interface to the
dynamic linking loader.
dlerror
The function dlerror()
returns a human readable string describing the most recent
error that occurred from dlopen(), dlsym() or dlclose() since the last call to
dlerror(). It returns NULL if
no errors have occurred since initialization or since it
was last called.
dlopen
The function dlopen()
loads the dynamic library file named by the null-terminated
string filename and
returns an opaque "handle" for the dynamic library. If
filename is NULL,
then the returned handle is for the main program. If
filename contains a
slash ("/"), then it is interpreted as a (relative or
absolute) pathname. Otherwise, the dynamic linker searches
for the library as follows (see ld.so(8) for further
details):
(ELF only) If the executable file for the calling
program contains a DT_RPATH tag, and does not contain
a DT_RUNPATH tag, then the directories listed in the
DT_RPATH tag are searched.
If the environment variable LD_LIBRARY_PATH is defined to
contain a colon-separated list of directories, then
these are searched. (As a security measure this
variable is ignored for set-user-ID and set-group-ID
programs.)
(ELF only) If the executable file for the calling
program contains a DT_RUNPATH tag, then the
directories listed in that tag are searched.
The cache file /etc/ld.so.cache (maintained by
ldconfig(8)) is
checked to see whether it contains an entry for
filename.
The directories /lib
and /usr/lib are
searched (in that order).
If the library has dependencies on other shared
libraries, then these are also automatically loaded by the
dynamic linker using the same rules. (This process may
occur recursively, if those libraries in turn have
dependencies, and so on.)
One of the following two values must be included in
flag:
RTLD_LAZY
Perform lazy binding. Only resolve symbols as the
code that references them is executed. If the symbol
is never referenced, then it is never resolved. (Lazy
binding is only performed for function references;
references to variables are always immediately bound
when the library is loaded.)
RTLD_NOW
If this value is specified, or the environment
variable LD_BIND_NOW is
set to a non-empty string, all undefined symbols in
the library are resolved before dlopen() returns. If this cannot be
done, an error is returned.
Zero of more of the following values may also be ORed in
flag:
RTLD_GLOBAL
The symbols defined by this library will be made
available for symbol resolution of subsequently
loaded libraries.
RTLD_LOCAL
This is the converse of RTLD_GLOBAL, and the default if
neither flag is specified. Symbols defined in this
library are not made available to resolve references
in subsequently loaded libraries.
RTLD_NODELETE (since glibc
2.2)
Do not unload the library during dlclose(). Consequently, the
library's static variables are not reinitialised if
the library is reloaded with dlopen() at a later time. This flag
is not specified in POSIX.1-2001.
RTLD_NOLOAD (since glibc
2.2)
Don't load the library. This can be used to test
if the library is already resident (dlopen() returns NULL if it is not,
or the library's handle if it is resident). This flag
can also be used to promote the flags on a library
that is already loaded. For example, a library that
was previously loaded with RTLD_LOCAL can be re-opened with
RTLD_NOLOAD |
RTLD_GLOBAL. This flag is not specified
in POSIX.1-2001.
RTLD_DEEPBIND (since glibc
2.3.4)
Place the lookup scope of the symbols in this
library ahead of the global scope. This means that a
self-contained library will use its own symbols in
preference to global symbols with the same name
contained in libraries that have already been loaded.
This flag is not specified in POSIX.1-2001.
If filename is a
NULL pointer, then the returned handle is for the main
program. When given to dlsym(), this handle causes a search for
a symbol in the main program, followed by all shared
libraries loaded at program startup, and then all shared
libraries loaded by dlopen()
with the flag RTLD_GLOBAL.
External references in the library are resolved using
the libraries in that library's dependency list and any
other libraries previously opened with the RTLD_GLOBAL flag. If the executable was
linked with the flag "−rdynamic" (or, synonymously,
"−−export−dynamic"), then the global
symbols in the executable will also be used to resolve
references in a dynamically loaded library.
If the same library is loaded again with dlopen(), the same file handle is
returned. The dl library maintains reference counts for
library handles, so a dynamic library is not deallocated
until dlclose() has been
called on it as many times as dlopen() has succeeded on it. The
_init routine, if
present, is only called once. But a subsequent call with
RTLD_NOW may force symbol
resolution for a library earlier loaded with RTLD_LAZY.
If dlopen() fails for any
reason, it returns NULL.
dlsym
The function dlsym() takes
a "handle" of a dynamic library returned by dlopen() and the null-terminated symbol
name, returning the address where that symbol is loaded
into memory. If the symbol is not found, in the specified
library or any of the libraries that were automatically
loaded by dlopen() when that
library was loaded, dlsym()
returns NULL. (The search performed by dlsym() is breadth first through the
dependency tree of these libraries.) Since the value of the
symbol could actually be NULL (so that a NULL return from
dlsym() need not indicate an
error), the correct way to test for an error is to call
dlerror() to clear any old
error conditions, then call dlsym(), and then call dlerror() again, saving its return value
into a variable, and check whether this saved value is not
NULL.
There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT. The former will find the first
occurrence of the desired symbol using the default library
search order. The latter will find the next occurrence of a
function in the search order after the current library.
This allows one to provide a wrapper around a function in
another shared library.
dlclose
The function dlclose()
decrements the reference count on the dynamic library
handle handle. If
the reference count drops to zero and no other loaded
libraries use symbols in it, then the dynamic library is
unloaded.
The function dlclose()
returns 0 on success, and non-zero on error.
The obsolete symbols _init and _fini
The linker recognizes special symbols _init and _fini. If a dynamic library
exports a routine named _init, then that code is
executed after the loading, before dlopen() returns. If the dynamic library
exports a routine named _fini, then that routine is
called just before the library is unloaded. In case you
need to avoid linking against the system startup files,
this can be done by giving gcc the "−nostartfiles"
parameter on the command line.
Using these routines, or the gcc −nostartfiles or −nostdlib options, is not
recommended. Their use may result in undesired behavior,
since the constructor/destructor routines will not be
executed (unless special measures are taken).
Instead, libraries should export routines using the
__attribute__((constructor))() and
__attribute__((destructor))()
function attributes. See the gcc info pages for information
on these. Constructor routines are executed before
dlopen() returns, and
destructor routines are executed before dlclose() returns.
Glibc extensions: dladdr() and dlvsym()
Glibc adds two functions not described by POSIX, with
prototypes
Copyright 1995 Yggdrasil Computing, Incorporated.
written by Adam J. Richter (adam@yggdrasil.com),
with typesetting help from Daniel Quinlan (quinlan@yggdrasil.com).
and Copyright 2003 Michael Kerrisk (mtk-manpages@gmx.net).
This is free documentation; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
The GNU General Public License's references to "object code"
and "executables" are to be interpreted as the output of any
document formatting or typesetting system, including
intermediate and printed output.
This manual is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public
License along with this manual; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
USA.
Modified by David A. Wheeler <dwheeler@dwheeler.com> 2000-11-28.
Applied patch by Terran Melconian, aeb, 2001-12-14.
Modified by Hacksaw <hacksaw@hacksaw.org> 2003-03-13.
Modified by Matt Domsch, 2003-04-09: _init and _fini obsolete
Modified by Michael Kerrisk <mtk-manpages@gmx.net> 2003-05-16.
Modified by Walter Harms: dladdr, dlvsym