隐藏" _init"和" _fini"共享库中的符号

时间:2018-06-02 20:26:25

标签: c++ c shared-libraries

我正在创建一个共享库,我注意到使用__attribute__((visibility("default")))(与-fvisibility=hidden一起使用)我的库也会导出_init_fini个符号。如果我使用一个exported_symbols列表(与-Wl,--version-script=<file_list>一起使用),lib只导出我的函数,这是完美的。

是否可以使用第一个解决方案并仅导出我的函数,而不使用_init_fini?感谢

1 个答案:

答案 0 :(得分:4)

首先,问题不仅限于_init_fini - GNU工具链默认导出其他无用的符号,例如_edata等等。这些符号确实是完全没有必要的(动态链接器通过不同的方式获得指向ctors / dtors的指针)。

我最近向gcc-helpBinutils列表报告了此问题。 Bintools列表中的回复是虽然这些符号确实没有在Linux系统上使用,但删除它们必须非常小心并且需要大量测试并且性能增益可以忽略不计。我没有在gcc-help中得到答案(也许在gcc开发者列表中重新发布是有意义的。)

作为解决方法,您可以通过版本脚本显式隐藏不需要的符号:

$ cat myapp.version
{
  global: XML_*; _INTERNAL_*;
  local: *;
};
$ cat Makefile
...
LDFLAGS += -Wl,--version-script=myapp.version

可以找到Expat项目的一个示例here。这种方法的一个问题(除了在所有项目中添加样板而不是在Binutils / GCC中修复一次)是因为使用Autoconf很难做到这一点。

请注意,即使您使用版本脚本,仍然需要使用-fvisibility=hidden进行编译(它允许编译器对隐藏符号执行更积极的优化,而在版本脚本中&#39;案例编译器不知道最终被隐藏的内容。