An audit library is built like any other shared object; however, its unique name-space within a process requires some additional care:
It must provide all dependency requirements.
It should not use system interfaces that do not provide for multiple instances of the interface within a process.
If the audit library calls printf(3C), then the audit library must define a dependency on libc (see "Generating a Shared Object"). Because the audit library has a unique name space, symbol references cannot be satisfied by the libc present in the application being audited. If an audit library has a dependency on libc, then two versions of libc.so.1 will be loaded into the process. One satisfies the binding requirements of the application link-map list, and the other satisfies the binding requirements of the audit link-map list.
To ensure audit libraries are built with all dependencies recorded, the link-editors -zdefs option should be used (see "Generating a Shared Object").
Some system interfaces exist assuming they are the only instance of their implementation within a process, for example, threads, signals and malloc(3C). Audit libraries should avoid using such interfaces, as doing so can inadvertently alter the behavior of the application.
The allocation of memory using mapmalloc(3MALLOC) by an audit library is acceptable, as this can exist with any allocation scheme normally employed by the application.