问题背景
在Debian编译LLVM时,出现如下错误:
relocation R_X86_64_PC32 against undefined symbol `__ehdr_start’ can not be used when making a shared object; recompile with -fPIC
该问题指出在链接生成动态库时,有的 .o 文件没有添加 -fPIC 编译。
该问题比较奇怪,因为使用的时同一套构建指令,只有在 Debian出现问题。
然后打印出详细的构建日志,也发现所有的 .o 文件在编译期间都添加了 -fPIC 。
感觉可能是系统的问题。
查找原因
经过搜索,发现是系统的 ld 链接器存在bug。
验证步骤:
- 查看系统的链接器版本
可以看到和文章中提到的版本一致。
# ld -v
GNU ld (GNU Binutils for Debian) 2.31.1
- 准备如下文件
$ cat test.cpp
extern char __ehdr_start;
int main() {
char x = __ehdr_start;
}
- 使用默认链接器
报错如下:
# g++ -shared -fPIC -o test test.cpp
/usr/bin/ld: /tmp/ccWvJyV9.o: relocation R_X86_64_PC32 against undefined symbol `__ehdr_start' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: nonrepresentable section on output
collect2: error: ld returned 1 exit status
- 使用 gold 链接器
可以正常执行完成
# g++ -fuse-ld=gold -shared -fPIC -o test test.cpp
# echo $?
0
至此,可以验证此系统此版本的链接器存在bug。
解决方案
- 更换 gold 或 lld 等其他链接器
- 升级 ld
参考: