我最近试图隐藏一些第三方DSO中的符号,并发现了创建“过滤器 DSO” 的 "--filter" LD 选项。从 ld手册 上,我认为动态链接器只会考虑存在于过滤器 DSO's dynsym 中的符号:
Makefile:
所以看起来正是我需要的:一种选择从DSO中哪些符号参与动态链接的方式。不幸的是,它并没有像我期望的那样工作(这个例子也可以从 github 克隆出来)。"动态链接器将根据过滤器对象的符号表解析符号,但实际上将链接到共享对象名称中找到的定义。"
Makefile:
lib1.so: lib1.c
gcc -shared -fPIC $^ -o $@
lib2.so: lib2.c
gcc -shared -fPIC $^ -o $@
lib2f.so: lib2f.c
gcc -shared -fPIC -Wl,--filter,lib2.so $^ -o $@
main: lib1.so lib2.so lib2f.so main.c
gcc main.c -L. -l2f -l1 -o $@
clean:
rm *.o *.so main
lib1.c
#include <stdio.h>
void func1()
{
printf("func1@lib1\n");
}
void func2()
{
printf("func2@lib1\n");
}
lib2.c
#include <stdio.h>
void func1()
{
printf("func1@lib2\n");
}
void func3()
{
printf("func3@lib2\n");
}
lib2f.c(lib2.so的过滤器):
void func3() {}
可执行文件
void func1();
void func2();
void func3();
int main()
{
func1();
func2();
func3();
return 0;
}
当我运行该测试程序时,我得到以下输出:
> LD_LIBRARY_PATH=. ./main
func1@lib2
func2@lib1
func3@lib2
我们可以看到,尽管试图通过lib2f.so“过滤”它,但实际上引用了来自lib2的一个符号。我希望输出结果如下:
> LD_LIBRARY_PATH=. ./main
func1@lib1 // use func1 from lib1
func2@lib1
func3@lib2
我是否可以通过使用 ld --filter
选项(又称 DT_FILTER)实现隐藏某些动态共享对象(DSO)的符号而达到我的目标呢?
如果不行,那么我的期望/手册阅读中有什么问题吗?
在 glibc 2.34 和 2.17 上都存在这种情况。