Linker and Libraries Guide

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 using dlopen(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.