无法解决的`r_x86_64_none`重定位

Unresolvable `R_X86_64_NONE` relocation

本文关键字:none 定位 x86 解决      更新时间:2023-10-16

我正在使用CentOS 7上的DevToolSet-7,并构建了Boost 1.65.1 W/IT。但是,当我链接我的应用程序时,我有以下内容:

/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的更多信息没有给出任何有价值的结果:主要是类似的问题,没有任何答案或精确说明这是什么以及如何解决。

所以我的问题是:

  • 这个错误到底是什么意思?
  • 什么是R_X86_64_NONE,为什么"没有重新分配"(根据Bintils的来源(符号的类型在精灵标题中存在?

附录

  • 在链接单元测试可执行文件上发生的错误发生了,该测试可执行,该测试与我的静态库链接并提升的静态库(单位测试框架(
  • 所有静态库(Boost and Mine One(都使用-fPIC选项
  • 构建

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

从发布到红色帽子bugzilla错误的构建日志:

[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

注意/usr/bin/strip,而不是/opt/rh/devtoolset-7/root/usr/bin/strip。因此使用系统strip命令。42对应于R_X86_64_REX_GOTPCRELX重定位,该重定位是由DTS BinutilS生成的优化的。

使用此C 文件的简单方法是:

#include <iostream>
void
dot ()
{
  std::cout << '.';
}

如果使用-O2 -fpic编译,它将为_ZNSt8ios_base4InitD1Ev产生X86_64_REX_GOTPCRELX重定位。在其中运行/usr/bin/strip -g将把其转变为R_X86_64_NONE。可以使用eu-readelf -r

对此进行验证

您可以使用rpm使用

来告诉使用DTS strip
%if 0%{?scl:1}
%define __strip %{_bindir}/strip
%endif

在RPM规格文件中,您可以添加

%undefine __brp_strip_static_archive

完全跳过静态库(无论如何,这可能是正确的事情(。