无法解决的“R_X86_64_NONE”搬迁

Unresolvable `R_X86_64_NONE` relocation

提问人:zaufi 提问时间:2/9/2018 最后编辑:zaufi 更新时间:2/21/2018 访问量:3071

问:

我在 CentOS 7 上使用 Devtoolset-7,并使用它构建了 Boost 1.65.1。 但是当我链接我的应用程序时,我得到了以下内容:

/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: /opt/rh/devtoolset-7/root/usr/lib64/libboost_unit_test_framework.a(compiler_log_formatter.o)(.text._ZN5boost9unit_test5utils11string_castINS0_13basic_cstringIKcEEEESsRKT_[_ZN5boost9unit_test5utils11string_castINS0_13basic_cstringIKcEEEESsRKT_]+0x3c): unresolvable R_X86_64_NONE relocation against symbol `_ZTVSt9basic_iosIcSt11char_traitsIcEE@@GLIBCXX_3.4'
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status

搜索更多信息不会给出任何有价值的结果:大多数类似的问题,没有任何答案或精确的解释,这是什么以及如何解决它。R_X86_64_NONE

所以我的问题是:

  • 这个错误到底意味着什么?
  • ELF 标头中存在什么以及为什么“没有什么可重新定位的”(根据 Bintils 消息来源)类型的符号?R_X86_64_NONE

附录

  • 链接单元测试可执行文件时发生错误,该可执行文件链接到我的静态库和 Boosts 的静态库(单元测试框架)
  • 所有静态库(Boost 和 mine 库)都内置了选项-fPIC

我真的希望这个问题能一劳永逸地解决(已经打了几次了,但这次更新到最新的 binutils 无济于事)。(将对此问题的任何活动开始赏金)

C++ ELF 未解析的外部 binutils

评论

0赞 OMGtechy 2/9/2018
使用最近基于 LLVM 的编译器(例如 clang(reviews.llvm.org/rL288485)
0赞 zaufi 2/9/2018
不幸的是,我需要 GCC 7.x %)
0赞 Some programmer dude 2/9/2018
你自己安装了GCC 7吗?你自己构建了 Boost 吗?使用与应用程序相同的编译器/链接器和标准库(包括版本)?我自己没有遇到过这个错误,但通过阅读类似的问题,它似乎主要是关于编译器/链接器/标准库版本不匹配的问题。
0赞 zaufi 2/9/2018
我使用了 Devtoolset 7 中的 GCC/Binutils。Boost 构建了 SCL 采用的 RPM 规范,并使用 DTS7 工具链进行了编译。
0赞 Florian Weimer 2/14/2018
@zaufi 你能在某个地方发布一组最小的目标文件来触发它吗?例如,您可以在 Bugzilla 中打开一个 bug。我从未见过任何触发此问题的对象文件,并且显然没有人提交适当的错误报告。

答:

10赞 Florian Weimer 2/15/2018 #1

发布到 Red Hat Bugzilla bug 的构建日志中:

[19:15:01]W:     [Step 8/12] + /usr/lib/rpm/check-buildroot
[19:15:01]W:     [Step 8/12] + /usr/lib/rpm/brp-scl-compress /opt/rh/devtoolset-7/root
[19:15:01]W:     [Step 8/12] + /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip
[19:16:40]W:     [Step 8/12] /usr/bin/strip: /work/build/BUILDROOT/devtoolset-7-boost-1.65.1-4.el7.centos.x86_64/opt/rh/devtoolset-7/root/usr/lib64/libboost_container.a(global_resource.o): invalid relocation type 42
[19:16:40]W:     [Step 8/12] /usr/bin/strip: BFD version 2.25.1-32.base.el7_4.2  assertion fail elf64-x86-64.c:341

注意 ,不是 。所以使用了系统命令。42 对应于由 DTS binutils 作为优化生成的重定位。/usr/bin/strip/opt/rh/devtoolset-7/root/usr/bin/stripstripR_X86_64_REX_GOTPCRELX

重现此问题的一种简单方法是使用此 C++ 文件:

#include <iostream>

void
dot ()
{
  std::cout << '.';
}

如果使用 编译,它将生成 的重定位。运行它会把它变成.这可以使用 进行验证。-O2 -fpicX86_64_REX_GOTPCRELX_ZNSt8ios_base4InitD1Ev/usr/bin/strip -gR_X86_64_NONEeu-readelf -r

您可以使用 RPM 来告诉使用 DTSstrip

%if 0%{?scl:1}
%define __strip %{_bindir}/strip
%endif

在 RPM 规范文件中,或者您可以添加

%undefine __brp_strip_static_archive

跳过完全剥离静态库(无论如何这可能是正确的做法)。