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.