Linker and Libraries Guide

Generating an Auxiliary Filter

The creation of an auxiliary filter is essentially the same as for a standard filter (see "Generating a Standard Filter" for more details). First let's define a filtee, libbar.so.1, on which this filter technology will be applied. This filtee might be built from several relocatable objects. One of these objects originates from the file bar.c, and supplies the symbol foo:


$ cat bar.c
char * foo()
{
    return("defined in bar.c");
}
$ cc -o libbar.so.1 -G -K pic .... bar.c ....

An auxiliary filter, libfoo.so.1, is generated for the symbols foo and bar, and indicates the association to the filtee libbar.so.1. For example:


$ cat foo.c
char * bar = "foo";

char * foo()
{
    return ("defined in foo.c");
}
$ LD_OPTIONS='-f libbar.so.1' \
cc -o libfoo.so.1 -G -K pic -h libfoo.so.1 -R. foo.c
$ ln -s libfoo.so.1 libfoo.so
$ dump -Lv libfoo.so.1 | egrep "SONAME|AUXILIARY"
[1]     SONAME    libfoo.so.1
[2]     AUXILIARY libbar.so.1

Note -

Here, the environment variable LD_OPTIONS is used to circumvent this compiler driver from interpreting the -f option as one of its own.


If the link-editor references the auxiliary filter libfoo.so.1 to build a dynamic executable or shared object, it will use the information from the filter's symbol table during symbol resolution (see "Symbol Resolution" for more details).

At runtime, any reference to the symbols of the filter will result in a search for the filtee libbar.so.1. If this filtee is found, the runtime linker will use this filtee to resolve any symbols defined by libfoo.so.1. If the filtee is not found, or a symbol from the filter is not found in the filtee, then the original value of the symbol within the filter is used.

For example, the following dynamic executable, prog, references the symbols foo and bar, which are resolved during link-edit from the filter libfoo.so.1:


$ cat main.c
extern char * bar, * foo();

main(){
    (void) printf("foo() is %s: bar=%s\n", foo(), bar);
}
$ cc -o prog main.c -R. -L. -lfoo
$ prog
foo() is defined in bar.c: bar=foo

The execution of the dynamic executable prog results in the function foo() being obtained from the filtee libbar.so.1, not from the filter libfoo.so.1. However, the data item bar is obtained from the filter libfoo.so.1, as this symbol has no alternative definition in the filtee libbar.so.1.

Auxiliary filters provide a mechanism for defining an alternative interface of an existing shared object. This mechanism is used in Solaris to provide optimized functionality within platform specific shared objects.


Note -

The environment variable LD_NOAUXFLTR can be set to disable the runtime linkers auxiliary filter processing. This can be useful in evaluating a filtees use and performance impact.


Platform Specific Shared Objects

An extension to the auxiliary filter naming mechanism provides for the use of the reserved token $PLATFORM. This token is expanded at runtime to reflect the underlying hardware implementation, as displayed by the utility uname(1) with the -i option.

The following example shows how the auxiliary filter libfoo.so.1 can be designed to access a platform specific filtee libbar.so.1:


$ LD_OPTIONS='-f /usr/platform/$PLATFORM/lib/libbar.so.1' \
cc -o libfoo.so.1 -G -K pic -h libfoo.so.1 -R. foo.c
$ dump -Lv libfoo.so.1 | egrep "SONAME|AUXILIARY"
[1]     SONAME    libfoo.so.1
[2]     AUXILIARY /usr/platform/$PLATFORM/lib/libbar.so.1

This mechanism is used on Solaris to provide platform specific extensions to the shared object /usr/lib/libc.so.1.