在Mac OS X上的共享库中隐藏符号(Hiding symbols in a shared lib

2019-08-03 18:46发布

我们已经建立了大量的开源软件在各种平台(Linux,在Windows,Mac OS X,32位和64位)数年无烦恼。 然而最近,在Mac OS X版本(64位)停止正常工作,并开始随机崩溃。 它与Mac OS X的我们的构建机器上10.8.2更新从10.7或多或少正值(但编译器工具链并没有改变,它仍然是LLVM-GCC 4.2.1)。

我们的应用程序是由一对夫妇的动态(共享)库和使用它们的许多可执行文件。 一个共享库的覆盖newdelete运营商的原因有多种。 在Mac OS X(和Linux),所有符号默认情况下出口的,包括我们的重载newdelete运算符。 在Mac OS X上的崩溃似乎与某些内存与一个内存子系统(不是我们的),然后通过我们自己的(和不兼容)释放分配delete的实现。

该sanest溶液似乎是防止重载操作符从被连接到共享库的用户可见。 这可以通过两种方式来完成:标记与运营商__attribute__((visibility("hidden")))或使用-unexported_symbols_list链接器命令行选项,以防止被导出一些符号。 第一个解决方案不幸的是不起作用:GCC发出警告说,运营商已经宣布不同(在<new> ),因此属性将被忽略。 从我在各个地方的读数, 第二个解决方案似乎是正确的解决这个问题。 但是由于某些原因,我们不能使它发挥作用

当链接共享库,我们传递的-Wl,-unexported_symbols_list unexported_symbols_list.txt选项G ++,这反过来应该传递给ld。 该unexported_symbols_list.txt文件包含符号下面的列表:

__ZdaPv
__ZdaPvRKSt9nothrow_t
__ZdlPv
__ZdlPvRKSt9nothrow_t
__ZdlPvS_
__Znam
__ZnamRKSt9nothrow_t
__Znwm
__ZnwmPv
__ZnwmRKSt9nothrow_t

这些是所有变化newdelete ,我们覆盖,并希望被隐藏。 我们做找不到这些符号nm libappleseed.dylib然后unmangling使用符号名称c++filt

这里是由CMake的生成链接命令行libappeseed.dylib

/usr/bin/g++  -g -Werror -dynamiclib -Wl,-headerpad_max_install_names -framework Cocoa -lcurl    -Werror -Wl,-unexported_symbols_list -Wl,unexported_symbols_list.txt -o ../mac-gcc4/appleseed/libappleseed.dylib [...]

不幸的是,尽管我们的一切努力似乎符号保持(如纳米所示)。

任何想法,我们在做什么错? 是否有另一种方法,我们可以尝试?


UPDATE 2012年12月19日:

我们的问题和解决方案应该很好覆盖在苹果这个技术说明: http://developer.apple.com/library/mac/#technotes/tn2185/_index.html (节“重写新/删除”)。

指针相关的源代码:

  • operator newoperator delete覆盖: allocator.cpp
  • 宏来控制在共享库符号可见: dllvisibility.h

的片段nm构建libappleseed.dylib用后的输出-fvisibility=hidden和运行strip -x libappleseed.dylib

...
00000000002a41b0 T __ZdaPv
00000000002a41f0 T __ZdaPvRKSt9nothrow_t
00000000002a4190 T __ZdlPv
00000000002a41d0 T __ZdlPvRKSt9nothrow_t
00000000002a4060 T __Znam
00000000002a4130 T __ZnamRKSt9nothrow_t
00000000002a3ff0 T __Znwm
00000000002a40d0 T __ZnwmRKSt9nothrow_t
...

Answer 1:

你应该与建设-fvisibility=hidden ,然后你只想要什么出口。 在这里有一个读:

http://gcc.gnu.org/wiki/Visibility

这也解释了-fvisibility-inlines-hidden 。 许多大型图书馆(QT,例如)利用这一点。 好处是相当可观的。



Answer 2:

你可以看一看符号映射/版本(--version脚本ld的选项)

http://accu.org/index.php/journals/1372



文章来源: Hiding symbols in a shared library on Mac OS X