GCC 5.3中的新选项:-fno-semantic-interposition

15
GCC 5.3新增了一个新选项:-fno-semantic-interposition

新的-fno-semantic-interposition选项可用于改善共享库的代码质量,其中不允许导出符号的交叉。

这听起来对于某些无法使用交叉引用的C++项目很有用,但延迟是个问题。

然而,描述相当模糊。是否有人能够澄清这个选项的具体作用?


2
这是一位开发人员的博客文章(向下滚动),与GCC5-IPA-LTO相关的新闻。 - molbdnilo
1
顺便提一下,一些编译器(例如LLVM)一直在默默地使用语义重定位(这破坏了ELF语义但在基准测试中表现出色)。 - yugr
1个回答

18

-fno-semantic-interposition可以显著提高共享库中代码的性能,但有些情况下可能会改变语义。

默认情况下,GCC遵循ELF符号重定位语义。简而言之,任何导出的库函数(即使用默认编译器标志编译的任何库函数)都可以通过LD_PRELOAD或在动态链接器更早加载的另一个共享库中具有相同名称的函数来替换运行时。这会阻止编译器执行许多有用的分析和优化(最主要的是内联和克隆),因为它们可能会破坏重定位。

-fno-semantic-interposition使编译器忽略潜在的重定位并更加积极地进行优化。

正如我所说,使用-fno-semantic-interposition有一些注意事项:

  • 它可能会改变程序的行为(当它实际上依赖于重定位时,有时你可能没有意识到这一点)
  • 它仅适用于共享库(不适用于可执行文件)
  • 如果您已经正确优化了库(即使用-fvisibility=hidden进行编译,并使用__attribute__((visibility("default"))) 显式注释所有导出符号),则它的用处要小得多

第一项阻止了-fno-semantic-interposition的广泛部署。例如,据我所知,没有 Linux发行版在广泛范围内使用它(顺便说一句,这将是一个很好的项目)。

顺便提一下,Clang编译器默认启用-fno-semantic-interposition选项,可能是为了性能考虑。他们一个相反的-fsemantic-interposition选项来启用与GCC兼容的ELF交叉引用语义。


没有知识、没有完整分析或没有严格定义的限制,实际干预不是一个严重的危险吗? - curiousguy
3
@curiousguy 是的,而且已经被证明会导致错误(详见Flameeyes关于符号冲突的博客文章)。现在推荐的编程实践是通过-fvisibility=hidden来减少导出的符号。不幸的是,这个实践并没有得到严格的遵守(我开发了一个检测不必要符号导出的工具,但并没有得到社区的太多关注)。 - yugr
这对我来说似乎也可能导致您链接到的库违反LGPL。 - Omnifarious

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接