.\" Modified by Walter Harms: dladdr, dlvsym
.\" Modified by Petr Baudis <pasky@suse.cz>, 2008-12-04: dladdr caveat
.\"
-.TH DLOPEN 3 2015-12-28 "Linux" "Linux Programmer's Manual"
+.TH DLOPEN 3 2017-09-15 "Linux" "Linux Programmer's Manual"
.SH NAME
dlclose, dlopen, dlmopen \-
open and close a shared object
.SH SYNOPSIS
.B #include <dlfcn.h>
-.sp
+.PP
.BI "void *dlopen(const char *" filename ", int " flags );
-.sp
+.PP
.BI "int dlclose(void *" handle );
-.sp
+.PP
.B #define _GNU_SOURCE
.br
.B #include <dlfcn.h>
-.sp
+.PP
.BI "void *dlmopen (Lmid_t " lmid ", const char *" filename ", int " flags );
-.sp
+.PP
Link with \fI\-ldl\fP.
.SH DESCRIPTION
.SS dlopen()
.BR dlinfo (3),
and
.BR dlclose ().
-
+.PP
If
.I filename
.\" FIXME On Solaris, when handle is NULL, we seem to get back
.TP
.B RTLD_LAZY
Perform lazy binding.
-Only resolve symbols as the code that references them is executed.
+Resolve symbols only as the code that references them is executed.
If the symbol is never referenced, then it is never resolved.
(Lazy binding is performed only for function references;
references to variables are always immediately bound when
.BR RTLD_NODELETE " (since glibc 2.2)"
Do not unload the shared object during
.BR dlclose ().
-Consequently, the object's static variables are not reinitialized
+Consequently, the object's static and global variables are not reinitialized
if the object is reloaded with
.BR dlopen ()
at a later time.
with the flag
.BR RTLD_GLOBAL .
.PP
-External references in the shared object are resolved using the
-shared objects in that object's dependency list and any other
-objects previously opened with the
-.B 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 shared object.
+Symbol references in the shared object are resolved using (in order):
+symbols in the link map of objects loaded for the main program and its
+dependencies;
+symbols in shared objects (and their dependencies)
+that were previously opened with
+.BR dlopen ()
+using the
+.BR RTLD_GLOBAL
+flag;
+and definitions in the shared object itself
+(and any dependencies that were loaded for that object).
+.PP
+Any global symbols in the executable that were placed into
+its dynamic symbol table by
+.BR ld (1)
+can also be used to resolve references in a dynamically loaded shared object.
+Symbols may be placed in the dynamic symbol table
+either because the executable was linked with the flag "\-rdynamic"
+(or, synonymously, "\-\-export\-dynamic"), which causes all of
+the executable's global symbols to be placed in the dynamic symbol table,
+or because
+.BR ld (1)
+noted a dependency on a symbol in another object during static linking.
.PP
-If the same shared object is loaded again with
+If the same shared object is opened again with
.BR dlopen (),
the same object handle is returned.
The dynamic linker maintains reference
has been called on it as many times as
.BR dlopen ()
has succeeded on it.
-Any initialization returns (see below) are called just once.
-However, a subsequent
+Constructors (see below) are called only when the object is actually loaded
+into memory (i.e., when the reference count increases to 1).
+.PP
+A subsequent
.BR dlopen ()
call that loads the same shared object with
.B RTLD_NOW
may force symbol resolution for a shared object earlier loaded with
.BR RTLD_LAZY .
+Similarly, an object that was previously opened with
+.BR RTLD_LOCAL
+can be promoted to
+.BR RTLD_GLOBAL
+in a subsequent
+.BR dlopen ().
.PP
If
.BR dlopen ()
.I flags
arguments, as well as the return value, are the same,
except for the differences noted below.
-
+.PP
The
.BR dlmopen ()
function differs from
The
.I Lmid_t
type is an opaque handle that refers to a namespace.
-
+.PP
The
.I lmid
argument is either the ID of an existing namespace
decrements the reference count on the
dynamically loaded shared object referred to by
.IR handle .
-If the reference count drops to zero,
-then the object is unloaded.
+.PP
+If the object's reference count drops to zero
+and no symbols in this object are required by other objects,
+then the object is unloaded
+after first calling any destructors defined for the object.
+(Symbols in this object might be required in another object
+because this object was opened with the
+.BR RTLD_GLOBAL
+flag and one of its symbols satisfied a relocation in another object.)
+.PP
All shared objects that were automatically loaded when
.BR dlopen ()
was invoked on the object referred to by
.I handle
are recursively closed in the same manner.
-
+.PP
A successful return from
.BR dlclose ()
does not guarantee that the symbols associated with
.BR dlopen ()
and
.BR dlmopen ()
-return a non-NULL handle for the loaded library.
+return a non-NULL handle for the loaded object.
On error
(file could not be found, was not readable, had the wrong format,
or caused errors during loading),
these functions return NULL.
-
+.PP
On success,
.BR dlclose ()
returns 0; on error, it returns a nonzero value.
-
+.PP
Errors from these functions can be diagnosed using
.BR dlerror (3).
.SH VERSIONS
The
.BR dlmopen ()
function is a GNU extension.
-
+.PP
The
.BR RTLD_NOLOAD ,
.BR RTLD_NODELETE ,
and symbol references are likewise resolved according to the usual rules,
but such resolution is confined to the definitions provided by the
objects that have been (explicitly and implicitly) loaded into the namespace.
-
+.PP
The
.BR dlmopen ()
function permits object-load isolation\(emthe ability
This can be achieved by using a separate namespace and the
.B RTLD_GLOBAL
flag.
-
+.PP
The
.BR dlmopen ()
function also can be used to provide better isolation than the
.BR RTLD_LOCAL
is insufficient to isolate a loaded shared object except in the (uncommon)
case where one has explicit control over all shared object dependencies.
-
+.PP
Possible uses of
.BR dlmopen ()
are plugins where the author of the plugin-loading framework
.BR dlmopen (),
this can be achieved by loading the same shared object file into
different namespaces.
-
+.PP
The glibc implementation supports a maximum of
.\" DL_NNS
16 namespaces.
info pages (under "Function attributes")
.\" info gcc "C Extensions" "Function attributes"
for further information.
-
+.PP
An older method of (partially) achieving the same result is via the use of
two special symbols recognized by the linker:
.B _init
.BR gcc (1)
.I \-nostartfiles
command-line option.
-.LP
+.PP
Use of
.B _init
and
.\" .\" void _init(void) __attribute__((constructor));
.\" .\" void _fini(void) __attribute__((destructor));
.\"
-
+.PP
Since glibc 2.2.3,
.BR atexit (3)
can be used to register an exit handler that is automatically
.SS History
These functions are part of the dlopen API, derived from SunOS.
.SH BUGS
-As at glibc 2.21, specifying the
+As at glibc 2.24, specifying the
.BR RTLD_GLOBAL
flag when calling
.BR dlmopen ()
.BR cos (3)
function, and prints the cosine of 2.0.
The following is an example of building and running the program:
-
+.PP
.in +4n
-.nf
+.EX
$ \fBcc dlopen_demo.c \-ldl\fP
$ \fB./a.out\fP
\-0.416147
-.fi
+.EE
.in
.SS Program source
-.nf
-
+\&
+.EX
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
dlclose(handle);
exit(EXIT_SUCCESS);
}
-.fi
+.EE
.SH SEE ALSO
.BR ld (1),
.BR ldd (1),
.BR rtld-audit (7),
.BR ld.so (8),
.BR ldconfig (8)
-
+.PP
gcc info pages, ld info pages