Linker and Libraries Guide

Establishing a Namespace

When the runtime linker binds a dynamic executable with its dependencies, a linked list of link-maps is generated to describe the application. The link-map structure describes each object within the application. The link-map structure is defined in /usr/include/sys/link.h. The symbol search mechanism that is required to bind together the objects of an application traverse this list of link-maps. This link-map list is said to provide the namespace for the applications symbol resolution.

The runtime linker is also described by a link-map. This link-map is maintained on a different list from the list of application objects. The runtime linker therefore resides in its own unique namespace, which prevents the application from seeing, or being able to directly access, any services within the runtime linker. An application can therefore only access the runtime linker through the filters provided by libc.so.1, or libdl.so.1.

Two identifiers are defined in /usr/include/link.h to define the application and runtime linker link-map lists.

#define LM_ID_BASE      0     /* application link-map list */
#define LM_ID_LDSO      1     /* runtime linker link-map list */

In addition to these two standard link-map lists, the runtime linker allows the creation of an arbitrary number of additional link-map lists. Each of these additional link-map lists provides a unique namespace. The rtld-audit interface employs its own link-map list on which the audit libraries are maintained. The audit libraries are therefore isolated from the symbol binding requirements of the application. Every rtld-audit support library is assigned a unique new link-map identifier.

An audit library can inspect the application link-map list using dlmopen(3C). When dlmopen() is used with the RTLD_NOLOAD flag, the audit library can query the existence of an object without causing the object to be loaded.