链接程序和库指南

生成辅助过滤器

要生成辅助过滤器,应先定义要应用过滤的 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 标志。要将共享库的单个接口声明为辅助过滤器,请使用链接编辑器 mapfile 和 AUXILIARY 指令。

在以下示例中,会将共享库 filter.so.1 定义为辅助过滤器。filter.so.1 提供符号 foo 和 bar,并且是 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 引用符号 foo 和 bar,这两个符号在链接编辑过程中通过过滤器 filter.so.1 进行解析。执行 prog 会导致从 filtee filtee.so.1 中获取 foo,而不是从过滤器 filter.so.1 中获取。但是,从过滤器 filter.so.1 中获取 bar,因为此符号在 filtee filtee.so.1 中没有备选定义。


$ cat main.c

extern char * bar, * foo();



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

{

	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 引用符号 foo 和 bar,这两个符号在链接编辑过程中通过过滤器 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 中获取 foo 和 bar。


$ prog

foo is defined in filter: bar is defined in filter

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

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


注 –

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