当前位置:  开发笔记 > 编程语言 > 正文

Linux中没有符号插入的共享对象,-fno-semantic-interposition error

如何解决《Linux中没有符号插入的共享对象,-fno-semantic-interpositionerror》经验,为你挑选了1个好方法。

类Unix系统中的共享对象(*.so)由于符号插入而效率低下:.so内部对全局变量的每次访问都需要GOT查找,而.so内部从一个函数到另一个函数的每次调用都需要一个PLT抬头.因此,我很高兴看到gcc版本5.1添加了选项-fno-semantic-interposition.但是,当我尝试在没有使用PLT的情况下创建一个函数调用另一个函数的.so时,我收到错误消息:

在创建共享对象时,不能使用符号`functionname'重定位R_X86_64_PC32; 用-fPIC重新编译

我期望选项-fno-semantic-interposition可以消除此错误消息,但事实并非如此.-mcmodel = large也无济于事.对函数的引用确实与位置无关,错误消息实际确认了这一点(R_X86_64_PC32表示在64位模式下与PC相关的32位重定位).-fPIC实际上并不意味着与位置无关,正如名称所暗示的那样,它实际上意味着使用GOT和PLT.

我无法使用,__attribute__((visibility ("hidden")))因为被调用的函数和调用者是在单独的文件中编译的(调用者在C++中,称为函数在汇编中).

我试图制作一个汇编列表来查看-fno-semantic-interposition选项的作用.我发现当一个函数在同一个文件中调用另一个函数时,它会引用一个本地别名,但在另一个文件中调用一个函数时它仍然使用PLT.

(g ++版本是5.2.1 Ubuntu,64位模式).

有没有办法让链接器在没有GOT/PLT查找的情况下接受.so内的交叉引用?



1> Employed Rus..:

有没有办法让链接器在没有GOT/PLT查找的情况下接受.so内的交叉引用?

是的:attribute((visibility("hidden")))正是这样做的.

我不能使用attribute((visibility("hidden")))因为被调用的函数和调用者是在单独的文件中编译的

您感到困惑:visibility("hidden")意味着当符号最终链接时,不会从共享库中导出符号.但该符号是全局的,并且在最终链接之前跨多个翻译单元可见.

证明:

$ cat t1.c
extern int foo() __attribute__((visibility("hidden")));

int main() { return foo(); }
$ cat t2.c
int foo() __attribute__((visibility("hidden")));
int foo() { return 42; }
$ gcc -c -fPIC t1.c t2.c
$ gcc -shared t1.o t2.o -o t.so
$ nm -D t.so | grep foo
$

我试图制作一个汇编列表来查看-fno-semantic-interposition选项的作用.我发现当一个函数在同一个文件中调用另一个函数时,它会引用一个本地别名,但在另一个文件中调用一个函数时它仍然使用PLT.

如果你读了讨论,在GCC-补丁,你会看到-fno-semantic-interposition大约是允许的可能interposable函数内联,不是不内联时,他们实际上是调用方式.

推荐阅读
放ch养奶牛
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有