首页 > 解决方案 > 使用 DT_FILTER 隐藏 DSO 中的符号

问题描述

我最近试图从第 3 方 DSO 中隐藏一些符号,并遇到了用于创建“过滤 DSO”的“--filter”LD 选项。从ld 手册页,我的印象是动态链接器只会考虑过滤器 DSO 的动态符号中存在的符号:

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

所以它看起来正是我所需要的:一种从 DSO 中选择哪些符号参与动态链接的方法。不幸的是,它并没有像我预期的那样工作(这个例子也可以从github克隆)

生成文件:

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 上。

标签: clinkersymbolsldglibc

解决方案


根据https://sourceware.org/bugzilla/show_bug.cgi?id=27977

DT_NEEDED 将引用的对象放在搜索范围内的当前对象之后。DT_FILTER 把它放在它前面。我相信这是当前 glibc 实现的唯一区别。根本没有过滤。基本上永远都是这样


推荐阅读