我有一个共享库 (bar.so) 形式的插件,它链接到一个更大的程序 (foo)。 foo 和 bar.so 都依赖于同一个第三方库 (baz),但它们需要将 baz 的实现完全分开。因此,当我链接 foo(使用提供的目标文件和存档)时,我需要它忽略 bar.so 中对 baz 的任何使用,反之亦然。
现在,如果我将 foo 与 --trace-symbol=baz_fun
链接,其中 baz_fun 是有问题的符号之一,我将得到以下输出:
bar.so: definition of baz_fun
foo/src.a(baz.o): reference to baz_fun
我相信这告诉我 foo 正在从 bar.so 引用 baz_fun(并且 foo 的执行证实了这一点)。
我尝试过的解决方案:
- 使用
objcopy
来“本地化”感兴趣的符号:objcopy --localize-symbols=local.syms bar.so
其中 local.syms 包含所有符号出于兴趣。我想我可能只是在这里感到困惑,也许“本地”并不意味着我认为的意思。无论如何,我从上面的链接得到相同的输出。我应该注意,如果我在使用objcopy
之前在 bar.so 上运行nm
工具,所有有问题的符号都有T
标志(大写表示全局)并且在objcopy
之后它们有一个t
表示它们现在是本地的。所以看来我正在正确使用objcopy
。 - 使用
-fvisibility=hidden
进行编译,但是由于其他一些限制,我需要使用似乎不支持该功能的 GCC 3.3。我可能能够升级到更新版本的 GCC,但我想确认使用此标志进行编译会在我走上这条路之前对我有所帮助。
其他注意事项:
- 我无权访问 foo 或 baz 的源代码
- 我更愿意将所有插件保存在一个共享对象 (bar.so) 中。 baz 实际上是一个许可库,所以我不想把它分开
最佳答案
使用 dlopen
加载带有 RTLD_DEEPBIND
标志的插件。
(编辑)
请注意,RTLD_DEEPBIND 是特定于 Linux 的,需要 glibc 2.3.4 或更新版本。
关于linux - 如何限制对共享对象中符号的访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6194525/