在 gcc 目标机器上,当想要编译共享库时,需要指定 -fpic 或 -fPIC 才能正确工作。这是因为默认情况下使用绝对寻址,这适用于完全控制自己的地址空间的可执行文件,但不适用于共享库,共享库可以加载到可执行文件地址空间中的任何位置。
然而,现代内核现在正在实现地址空间随机化,并且许多现代体系结构支持 PC 相对寻址。这一切似乎使得绝对寻址变得不可用(地址空间随机化)或不需要(PC 相对寻址)。
我还注意到 clang 没有 -fPIC 选项,这让我认为不再需要它。
那么 -fPIC 现在是多余的还是需要生成单独的 .o 文件,一个用于静态库使用,一个用于共享库使用?
您仍然需要使用 -fPIC 进行编译。该问题无法通过 PC 相对寻址来解决。问题是如何解析外部符号。在动态链接程序中,解析遵循不同的规则,特别是在地址空间随机化的情况下,它无法在链接期间解析。
clang 确实有 -fPIC 标志,就像 gcc 一样。
$ cat > foo.c
void foo(void);
void bar(void) { foo(); }
$ gcc -S foo.c && grep call.*foo foo.s
call foo
$ gcc -fPIC -S foo.c && grep call.*foo foo.s
call foo@PLT
$ clang -S foo.c && grep call.*foo foo.s
callq foo
$ clang -fPIC -S foo.c && grep call.*foo foo.s
callq foo@PLT
$
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)