GCC共享库链接glibc失败

9
我正在使用Linux 64位下的Eclipse CDT编写一个简单的C共享库。代码中有一个对<stdlib.h>中的rand()函数的引用。它可以编译,但在链接时,链接器报告以下错误:
gcc -shared -o "libalg.so"  ./sort.o   
/usr/bin/ld: ./sort.o: relocation R_X86_64_PC32 against undefined symbol `rand@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value

sort.o是从文件编译出的目标文件,libalg.so是目标共享库的名称。

有人能解释一下为什么会发生这种情况吗?

谢谢。


你尝试过像错误信息建议的那样,在gcc中传递“-fPIC”重新编译吗? - zneak
还没有,我只是想先理解问题。 - Wudong
1
据说加上-fPIC可以解决这个问题。 - Wudong
这是一个棘手的链接问题,我对此并不十分熟悉,但基本上,程序被加载到可预测的地址,而共享库则不是。程序的可预测地址使得链接器能够使用一些技巧来查找无法与库一起使用的符号。编译成位置无关代码(PIC表示位置无关代码)允许使用其他适用于库的技巧,但它也带来了不同的权衡。 - zneak
1个回答

17

x86_64 架构中,默认情况下,gcc 要求您使用 -fPIC 即 默认使用位置无关代码。

出现错误的根本原因是符号 rand 的重定位类型为 R_X86_64_PC32,这意味着它是 PC 相关的,并且应该位于以下指令的 32bit 偏移量内。

但当前架构是 x86_64 类型,这意味着它可以位于 64bit 地址空间的任何位置。

因此,动态链接器实际上不能链接具有这种重定位类型的符号。

要么您必须使用 -fPIC,要么使用 -mcmodel=large 编译您的代码,这将使重定位类型变为 R_X86_64_64

有关链接方式的更多详细信息,请参阅 Eli Bendersky 的博客


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