Gain access to an executable object file
#include <dlfcn.h> void * dlopen( const char * pathname, int mode );
The following bits are Unix extensions:
The following bits are QNX Neutrino extensions:
For more information, see “The mode,” below.
Use the -l c option to qcc to link against this library. This library is usually included automatically.
The dlopen() function gives you direct access to the dynamic linking facilities by making the executable object file specified in pathname available to the calling process. It returns a handle that you can use in subsequent calls to dlsym() and dlclose().
|The dlopen() function is available only to a dynamically-linked process.
A statically-linked process (one where libc is linked statically) can't
call dlopen() because a statically-linked executable:
Any dependencies recorded within pathname are loaded as part of the dlopen() call. These dependencies are searched in load-order to locate any additional dependencies. This process continues until all of the dependencies for pathname have been satisfied. This dependency tree is called a group.
If pathname is NULL, dlopen() provides a handle to the running process's global symbol object. This provides access to the symbols from the original program image file, the dependencies it loaded at startup, plus any objects opened with dlopen() calls using the RTLD_GLOBAL flag. This set of symbols can change dynamically if the application subsequently calls dlopen() using RTLD_GLOBAL.
You can use dlopen() any number of times to open objects whose names resolve to the same absolute or relative path name; the object is loaded into the process's address space only once.
In order to find the shared objects, dlopen() searches the following, in this order:
|For security reasons, the runtime linker ignores the value of LD_LIBRARY_PATH if the binary has the setuid bit set.|
The above directories are set as follows:
setconf _CS_LIBPATH 'getconf _CS_LIBPATH':/new/path
When loading shared objects, the application should open a specific version instead of relying on the version pointed to by a symbolic link.
The mode argument indicates how dlopen() operates on pathname when handling relocations, and controls the visibility of symbols found in pathname and its dependencies.
The mode argument is a bitwise-OR of the constants described below. Note that the relocation and visibility constants are mutually exclusive.
When you load an object by calling dlopen(), the object may contain references to symbols whose addresses aren't known until the object has been loaded; these references must be relocated before accessing the symbols. The mode controls when relocations take place, and can be one of:
The following mode bits determine the scope of visibility for symbols loaded with dlopen():
The program's image and any objects loaded at program startup have a mode of RTLD_GLOBAL; the default mode for objects acquired with dlopen() is RTLD_LOCAL. A local object may be part of the dependencies for more than one group; any object with a RTLD_LOCAL mode referenced as a dependency of an object with a RTLD_GLOBAL mode is promoted to RTLD_GLOBAL.
Objects loaded with dlopen() that require relocations against global symbols can reference the symbols in any RTLD_GLOBAL object.
You can OR the mode with the following values to affect the symbol scope:
If you don't specify either of these values, dlopen() uses RTLD_WORLD | RTLD_GROUP.
|If you specify RTLD_WORLD without RTLD_GROUP, dlopen() doesn't load any of the DLL's dependencies.|
The following flags provide additional capabilities:
When resolving the symbols in the shared object, the runtime linker searches for them in the dynamic symbol table using the following order:
|For security reasons, the runtime linker ignores the value of LD_PRELOAD if the binary has the setuid bit set.|
For executables, the dynamic symbol table typically contains only those symbols that are known to be needed by any shared libraries. This is determined by the linker when the executable is linked against a shared library.
Since you don't link your executable against a shared object that you load with dlopen(), the linker can't determine which executable symbols need to be made available to the shared object.
If your shared object needs to resolve symbols in the executable, then you may force the linker to make all of the symbols in the executable available for dynamic linking by specifying the -E linker option. For example:
qcc -Vgcc_ntox86 -Wl,-E -o main main.o
Shared objects always place all their symbols in dynamic symbol tables, so this option isn't needed when linking a shared object.
A handle to the object, or NULL if an error occurs.
|Don't interpret the value of this handle in any way. For example, if you open the same object repeatedly, don't assume that dlopen() returns the same handle.|
If an error occurs, more detailed diagnostic information is available from dlerror().
|For security reasons, the runtime linker unsets LD_DEBUG_OUTPUT and ignores the value of LD_LIBRARY_PATH and LD_PRELOAD if the binary has the setuid bit set.|
A value of 1 (one) is the same as all.
POSIX 1003.1 XSI
Some symbols defined in executables or shared objects might not be available to the runtime linker. The symbol table created by ld for use by the runtime linker might contain a subset of the symbols defined in the object.
dladdr(), dlclose(), dlerror(), dlsym()
ld, qcc in the Utilities Reference
“Dynamic Linking” chapter of the System Architecture guide
“Lazy loading” in the “Compiling and Debugging” chapter of the QNX Neutrino Programmer's Guide