Oracle® Solaris 11.2 Linkers and Libraries Guide

Exit Print View

Updated: July 2014
 
 

Audit Interface Control Flow

The following sections describe the auditing interface routines and actions an audit library can perform with each interface. The emphasis is on process initialization. These routines are presented in the order they are called in the common case of a global auditor that is provided at process startup.

Auditing interfaces fall into one of two categories, informational, and control.

Informational interfaces provide the audit library information about the executing process, such as object searching, object loading, and symbol bindings. In addition, these interfaces allow the auditor to modify the objects loaded, and to ask for notification of future symbol binding events.

Control interfaces are called to allow the audit library to track the start or end of a phase of activity within the process execution. These interfaces allow the auditor to safely inspect a consistent set of objects, and can even allow new objects to be loaded.

When an auditing library is first loaded, an immediate call is made to the library's la_version() interface. This handshake verifies that the audit library is supportable, and allows the audit library to define the interface version that the library requires from the runtime linker.

An audit library can be established at process startup, either from using LD_AUDIT, or from a local auditing definition within the executable object that starts the process. See Invoking the Auditing Interface. In this scenario, an la_objopen() call, for both the executable object, and the runtime linker, are provided to the audit library.

At this point the process is still in the early stages of construction. The auditor should refrain from performing any actions that might disturb this construction, such as adding additional objects to the process, or exhaustive symbol searches of the process. These actions can result in prematurely loading and relocating objects in an attempt to satisfy a symbol look up.

Dependencies that are immediately loaded at process initialization are each reported to the auditor library's la_objopen() interface. For processes that employ lazy loading, only a few dependencies may be loaded at process initialization. See Lazy Loading of Dynamic Dependencies. Each loaded object is relocated, which results in symbol bindings being established between symbol references and symbol definitions. These bindings are reported to the audit library's la_symbind() interface.

Once all immediate dependencies have been loaded, and relocated, the audit library's la_preinit() interface is called. At this point, the process is still under construction. Threads initialization and initialization routine collection are still pending. However, this interface provides a convenient control point to add additional objects to the initial process.

Once threads initialization is completed, the audit library's la_callinit() interface is called. At this point, all loaded objects are ready to execute, and their initialization routines have been collected and sorted in preparation for execution. See Initialization and Termination Routines. The la_callinit() control point marks the transition to executing application code.

The execution of application code results in function call bindings being established between symbol references and symbol definitions. These bindings are reported to the audit library's la_symbind() and/or la_pltenter() interfaces. With lazy loading, additional objects can be loaded to satisfy symbol references, which are reported to the audit library's la_objopen().

Once all initialization code has been executed, the audit library's la_callentry() interface is called. The la_callentry() control point marks the end of processes initialization, and the transition to the applications entry point, typically start() or main().

As the process continues to execute, more symbol bindings can occur, resulting in la_symbind() and/or la_pltenter() calls. Addition dependencies can be loaded, resulting in la_objopen() calls. New dependencies can also be unloaded, resulting in la_objclose() calls. Any loading or unloading of objects is bound by a pair of la_activity() calls. The first la_activity() hints at the targeted behavior, an object addition or deletion. The second la_activity() indicates that the dependency structure within the process is consistent. Auditors should restrict their inspection of the process to follow a consistent notification.