gpt4 book ai didi

c++ - 无法解析的 `R_X86_64_NONE` 重定位

转载 作者:可可西里 更新时间:2023-11-01 17:49:14 25 4
gpt4 key购买 nike

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

/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 的更多信息没有给出任何有值(value)的结果:主要是 similar questions没有任何答案或精确解释这是什么以及如何解决它。

所以我的问题是:

  • 这个错误的真正含义是什么?
  • 什么是 R_X86_64_NONE 以及为什么在 ELF header 中存在“无需重新定位”(根据 bintils 来源)类型的符号?

附录:

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

附言。我真的希望这个问题一劳永逸地解决(已经打了几次,但这次更新到最新的 binutils 没有帮助)。 (将开始对这个问题的任何事件进行赏金)

最佳答案

来自build log posted to the 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

注意 /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 using

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

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

%undefine __brp_strip_static_archive

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

关于c++ - 无法解析的 `R_X86_64_NONE` 重定位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48706962/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com