Dynamic Link library support for the Linux OS.

David Engel
Eric Youngdale
Peter Macdonald
Hongjiu Lu
Mitch D'Souza
Michael Deutschmann (this documentation)


The ld.so suite contains special files and utilities needed for linux to handle dynamic libraries.

Ordinary static libraries (`lib*.a' files) are included into executables that use their functions. A file that only uses static libraries needs less intelligence to load, but takes up more space. If many executables use the same library, there can be much wastage of storage space, since multiple copies of the library functions are scattered across the executables. However, static libraries are easier to make.

Dynamic libraries (`lib*.so*' files) are not copied into executables --- the executable is written in such a way that it will automatically load the libraries. In linux, the executable will first load the special library ld.so or ld-linux.so, which contains the intelligence to load further dynamic libraries. Since multiple files end up getting executable data from the same file, dynamic libraries are also known as shared libraries.

Linux executables come in two flavors, ELF and a.out.

a.out is the original executable format used by Linux. It has somewhat less overhead than ELF. However creating shared libraries for a.out is very involved, and each a.out shared library must be explicitly registered. ELF is a more recent format, which supports a much simpler method of creating libraries. ELF libraries may also be linked manually (see section User dynamic linking library).

Since many library authors prefer ELF and no longer release shared a.out libraries, a.out is moribund on Linux. This version of the ld.so can be compiled to support only ELF, or to support both formats. (The last release of ld.so to support a.out alone was 1.8.0.)

ld.so: Dynamic linker core

ld.so works behind the scenes to handle dynamic libraries in Linux. Users will almost never have to deal with it directly, but in special cases one can send instructions to it through environment variables. Also, if something is wrong with your libraries (usually an incorrect version) ld.so will give error messages.

Actually ld.so is the a.out linker. The new ELF executables are handled by a related program ld-linux.so.

Configuration Files

A file created by ldconfig and used to speed linking. It's structure is private to the suite.
A simple list of directories to scan for libraries, in addition to `/usr/lib' and `/lib', which are hardwired. It may contain comments started with a `#'.
A list of libraries to preload. This allows preloading libraries for setuid/setgid executables securely. It may contain comments.

Environment Variables

These variables supply a library path for finding dynamic libraries, in the standard colon seperated format. These variables are ignored when executing setuid/setgid programs, because otherwise they would be a security hazard. ld.so will use LD_AOUT_LIBRARY_PATH and ld-linux.so will use LD_LIBRARY_PATH.
These variables allow an extra library not specified in the executable to be loaded. Generally this is only useful if you want to override a function. These are also ignored when running setuid/setgid executables. ld.so will use LD_AOUT_PRELOAD and ld-linux.so will use LD_PRELOAD.
If non-empty, errors about incompatible minor revisions are suppressed.
If non-empty, allow executables to specify absolute library names. This option is deprecated.


`Can't find library library'
The executable required a dynamically linked library that ld.so cannot find. Your symbolic links may be not set right, or you may have not installed a library needed by the program.
`Can't load library library'
The library is corrupt.
`Incompatible library library'
`Require major version x and found y'
Your version of the library is incompatible with the executable. Recompiling the executable, or upgrading the library will fix the problem.
`using incompatible library library'
`Desire minor version >= x and found y.'
Your version of the library is older than that expected by the executable, but not so old that the library interface has radically changed, so the linker will attempt to run anyway. There is a chance that it will work, but you should upgrade the library or recompile the software. The environment variable LD_NOWARN can be used to supress this message.
`too many directories in library path'
The linker only supports up to 32 library directories. You have too many.
`dynamic linker error in blah'
The linker is having trouble handling a binary - it is probably corrupt.
`can't map cache file cache-file'
`cache file cache-file blah'
The linker cache file (generally `/etc/ld.so.cache') is corrupt or non-existent. These errors can be ignored, and can be prevented by regenerating the cache file with ldconfig.

ldd: Dependency scanner

ldd is a utility that prints out the dynamic libraries that an executable is linked to.

Actually ldd works by signalling ld.so to print the dependencies. For a.out executables this is done by starting the executable with argc equal to 0. The linker detects this and prints the dependencies. (This can cause problems with very old binaries, which would run as normal only with an inappropriate argc.)

For ELF executables, special environment variables are used to tell the linker to print the dependencies.

ldd has a few options:

Print the version number of ldd itself
Print the version number of the dynamic linker
Report missing functions. This is only supported for ELF executables.
Report missing objects. This is also only available for ELF executables.

ldconfig: Setup program

This utility is used by the system administrator to automatically set up symbolic links needed by the libraries, and also to set up the cache file.

ldconfig is run after new dynamic libraries are installed, and if the cache file or links are damaged. It is also run when upgrading the ld.so suite itself.

The `/lib' and `/usr/lib' directories, and any listed in the file `/etc/ld.so.conf' are scanned by default unless `-n' is used. Additional directories may be specified on the command line.

It has the following options:

Enter debug mode. Implies `-N' and `-X'.
Verbose. Print out links created and directories scanned.
Check directories specified on the commandline only.
Do not regenerate the cache.
Do not rebuild symbolic links.
Set up symbolic links for only libraries presented on the command line.
Print out the library pathnames in the cache file (`/etc/ld.so.cache')

User dynamic linking library

The ld.so package includes a small library of functions (libdl) to allow manual dynamic linking. Normally programs are linked so that dynamic functions and objects are automagically available. These functions allow one to manually load and access a symbol from a library. They are only available for ELF executables.


To access this library, add the flag `-ldl' to your compile command when linking the executable. You also must include the header file dlfcn.h. You may also need the flag `-rdynamic', which enables resolving references in the loaded libraries against your executable.

Generally, you will first use dlopen to open a library. Then you use dlsym one or more times to access symbols. Finally you use dlclose to close the library.

These facilities are most useful for language interpreters that provide access to external libraries. Without libdl, it would be neccessary to link the interpreter executable with any and all external libraries needed by the programs it runs. With libdl, the interpreter only needs to be linked with the libraries it uses itself, and can dynamically load in additional ones if programs need it.


Function: void *dlopen ( const char filename, int flags )

This function opens the dynamic library specified by filename and returns an abstract handle, which can be used in subsequent calls to dlsym. The function will respect the LD_ELF_LIBRARY_PATH and LD_LIBRARY_PATH environment variables.

The following flags can be used with dlopen:

Macro: int RTLD_LAZY
Resolve symbols in the library as they are needed.

Macro: int RTLD_NOW
Resolve all symbols in the library before returning, and fail if not all can be resolved. This is mutually exclusive with RTLD_LAZY.

Macro: int RTLD_GLOBAL
Make symbols in this library available for resolving symbols in other libraries loaded with dlopen.

Function: int dlclose ( void *handle )

This function releases a library handle.

Note that if a library opened twice, the handle will be the same. However, a reference count is used, so you should still close the library as many times as you open it.

Function: void *dlsym (void *handle,char *symbol-name)

This function looks up the name symbol-name in the library and returns it in the void pointer.

If there is an error, a null pointer will be returned. However, it is possible for a valid name in the library to have a null value, so dlerror should be used to check if there was an error.

Function: libdl function const char *dlerror( void )

This function is used to read the error state. It returns a human-readable string describing the last error, or null, meaning no error.

The function resets the error value each time it is called, so the result should be copied into a variable. If the function is called more than once after an error, the second and subsequent calls will return null.

Example program

Here is an example program that prints the cosine of two by manually linking to the math library:

#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char **argv) {
    void *handle;
    double (*cosine)(double);
    char *error;

    handle = dlopen ("/lib/libm.so", RTLD_LAZY);
    if (!handle) {
        fputs (dlerror(), stderr);

    cosine = dlsym(handle, "cos");
    if ((error = dlerror()) != NULL)  {
        fputs(error, stderr);

    printf ("%f\\n", (*cosine)(2.0));

This document was generated on 29 September 1999 using the texi2html translator version 1.51a.