Loading Additional Objects
Additional objects can be added to a running process's
address space by using
dlopen
(3C). This function takes a path name and
a binding mode as arguments, and returns a handle to the
application. This handle can be used to locate symbols for use by
the application using
dlsym
(3C).
If the path name is specified as a simple file name, one with no '/' in the name, then the runtime linker uses a set of rules to generate an appropriate path name. Path names that contain a '/' are used as provided.
These search path rules are exactly the same as are used to locate any
initial dependencies. See Directories Searched by the Runtime Linker. For example, the
file main.c
contains the following code
fragment.
#include <stdio.h> #include <dlfcn.h> int main(int argc, char **argv) { void *handle; .... if ((handle = dlopen("foo.so.1", RTLD_LAZY)) == NULL) { (void) printf("dlopen: %s\n", dlerror()); return (1); } ....
To locate the shared object
foo.so.1
, the runtime linker uses any
LD_LIBRARY_PATH
definition that is present at
process initialization. Next, the runtime linker uses any
runpath specified during the link-edit of
prog
. Finally, the runtime linker uses
the default locations /lib
and
/usr/lib
for 32-bit objects, or
/lib/64
and
/usr/lib/64
for 64-bit
objects.
If the path name is specified as:
if ((handle = dlopen("./foo.so.1", RTLD_LAZY)) == NULL) {
then the runtime linker searches for the file only in the current working directory of the process.
Note:
Any shared object that is specified usingdlopen
(3C) should be referenced by its
versioned file name. For more
information on versioning, see Coordination of Versioned Filenames.
If the required object cannot be located,
dlopen
(3C) returns a NULL
handle. In this case
dlerror
(3C) can be used to display the true
reason for the failure. For example.
$ cc -o prog main.c $ prog dlopen: ld.so.1: prog: fatal: foo.so.1: open failed: No such file or directory
If the object being added by
dlopen
(3C) has dependencies on other objects,
they too are brought into the process's address space. This process
continues until all the dependencies of the specified object are
loaded. This dependency tree is referred to as a
group.
If the object specified by
dlopen
(3C), or any of its dependencies, are
already part of the process image, then the objects are not
processed any further. A valid handle is returned to the
application. This mechanism prevents the same object from being
loaded more than once, and enables an application to obtain a handle
to itself. For example, from the previous example,
main.c
can contain the following
dlopen
() call.
if ((handle = dlopen(0, RTLD_LAZY)) == NULL) {
The handle returned from this
dlopen
(3C) can be used to locate symbols within
the application itself, within any of the dependencies loaded as
part of the process's initialization, or within any objects added to
the process's address space, using a
dlopen
(3C) that specified the
RTLD_GLOBAL
flag.