Bug 1545386

Summary: Unresolvable `R_X86_64_NONE` relocation
Product: Red Hat Developer Toolset Reporter: Alex Turbov <i.zaufi>
Component: binutilsAssignee: Nick Clifton <nickc>
Status: CLOSED CURRENTRELEASE QA Contact: Martin Cermak <mcermak>
Severity: unspecified Docs Contact: Vladimír Slávik <vslavik>
Priority: unspecified    
Version: DTS 7.1 RHEL 7CC: fweimer, kanderso, law, mcermak, mnewsome, mpolacek, mprchlik, ohudlick, vslavik
Target Milestone: alpha   
Target Release: 8.0   
Hardware: x86_64   
OS: Linux   
URL: https://stackoverflow.com/questions/48706962/unresolvable-r-x86-64-none-relocation
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Cause: The BFD library would convert any unknown relocation into a null relocation. Consequence: If the strip program was used to strip a binary created by an assembler that used a newer version of the BFD library, any relocations unknown to strip would be silently converted into null relocations, thus breaking the binary. Fix: Modify the BFD library so that it reports unknown relocations, but it does not modify them. Result: Strip will now generate an error message and refuse to strip any binary containing relocations that it does not recognise.
Story Points: ---
Clone Of:
: 1553842 1653797 (view as bug list) Environment:
Last Closed: 2020-06-05 08:17:14 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1553842, 1653797, 1653798, 1660547, 1660549    
Attachments:
Description Flags
Full CLI of `g++ -v`
none
Archive w/ *.o and boost test FW static lib
none
Boost build log
none
The RPM spec used to build Boost for DTS-7 none

Description Alex Turbov 2018-02-14 19:41:35 UTC
Created attachment 1396120 [details]
Full CLI of `g++ -v`

Description of problem:

From: https://stackoverflow.com/questions/48706962/unresolvable-r-x86-64-none-relocation


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/bin/c++  -g   -Wl,--no-as-needed CMakeFiles/core_unit_tests.dir/Text.cpp.o CMakeFiles/core_unit_tests.dir/unit_tests_main.cc.o  -o core_unit_tests /opt/rh/devtoolset-7/root/usr/lib64/libboost_unit_test_framework.a 
/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(progress_monitor.o)(.text+0x3f): unresolvable R_X86_64_NONE relocation against symbol `_ZSt4cout@@GLIBCXX_3.4'
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: final link failed: Nonrepresentable section on output

Comment 2 Alex Turbov 2018-02-14 19:45:37 UTC
Created attachment 1396121 [details]
Archive w/ *.o and boost test FW static lib

Comment 3 Florian Weimer 2018-02-14 22:26:59 UTC
(In reply to Alex Turbov from comment #2)
> Created attachment 1396121 [details]
> Archive w/ *.o and boost test FW static lib

Where did you obtain libboost_unit_test_framework.a?  It looks corrupted.  Did you build it yourself?  If yes, which toolchain did you use?  Do you have build logs?

Comment 4 Alex Turbov 2018-02-15 03:32:34 UTC
Created attachment 1396250 [details]
Boost build log

Comment 5 Florian Weimer 2018-02-15 06:40:16 UTC
From the build log:

[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

There are a couple of bugs here.

The RPM build does not use the strip command from DTS.  /usr/bin/strip (from binutils 2.25) does not recognize the new R_X86_64_REX_GOTPCRELX relocation that DTS binutils produces.  /usr/lib/rpm/brp-strip-static-archive ignores the exit status of /usr/bin/strip, and since that program updates the object file in place, it leaves behind a corrupted file, which is then packaged by RPM.

Red Hat Enterprise Linux 7.5 will have a newer system binutils which is able to process the relocation.

Another workaround is to add 

%undefine __brp_strip_static_archive

to the spec file, which will produce a static library with debugging information (which I would personally prefer anyway).

Comment 6 Florian Weimer 2018-02-15 07:28:30 UTC
By the way, could you attach the RPM spec file you use for building Boost?  I wonder if there is a way we can switch the debuginfo stripping to DTS strip.

Comment 7 Alex Turbov 2018-02-15 07:50:20 UTC
Created attachment 1396307 [details]
The RPM spec used to build Boost for DTS-7

Comment 8 Alex Turbov 2018-02-15 13:55:30 UTC
Another workaround, detect if RPM builds under the `devtoolset-N` and redefine `_strip` to proper location:

%global __strip %{_bindir}/strip

Comment 12 Nick Clifton 2018-02-22 12:43:35 UTC
Just discovered another bug with strip.  When it does encounter an unknown
reloc, it not only replaces it with a null relocation (which is why the
output is corrupt), it also does not return a failure exit status.  So even
if brp-strip-static-archive is as it should be, that will not resolve this
particular problem. :-(

Comment 13 Nick Clifton 2018-02-22 13:11:07 UTC
I have reported the strip bug(s) upstream:

https://sourceware.org/bugzilla/show_bug.cgi?id=22875

Comment 14 Nick Clifton 2018-02-27 17:21:01 UTC
Deferring to DTS-8

Comment 15 Nick Clifton 2018-07-11 11:45:36 UTC
Fixed.  (Actually fixed a while ago, but I forgot to update this BZ).

Comment 16 Miloš Prchlík 2020-06-05 08:17:14 UTC
Verified with DTS 9.1, with devtoolset-9-binutils-2.32-16.el7.x86_64.