summaryrefslogtreecommitdiffstats
path: root/man/man3/dlopen.3
diff options
context:
space:
mode:
Diffstat (limited to 'man/man3/dlopen.3')
-rw-r--r--man/man3/dlopen.3624
1 files changed, 624 insertions, 0 deletions
diff --git a/man/man3/dlopen.3 b/man/man3/dlopen.3
new file mode 100644
index 0000000..14f1689
--- /dev/null
+++ b/man/man3/dlopen.3
@@ -0,0 +1,624 @@
+'\" t
+.\" 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, 2015 Michael Kerrisk <mtk.manpages@gmail.com>
+.\"
+.\" SPDX-License-Identifier: GPL-2.0-or-later
+.\"
+.\" 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@gmail.com> 2003-05-16.
+.\" Modified by Walter Harms: dladdr, dlvsym
+.\" Modified by Petr Baudis <pasky@suse.cz>, 2008-12-04: dladdr caveat
+.\"
+.TH dlopen 3 2024-05-02 "Linux man-pages (unreleased)"
+.SH NAME
+dlclose, dlopen, dlmopen \-
+open and close a shared object
+.SH LIBRARY
+Dynamic linking library
+.RI ( libdl ", " \-ldl )
+.SH SYNOPSIS
+.nf
+.B #include <dlfcn.h>
+.P
+.BI "void *dlopen(const char *" filename ", int " flags );
+.BI "int dlclose(void *" handle );
+.P
+.B #define _GNU_SOURCE
+.br
+.B #include <dlfcn.h>
+.P
+.BI "void *dlmopen(Lmid_t " lmid ", const char *" filename ", int " flags );
+.fi
+.SH DESCRIPTION
+.SS dlopen()
+The function
+.BR dlopen ()
+loads the dynamic shared object (shared library)
+file named by the null-terminated
+string
+.I filename
+and returns an opaque "handle" for the loaded object.
+This handle is employed with other functions in the dlopen API, such as
+.BR dlsym (3),
+.BR dladdr (3),
+.BR dlinfo (3),
+and
+.BR dlclose ().
+.P
+If
+.I filename
+.\" FIXME On Solaris, when handle is NULL, we seem to get back
+.\" a handle for (something like) the root of the namespace.
+.\" The point here is that if we do a dlmopen(LM_ID_NEWLM), then
+.\" the filename==NULL case returns a different handle than
+.\" in the initial namespace. But, on glibc, the same handle is
+.\" returned. This is probably a bug in glibc.
+.\"
+is NULL, then the returned handle is for the main program.
+If
+.I filename
+contains a slash ("/"), then it is interpreted as a (relative
+or absolute) pathname.
+Otherwise, the dynamic linker searches for the object as follows
+(see
+.BR ld.so (8)
+for further details):
+.IP \[bu] 3
+(ELF only) If the calling object
+(i.e., the shared library or executable from which
+.BR dlopen ()
+is called)
+contains a DT_RPATH tag, and does not contain a DT_RUNPATH tag,
+then the directories listed in the DT_RPATH tag are searched.
+.IP \[bu]
+If, at the time that the program was started, the environment variable
+.B LD_LIBRARY_PATH
+was 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.)
+.IP \[bu]
+(ELF only) If the calling object
+contains a DT_RUNPATH tag, then the directories listed in that tag
+are searched.
+.IP \[bu]
+The cache file
+.I /etc/ld.so.cache
+(maintained by
+.BR ldconfig (8))
+is checked to see whether it contains an entry for
+.IR filename .
+.IP \[bu]
+The directories
+.I /lib
+and
+.I /usr/lib
+are searched (in that order).
+.P
+If the object specified by
+.I filename
+has dependencies on other shared objects,
+then these are also automatically loaded by the dynamic linker
+using the same rules.
+(This process may occur recursively,
+if those objects in turn have dependencies, and so on.)
+.P
+One of the following two values must be included in
+.IR flags :
+.TP
+.B RTLD_LAZY
+Perform lazy binding.
+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
+the shared object is loaded.)
+Since glibc 2.1.1,
+.\" commit 12b5b6b7f78ea111e89bbf638294a5413c791072
+this flag is overridden by the effect of the
+.B LD_BIND_NOW
+environment variable.
+.TP
+.B RTLD_NOW
+If this value is specified, or the environment variable
+.B LD_BIND_NOW
+is set to a nonempty string,
+all undefined symbols in the shared object are resolved before
+.BR dlopen ()
+returns.
+If this cannot be done, an error is returned.
+.P
+Zero or more of the following values may also be ORed in
+.IR flags :
+.TP
+.B RTLD_GLOBAL
+The symbols defined by this shared object will be
+made available for symbol resolution of subsequently loaded shared objects.
+.TP
+.B RTLD_LOCAL
+This is the converse of
+.BR RTLD_GLOBAL ,
+and the default if neither flag is specified.
+Symbols defined in this shared object are not made available to resolve
+references in subsequently loaded shared objects.
+.TP
+.BR RTLD_NODELETE " (since glibc 2.2)"
+Do not unload the shared object during
+.BR dlclose ().
+Consequently, the object's static and global variables are not reinitialized
+if the object is reloaded with
+.BR dlopen ()
+at a later time.
+.TP
+.BR RTLD_NOLOAD " (since glibc 2.2)"
+Don't load the shared object.
+This can be used to test if the object is already resident
+.RB ( dlopen ()
+returns NULL if it is not, or the object's handle if it is resident).
+This flag can also be used to promote the flags on a shared object
+that is already loaded.
+For example, a shared object that was previously loaded with
+.B RTLD_LOCAL
+can be reopened with
+.BR RTLD_NOLOAD\ |\ RTLD_GLOBAL .
+.\"
+.TP
+.BR RTLD_DEEPBIND " (since glibc 2.3.4)"
+.\" Inimitably described by UD in
+.\" http://sources.redhat.com/ml/libc-hacker/2004-09/msg00083.html.
+Place the lookup scope of the symbols in this
+shared object ahead of the global scope.
+This means that a self-contained object will use
+its own symbols in preference to global symbols with the same name
+contained in objects that have already been loaded.
+.P
+If
+.I filename
+is NULL, then the returned handle is for the main program.
+When given to
+.BR dlsym (3),
+this handle causes a search for a symbol in the main program,
+followed by all shared objects loaded at program startup,
+and then all shared objects loaded by
+.BR dlopen ()
+with the flag
+.BR RTLD_GLOBAL .
+.P
+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
+.B RTLD_GLOBAL
+flag;
+and definitions in the shared object itself
+(and any dependencies that were loaded for that object).
+.P
+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.
+.P
+If the same shared object is opened again with
+.BR dlopen (),
+the same object handle is returned.
+The dynamic linker maintains reference
+counts for object handles, so a dynamically loaded shared object is not
+deallocated until
+.BR dlclose ()
+has been called on it as many times as
+.BR dlopen ()
+has succeeded on it.
+Constructors (see below) are called only when the object is actually loaded
+into memory (i.e., when the reference count increases to 1).
+.P
+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
+.B RTLD_LOCAL
+can be promoted to
+.B RTLD_GLOBAL
+in a subsequent
+.BR dlopen ().
+.P
+If
+.BR dlopen ()
+fails for any reason, it returns NULL.
+.\"
+.SS dlmopen()
+This function performs the same task as
+.BR dlopen ()\[em]the
+.I filename
+and
+.I flags
+arguments, as well as the return value, are the same,
+except for the differences noted below.
+.P
+The
+.BR dlmopen ()
+function differs from
+.BR dlopen ()
+primarily in that it accepts an additional argument,
+.IR lmid ,
+that specifies the link-map list (also referred to as a
+.IR namespace )
+in which the shared object should be loaded.
+(By comparison,
+.BR dlopen ()
+adds the dynamically loaded shared object to the same namespace as
+the shared object from which the
+.BR dlopen ()
+call is made.)
+The
+.I Lmid_t
+type is an opaque handle that refers to a namespace.
+.P
+The
+.I lmid
+argument is either the ID of an existing namespace
+.\" FIXME: Is using dlinfo() RTLD_DI_LMID the right technique?
+(which can be obtained using the
+.BR dlinfo (3)
+.B RTLD_DI_LMID
+request) or one of the following special values:
+.TP
+.B LM_ID_BASE
+Load the shared object in the initial namespace
+(i.e., the application's namespace).
+.TP
+.B LM_ID_NEWLM
+Create a new namespace and load the shared object in that namespace.
+The object must have been correctly linked
+to reference all of the other shared objects that it requires,
+since the new namespace is initially empty.
+.P
+If
+.I filename
+is NULL, then the only permitted value for
+.I lmid
+is
+.BR LM_ID_BASE .
+.SS dlclose()
+The function
+.BR dlclose ()
+decrements the reference count on the
+dynamically loaded shared object referred to by
+.IR handle .
+.P
+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
+.B RTLD_GLOBAL
+flag and one of its symbols satisfied a relocation in another object.)
+.P
+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.
+.P
+A successful return from
+.BR dlclose ()
+does not guarantee that the symbols associated with
+.I handle
+are removed from the caller's address space.
+In addition to references resulting from explicit
+.BR dlopen ()
+calls, a shared object may have been implicitly loaded
+(and reference counted) because of dependencies in other shared objects.
+Only when all references have been released can the shared object
+be removed from the address space.
+.SH RETURN VALUE
+On success,
+.BR dlopen ()
+and
+.BR dlmopen ()
+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.
+.P
+On success,
+.BR dlclose ()
+returns 0; on error, it returns a nonzero value.
+.P
+Errors from these functions can be diagnosed using
+.BR dlerror (3).
+.SH ATTRIBUTES
+For an explanation of the terms used in this section, see
+.BR attributes (7).
+.TS
+allbox;
+lbx lb lb
+l l l.
+Interface Attribute Value
+T{
+.na
+.nh
+.BR dlopen (),
+.BR dlmopen (),
+.BR dlclose ()
+T} Thread safety MT-Safe
+.TE
+.SH STANDARDS
+.TP
+.BR dlopen ()
+.TQ
+.BR dlclose ()
+POSIX.1-2008.
+.TP
+.BR dlmopen ()
+.TQ
+.B RTLD_NOLOAD
+.TQ
+.B RTLD_NODELETE
+GNU.
+.TP
+.B RTLD_DEEPBIND
+Solaris.
+.SH HISTORY
+.TP
+.BR dlopen ()
+.TQ
+.BR dlclose ()
+glibc 2.0.
+POSIX.1-2001.
+.TP
+.BR dlmopen ()
+glibc 2.3.4.
+.SH NOTES
+.SS dlmopen() and namespaces
+A link-map list defines an isolated namespace for the
+resolution of symbols by the dynamic linker.
+Within a namespace,
+dependent shared objects are implicitly loaded according to the usual rules,
+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.
+.P
+The
+.BR dlmopen ()
+function permits object-load isolation\[em]the ability
+to load a shared object in a new namespace without
+exposing the rest of the application to the symbols
+made available by the new object.
+Note that the use of the
+.B RTLD_LOCAL
+flag is not sufficient for this purpose,
+since it prevents a shared object's symbols from being available to
+.I any
+other shared object.
+In some cases,
+we may want to make the symbols provided by a dynamically
+loaded shared object available to (a subset of) other shared objects
+without exposing those symbols to the entire application.
+This can be achieved by using a separate namespace and the
+.B RTLD_GLOBAL
+flag.
+.P
+The
+.BR dlmopen ()
+function also can be used to provide better isolation than the
+.B RTLD_LOCAL
+flag.
+In particular, shared objects loaded with
+.B RTLD_LOCAL
+may be promoted to
+.B RTLD_GLOBAL
+if they are dependencies of another shared object loaded with
+.BR RTLD_GLOBAL .
+Thus,
+.B 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.
+.P
+Possible uses of
+.BR dlmopen ()
+are plugins where the author of the plugin-loading framework
+can't trust the plugin authors and does not wish
+any undefined symbols from the plugin framework to be resolved to plugin
+symbols.
+Another use is to load the same object more than once.
+Without the use of
+.BR dlmopen (),
+this would require the creation of distinct copies of the shared object file.
+Using
+.BR dlmopen (),
+this can be achieved by loading the same shared object file into
+different namespaces.
+.P
+The glibc implementation supports a maximum of
+.\" DL_NNS
+16 namespaces.
+.\"
+.SS Initialization and finalization functions
+Shared objects may export functions using the
+.B __attribute__((constructor))
+and
+.B __attribute__((destructor))
+function attributes.
+Constructor functions are executed before
+.BR dlopen ()
+returns, and destructor functions are executed before
+.BR dlclose ()
+returns.
+A shared object may export multiple constructors and destructors,
+and priorities can be associated with each function
+to determine the order in which they are executed.
+See the
+.B gcc
+info pages (under "Function attributes")
+.\" info gcc "C Extensions" "Function attributes"
+for further information.
+.P
+An older method of (partially) achieving the same result is via the use of
+two special symbols recognized by the linker:
+.B _init
+and
+.BR _fini .
+If a dynamically loaded shared object exports a routine named
+.BR _init (),
+then that code is executed after loading a shared object, before
+.BR dlopen ()
+returns.
+If the shared object exports a routine named
+.BR _fini (),
+then that routine is called just before the object is unloaded.
+In this case, one must avoid linking against the system startup files,
+which contain default versions of these files;
+this can be done by using the
+.BR gcc (1)
+.I \-nostartfiles
+command-line option.
+.P
+Use of
+.B _init
+and
+.B _fini
+is now deprecated in favor of the aforementioned
+constructors and destructors,
+which among other advantages,
+permit multiple initialization and finalization functions to be defined.
+.\"
+.\" Using these routines, or the gcc
+.\" .B \-nostartfiles
+.\" or
+.\" .B \-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).
+.\" .\" void _init(void) __attribute__((constructor));
+.\" .\" void _fini(void) __attribute__((destructor));
+.\"
+.P
+Since glibc 2.2.3,
+.BR atexit (3)
+can be used to register an exit handler that is automatically
+called when a shared object is unloaded.
+.SS History
+These functions are part of the dlopen API, derived from SunOS.
+.SH BUGS
+As at glibc 2.24, specifying the
+.B RTLD_GLOBAL
+flag when calling
+.BR dlmopen ()
+.\" dlerror(): "invalid mode"
+generates an error.
+Furthermore, specifying
+.B RTLD_GLOBAL
+when calling
+.BR dlopen ()
+results in a program crash
+.RB ( SIGSEGV )
+.\" https://sourceware.org/bugzilla/show_bug.cgi?id=18684
+if the call is made from any object loaded in a
+namespace other than the initial namespace.
+.SH EXAMPLES
+The program below loads the (glibc) math library,
+looks up the address of the
+.BR cos (3)
+function, and prints the cosine of 2.0.
+The following is an example of building and running the program:
+.P
+.in +4n
+.EX
+$ \fBcc dlopen_demo.c \-ldl\fP
+$ \fB./a.out\fP
+\-0.416147
+.EE
+.in
+.SS Program source
+\&
+.\" SRC BEGIN (dlopen.c)
+.EX
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+\&
+#include <gnu/lib\-names.h> /* Defines LIBM_SO (which will be a
+ string such as "libm.so.6") */
+int
+main(void)
+{
+ void *handle;
+ double (*cosine)(double);
+ char *error;
+\&
+ handle = dlopen(LIBM_SO, RTLD_LAZY);
+ if (!handle) {
+ fprintf(stderr, "%s\en", dlerror());
+ exit(EXIT_FAILURE);
+ }
+\&
+ dlerror(); /* Clear any existing error */
+\&
+ cosine = (double (*)(double)) dlsym(handle, "cos");
+\&
+ /* According to the ISO C standard, casting between function
+ pointers and \[aq]void *\[aq], as done above, produces undefined results.
+ POSIX.1\-2001 and POSIX.1\-2008 accepted this state of affairs and
+ proposed the following workaround:
+\&
+ *(void **) (&cosine) = dlsym(handle, "cos");
+\&
+ This (clumsy) cast conforms with the ISO C standard and will
+ avoid any compiler warnings.
+\&
+ The 2013 Technical Corrigendum 1 to POSIX.1\-2008 improved matters
+ by requiring that conforming implementations support casting
+ \[aq]void *\[aq] to a function pointer. Nevertheless, some compilers
+ (e.g., gcc with the \[aq]\-pedantic\[aq] option) may complain about the
+ cast used in this program. */
+.\" http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html#tag_03_112_08
+.\" http://pubs.opengroup.org/onlinepubs/9699919799/functions/dlsym.html#tag_16_96_07
+.\" http://austingroupbugs.net/view.php?id=74
+\&
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\en", error);
+ exit(EXIT_FAILURE);
+ }
+\&
+ printf("%f\en", (*cosine)(2.0));
+ dlclose(handle);
+ exit(EXIT_SUCCESS);
+}
+.EE
+.\" SRC END
+.SH SEE ALSO
+.BR ld (1),
+.BR ldd (1),
+.BR pldd (1),
+.BR dl_iterate_phdr (3),
+.BR dladdr (3),
+.BR dlerror (3),
+.BR dlinfo (3),
+.BR dlsym (3),
+.BR rtld\-audit (7),
+.BR ld.so (8),
+.BR ldconfig (8)
+.P
+gcc info pages, ld info pages