如何使共享库符号强大?

How can I make a shared library's symbols strong?

我创建了一个共享库,它引用了很多 C++ 模板函数。这些符号作为弱引用输入共享库的导出 table(例如,当我使用 nm 查看共享库的符号时,它们显示为类型 W)。这意味着在运行时,这些符号可能会被首先加载的不同共享库的副本插入。

对于我的应用程序来说,重要的是我的共享库使用这些函数的副本,这些函数包含在库本身中,而不是来自任何其他库。有什么办法可以确保这一点?在我看来,这相当于将所有各种模板实例静态链接到共享库中。

This means that at runtime, these symbols can possibly be interposed by copies from a different shared library that got loaded first.

请注意,无论 weak 属性如何,它们都可以插入(参见 this GCC post 说动态 linker 对待弱者类似于对待强者,除非设置了 LD_DYNAMIC_WEAK,这通常是't).

It's important for my application that my shared library use the copies of these functions that are contained within the library itself, not from any other library. Is there any way to ensure this?

您可以做几件事。

通常推荐的方法是将 fvisibility=hidden 添加到您的 CFLAGS 以防止从您的库中导出任何符号,然后使用 __attribute__((visibility("default"))) 标记(希望很少)导出的函数。这也将允许在编译时进行更好的优化和更快的启动,因为 rtld 将需要处理更少的符号。

穷人的有限解决方案是使用 -fvisibility-inlines-hidden,这是 -fvisility=hidden 的有限形式。它只会隐藏内联函数(例如,来自 STL 模板)。

如果您不想弄乱源代码,link 与 -Wl,-Bsymbolic - 这将强制尽可能在库中解析引用。

-- 编辑--

实际上,即使您启用 -fvisibility=hidden 以防止其他库(或可执行文件本身)动态插入对导出函数的库内引用,您也需要 -Bsymbolic