使用DT_FILTER从DSO中隐藏符号

3
我最近试图隐藏一些第三方DSO中的符号,并发现了创建“过滤器 DSO” 的 "--filter" LD 选项。从 ld手册 上,我认为动态链接器只会考虑存在于过滤器 DSO's dynsym 中的符号:

"动态链接器将根据过滤器对象的符号表解析符号,但实际上将链接到共享对象名称中找到的定义。"

所以看起来正是我需要的:一种选择从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 上都存在这种情况。

2个回答

1
根据https://sourceware.org/bugzilla/show_bug.cgi?id=27977的说法:

DT_NEEDED将引用的对象放在搜索范围中当前对象之后。DT_FILTER将其放在之前。我相信这是当前glibc实现中唯一的区别。没有过滤。自从很久以前就一直是这样


0

我正在尝试实现相同的事情。看起来这与链接顺序有关。我将 -l1 移到了 -l2f 之前,即在 Makefile 中更改您的链接行为:

main: lib1.so lib2.so lib2f.so main.c
    gcc main.c -L. -l1 -l2f -o $@

我得到的结果是:

$ ./main 
func1@lib1
func2@lib1
func3@lib2

当然,这取决于链接顺序。我相信在这样的链接顺序下根本不需要过滤器。 - tdiff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接