Generating Auxiliary Filters
To generate an auxiliary filter, you first define a
filtee on which the filtering is applied.
The following example builds a filtee
filtee.so.1
, supplying the symbol
foo
.
$ cat filtee.c char *foo() { return("defined in filtee"); } $ cc -o filtee.so.1 -G -K pic filtee.c
Auxiliary filtering can be defined at the object level, or for
individual symbols. To declare all of the interfaces offered by a
shared object to be auxiliary filters, use the link-editor
mapfile
FILTER
directive, or -f
command
line option. To declare individual interfaces of a shared object to
be auxiliary filters, use a link-editor mapfile
FILTER
directive or -f
command
line option. To declare individual interfaces of a shared object to
be auxiliary filters, use a link-editor mapfile
and the AUXILIARY
or FILTER
symbol attribute.
In the following example, the shared object
filter.so.1
is defined to be an
auxiliary filter. filter.so.1
offers the
symbols foo
and bar
, and is an
auxiliary filter on the filtee
filtee.so.1
. In this example, the environment
variable LD_OPTIONS
is used to circumvent the
compiler driver from interpreting the -f
option.
$ cat filter.c char *bar = "defined in filter"; char *foo() { return ("defined in filter"); } $ LD_OPTIONS='-f filtee.so.1' \ cc -o filter.so.1 -G -K pic -h filter.so.1 -R. filter.c $ elfdump -d filter.so.1 | egrep "SONAME|AUXILIARY" [2] SONAME 0xee filter.so.1 [3] AUXILIARY 0xfb filtee.so.1
A mapfile
can be used instead of the
-f
command line option.
$ cat mapfile $mapfile_version 2 FILTER { FILTEE = filtee.so.1; TYPE = AUXILIARY; }; $ cc -o filter.so.1 -G -K pic -h filter.so.1 -M mapfile -R. filter.c $ elfdump -d filter.so.1 | egrep "SONAME|AUXILIARY" [2] SONAME 0xee filter.so.1 [3] AUXILIARY 0xfb filtee.so.1
The link-editor can reference the auxiliary filter
filter.so.1
as a dependency when creating
a dynamic object. The link-editor uses
information from the symbol table of the filter to satisfy any
symbol resolution. However, at runtime, any reference to the symbols
of the filter result in a search for the filtee
filtee.so.1
. If this filtee is
found, the runtime linker uses the filtee to
resolve any symbols defined by filter.so.1
. If
the filtee is not found, or a symbol from the
filter is not found in the filtee, then the
original 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
filter.so.1
. The execution of
prog
results in foo
being obtained from the filtee
filtee.so.1
, not from the
filter filter.so.1
. However,
bar
is obtained from the filter
filter.so.1
, as this symbol has no
alternative definition in the filtee
filtee.so.1
.
$ cat main.c extern char *bar, *foo(); void main() { (void) printf("foo is %s: bar is %s\n", foo(), bar); } $ cc -o prog main.c -R. filter.so.1 $ prog foo is defined in filtee: bar is defined in filter
In the following example, the shared object
filter.so.2
defines the interface
foo
, to be an auxiliary filter on the
filtee
filtee.so.1
.
$ cat filter.c char *bar = "defined in filter"; char *foo() { return ("defined in filter"); } $ cat mapfile $mapfile_version 2 SYMBOL_SCOPE { global: foo { AUXILIARY=filtee.so.1 }; }; $ cc -o filter.so.2 -G -K pic -h filter.so.2 -M mapfile -R. filter.c $ elfdump -d filter.so.2 | egrep "SONAME|AUXILIARY" [2] SONAME 0xd8 filter.so.2 [3] SUNW_AUXILIARY 0xfb filtee.so.1 $ elfdump -y filter.so.2 | egrep "foo|bar" [1] [ AUXILIARY ] [3] filtee.so.1 foo [10] [ DEPEND] <self> bar
At runtime, any reference to the symbol foo
of the
filter, results in a search for the filtee
filtee.so.1
. If the filtee is
found, the filtee is loaded. The
filtee is then used to resolve the symbol
foo
defined by
filter.so.2
. If the
filtee is not found, symbol
foo
defined by
filter.so.2
is used. Reference to the
symbol bar
always uses the symbol from
filter.so.2
, as no
filtee processing is defined for this
symbol.
For example, the following dynamic executable
prog
, references the symbols
foo
and bar
, which are
resolved during link-edit from the filter
filter.so.2
. If the
filtee
filtee.so.1
exists, the execution of
prog
results in foo
being obtained from the filtee
filtee.so.1
, and bar
being
obtained from the filter filter.so.2
.
$ cc -o prog main.c -R. filter.so.2 $ prog foo is defined in filtee: bar is defined in filter
If the filtee
filtee.so.1
does not exist, the execution of
prog
results in foo
and bar
being obtained from the filter
filter.so.2
.
$ prog
foo is defined in filter: bar is defined in filter
In these examples, the filtee
filtee.so.1
is uniquely associated to the
filter. The filtee is not available to satisfy
symbol lookup from any other objects that might be loaded as a
consequence of executing prog
.
Auxiliary filters provide a mechanism for defining an alternative interface of an existing shared object. This mechanism is used in the Oracle Solaris OS to provide optimized functionality within hardware capability, and platform specific shared objects. See Capability Specific Shared Objects, and System Specific Shared Objects for examples.
Note:
The environment variableLD_NOAUXFLTR
can be set to disable
the runtime linkers auxiliary filter processing. Because
auxiliary filters are frequently employed to provide
platform specific optimizations, this option can be useful
in evaluating filtee use and their
performance impact.