Oracle® Solaris 11.2 链接程序和库指南

退出打印视图

更新时间: 2014 年 7 月
 
 

生成辅助过滤器

要生成辅助过滤器,应先定义要对其应用过滤的 filtee。以下示例将生成一个 filtee filtee.so.1,并提供符号 foo

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

可以通过以下两种方法之一提供辅助过滤。要将共享目标文件提供的所有接口都声明为辅助过滤器,可使用链接编辑器的 –f 选项。要将共享目标文件的单个接口声明为辅助过滤器,可使用链接编辑器 mapfileAUXILIARY 关键字。

以下示例将 filter.so.1 共享目标文件定义为辅助过滤器。filter.so.1 提供 foobar 符号,并且是 filtee filtee.so.1 的辅助过滤器。在此示例中,使用环境变量 LD_OPTIONS 来阻止编译器动程序解释 –f 选项。

$ 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

创建动态可执行文件或共享目标文件时,链接编辑器可将辅助过滤器 filter.so.1 引用为依赖项。链接编辑器使用此过滤器符号表中的信息来实现任何符号解析。但是,在运行时,对此过滤器符号的任何引用都会导致搜索 filtee filtee.so.1。如果找到了 filtee,运行时链接程序就会使用 filtee 解析由 filter.so.1 定义的任何符号。如果未找到此 filtee,或者在此 filtee 中未找到过滤器符号,则会使用过滤器中的原始符号。

例如,以下动态可执行文件 prog 引用符号 foobar;这两个符号在链接编辑过程中通过过滤器 filter.so.1 进行解析。执行 prog 会导致从 filtee filtee.so.1 中获取 foo,而不是filter.so.1 过滤器中获取。但是,bar 是从过滤器 filter.so.1 中获取的,因为此符号在 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

在以下示例中,共享目标文件 filter.so.2 将接口 foo 定义为针对 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]  A    [3] filtee.so.1      foo
    [10]  D        <self>           bar

在运行时,对过滤器符号 foo 的任何引用都会导致搜索 filtee filtee.so.1。如果找到 filtee,就会将 filtee 装入。然后,使用 filtee 来解析由 filter.so.2 定义的 foo。如果未找到 filtee,则将使用由 filter.so.2 定义的 foo 符号。对符号 bar 的引用始终使用 filter.so.2 中的符号,因为没有为此符号定义 filtee 处理。

例如,以下动态可执行文件 prog 引用符号 foobar,这两个符号在链接编辑过程中通过过滤器 filter.so.2 进行解析。如果存在 filtee filtee.so.1,执行 prog 将导致从 filtee filtee.so.1 中获取 foo,并从过滤器 filter.so.2 获取 bar

$ cc -o prog main.c -R. filter.so.2
$ prog
foo is defined in filtee: bar is defined in filter

如果不存在 filtee filtee.so.1,执行 prog 将导致从过滤器 filter.so.2 获取 foobar

$ prog
foo is defined in filter: bar is defined in filter

在这些示例中,filtee filtee.so.1 仅与过滤器关联。不能使用该 filtee 从任何其他可能作为 prog 执行结果而装入的目标文件中实现符号查找。

辅助过滤器提供了一种用于定义现有共享目标文件的备用接口的机制。在 Oracle Solaris OS 中使用此机制可以提供优化的硬件功能以及平台特定的共享目标文件。有关示例,请参见特定于功能的共享目标文件特定于指令集的共享目标文件特定于系统的共享目标文件


注 - 环境变量 LD_NOAUXFLTR 可设置为禁用运行时链接程序辅助过滤器处理。由于通常使用辅助过滤器来提供平台特定的优化,因此,该选项在评估 filtee 用法及其性能影响方面很有用。