在共享库中隐藏“_init”和“_fini”符号

Taw*_*Taw 3 c c++ shared-libraries

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

这是一种使用第一个解决方案并且只导出我的函数的方法,没有_init和_fini?谢谢

yug*_*ugr 6

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

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

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

$ cat myapp.version
{
  global: XML_*; _INTERNAL_*;
  local: *;
};
$ cat Makefile
...
LDFLAGS += -Wl,--version-script=myapp.version
Run Code Online (Sandbox Code Playgroud)

可以在此处找到 Expat 项目的示例。这种方法的一个问题(除了向所有项目添加样板而不是在 Binutils/GCC 中修复一次之外)是很难用 Autoconf 做到正确。

请注意,即使您使用版本脚本,您仍然需要编译-fvisibility=hidden(它允许编译器对隐藏符号执行更积极的优化,而在版本脚本的情况下,编译器不知道最终隐藏了什么)。