11

I'm using Devtoolset-7 on CentOS 7 and have built Boost 1.65.1 w/ it. But when I link my application, I've got the following:

/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

Searching more info about R_X86_64_NONE doesn't give any valuable results: mostly similar questions w/o any answer or precise explanation what is this and how to solve it.

So my questions are:

  • what is this error really means?
  • what is R_X86_64_NONE and why "nothing to relocate" (according to bintils sources) type of symbol ever exists in ELF headers?

Addendum:

  • The error happened on linking unit tests executable which is linked against my static library and Boosts' static libraries (unit tests framework)
  • All static libraries (Boost and mine one) has built with -fPIC option

PS. I really want this question to be resolved once and forever (already hit it few times, but this time update to latest binutils doesn't help). (will start a bounty on any activity on this question)

zaufi
  • 6,811
  • 26
  • 34
  • You might have more luck with a recent LLVM based compiler such as clang (https://reviews.llvm.org/rL288485) – OMGtechy Feb 09 '18 at 13:38
  • unfortunately I need GCC 7.x %) – zaufi Feb 09 '18 at 13:39
  • Have you installed GCC 7 yourself? Did you build Boost yourself? With the same compiler/linker and standard library (including *version*) as you use for your application? I haven't had this error myself, but by reading similar questions it mostly seems to be a problem about mismatching compiler/linker/standard library versions. – Some programmer dude Feb 09 '18 at 13:44
  • I've used GCC/Binutils from Devtoolset 7. Boost has built w/ the RPM spec adopted for SCL and compiled w/ DTS7 toolchain as well. – zaufi Feb 09 '18 at 13:47
  • @zaufi Can you post a minimal set of object files which trigger this somewhere? You could open a bug in Bugzilla, for instance. I have never seen any object files which trigger this, and no one apparently has filed a proper bug report. – Florian Weimer Feb 13 '18 at 19:58
  • @zaufi, I need the exact linker invocation (as shown with `g++ -v`) and a tarball with all the input files (at least those which are not part of the distribution/software collection). – Florian Weimer Feb 14 '18 at 16:14
  • @FlorianWeimer, please tell me the bug tracker URL to post it (I don't this SO is a right place for that %) – zaufi Feb 14 '18 at 17:58
  • [Developer Toolset, `binutils` component](https://bugzilla.redhat.com/enter_bug.cgi?product=Red%20Hat%20Developer%20Toolset&component=binutils) This is the component which contains the linker. – Florian Weimer Feb 14 '18 at 18:22
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/165180/discussion-between-zaufi-and-florian-weimer). – zaufi Feb 14 '18 at 19:47

1 Answers1

10

From the 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

Note /usr/bin/strip, not /opt/rh/devtoolset-7/root/usr/bin/strip. So the system strip command is used. 42 corresponds to the R_X86_64_REX_GOTPCRELX relocation, which is generated by DTS binutils as an optimization.

A simple way to reproduce this is with this C++ file:

#include <iostream>

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

If compile with -O2 -fpic, it will produce an X86_64_REX_GOTPCRELX relocation for _ZNSt8ios_base4InitD1Ev. Running /usr/bin/strip -g on that will turn that into R_X86_64_NONE. This can be verified using eu-readelf -r.

You can use RPM to tell to use the DTS strip using

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

in the RPM spec file, or you can add

%undefine __brp_strip_static_archive

to skip stripping the static library completely (which is probably the right thing to do anyway).

zaufi
  • 6,811
  • 26
  • 34
Florian Weimer
  • 32,022
  • 3
  • 48
  • 92