【问题标题】:gcc shared library failed linking to glibcgcc 共享库链接到 glibc 失败
【发布时间】:2014-02-09 00:54:27
【问题描述】:

我正在使用 Eclipse CDT 在 Linux 64bit 下编写一个简单的 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 是目标共享库名称。

谁能解释为什么会这样?

谢谢。

【问题讨论】:

  • 您是否尝试过按照错误消息的提示重新编译将 -fPIC 传递给 gcc?
  • 还没有,我只是想先了解一下问题。
  • 显然加上 -fPIC 解决了这个问题。
  • 这是一个血腥的链接问题,我对此还不够好,无法真正提供帮助,但基本上,程序是在可预测的地址加载的,但共享库不是。程序的可预测地址使链接器能够使用技巧来查找库无法使用的符号。编译为与位置无关的代码(PIC 表示与位置无关的代码)允许使用其他与库一起使用的技巧,但它带来了不同的权衡。

标签: c gcc linker


【解决方案1】:

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

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

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

所以动态链接器实际上无法链接具有这种重定位类型的符号。

您必须使用-fPIC 或使用-mcmodel=large 编译您的代码,这实际上会将重定位类型设置为R_X86_64_64

有关如何完成链接的更多详细信息,请参阅Eli Bendersky 的这篇精彩博客

【讨论】:

    猜你喜欢
    • 2019-08-23
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-26
    • 1970-01-01
    相关资源
    最近更新 更多