New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 824983 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Last visit > 30 days ago
Closed: Apr 2018
Components:
EstimatedDays: ----
NextAction: ----
OS: Chrome
Pri: 2
Type: Bug
Build-Toolchain



Sign in to add a comment

media-libs/qhull fails to build when SHT_RELR sections are enabled

Project Member Reported by rahulchaudhry@chromium.org, Mar 22 2018

Issue description

I am testing support for SHT_RELR sections in chromium os. SHT_RELR sections are used to compactly store all the R_X86_64_RELATIVE relocations in a PIE binary or a shared object. For more background, see the official proposal here: https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg

SHT_RELR sections do not support relative relocations with odd offsets.
This results in media-libs/qhull failing to build when SHT_RELR sections are enabled.

Steps to reproduce:

1. setup_board --board=guado_moblab
2. build_packages --board=guado_moblab
3. cherry pick https://chromium-review.googlesource.com/967052
4. sudo emerge cross-x86_64-cros-linux-gnu/binutils
5. emerge-guado_moblab media-libs/qhull

fails with:

[100%] Linking CXX executable user_eg3
/usr/x86_64-pc-linux-gnu/x86_64-cros-linux-gnu/binutils-bin/2.27.0/ld.gold.real: internal error in shrink_relocs, at /var/tmp/portage/cross-x86_64-cros-linux-gnu/binutils-2.27.0-r7/work/binutils-2.27.0/binutils-2.27/gold/output.h:2527
clang-6.0: error: linker command failed with exit code 1 (use -v to see invocation)

when linking the 'user_eg3' binary.

The relevant assert in gold linker is just checking that the offset is not odd:

2526         // Odd addresses are not supported in SHT_RELR.
2527         gold_assert(current%2 == 0);

 
Reduced it to this minimized testcase:

---------------- test.cpp ----------------
char str[]= "..";

int foo(void) {
        return 0;
}

class bar {
};

int main(void) {
        try {
                return foo();
        } catch(bar &e) {
                return 1;
        }
}
------------------------------------------
$ clang++ -fPIE -pie -fuse-ld=gold test.cpp
/usr/x86_64-pc-linux-gnu/binutils-bin/2.27.0/ld.gold.real: internal error in shrink_relocs, at /var/tmp/portage/sys-devel/binutils-2.27.0-r7/work/binutils-2.27.0/binutils-2.27/gold/output.h:2527
clang-6.0: error: linker command failed with exit code 1 (use -v to see invocation)

The length of str is important (must be even), as is the presence of the try/catch block.

Looking inside the object file (same test.cpp source as above):

$ clang++ -fPIE -c test.cpp
$ objdump -D -M intel -rz test.o

# relevant sections from the output:
Disassembly of section .data:

0000000000000000 <str>:
   0:   2e 2e 00 00             cs add BYTE PTR cs:[rax],al
                        3: R_X86_64_64  _ZTI3bar
   4:   00 00                   add    BYTE PTR [rax],al
   6:   00 00                   add    BYTE PTR [rax],al
   8:   00 00                   add    BYTE PTR [rax],al
   a:   00                      .byte 0x0

Disassembly of section .data.rel.ro._ZTI3bar:

0000000000000000 <_ZTI3bar>:
   0:   00 00                   add    BYTE PTR [rax],al
                        0: R_X86_64_64  _ZTVN10__cxxabiv117__class_type_infoE+0x10
   2:   00 00                   add    BYTE PTR [rax],al
   4:   00 00                   add    BYTE PTR [rax],al
   6:   00 00                   add    BYTE PTR [rax],al
   8:   00 00                   add    BYTE PTR [rax],al
                        8: R_X86_64_64  _ZTS3bar
   a:   00 00                   add    BYTE PTR [rax],al
   c:   00 00                   add    BYTE PTR [rax],al
   e:   00 00                   add    BYTE PTR [rax],al

Disassembly of section .rodata._ZTS3bar:

0000000000000000 <_ZTS3bar>:
   0:   33 62 61                xor    esp,DWORD PTR [rdx+0x61]
   3:   72 00                   jb     5 <_ZTS3bar+0x5>


The R_X86_64_64 relocation in <str> at offset 3 is the one that turns into R_X86_64_RELATIVE with odd offset in the final binary.
Note that 'str' is defined as a string of length 2, so the first three bytes "2e 2e 00" are all of str.
Offset 3 has something else (a pointer) generated by the compiler that is not aligned to pointer size.
It is pointing to '_ZTI3bar', which is the typeinfo for class bar used in the try/catch block.

Looking at the generated assembly from clang++ (same test.cpp source as above):

$ clang++ -fPIE -S test.cpp

# relevant sections from test.s:
        .type   str,@object             # @str
        .data
        .globl  str
str:
        .asciz  ".."
        .size   str, 3

        .type   _ZTS3bar,@object        # @_ZTS3bar
        .section        .rodata._ZTS3bar,"aG",@progbits,_ZTS3bar,comdat
        .weak   _ZTS3bar
_ZTS3bar:
        .asciz  "3bar"
        .size   _ZTS3bar, 5

        .type   _ZTI3bar,@object        # @_ZTI3bar
        .section        .data.rel.ro._ZTI3bar,"aGw",@progbits,_ZTI3bar,comdat
        .weak   _ZTI3bar
        .p2align        3
_ZTI3bar:
        .quad   _ZTVN10__cxxabiv117__class_type_infoE+16
        .quad   _ZTS3bar
        .size   _ZTI3bar, 16

        .data
.L_ZTI3bar.DW.stub:
        .quad   _ZTI3bar


It is this last symbol, '.L_ZTI3bar.DW.stub' that ends up directly following 'str' in .data section.
Note that there is no '.p2align' directive for this symbol.
If I add an alignment directive in the assembly file:

          .data
+         .p2align        3
  .L_ZTI3bar.DW.stub:
          .quad   _ZTI3bar

And continue with the build, it links successfully:
$ clang++ -fPIE -c test.s
$ clang++ -pie -fuse-ld=gold test.o


Another thing to note is that this indirection for '_ZTI3bar' is only generated when compiling with -fPIE.

$ clang++ -S test.cpp

# '.L_ZTI3bar.DW.stub' is not generated. '_ZTI3bar' is referenced directly from inside <main>.

Another thing to note is that building with g++ works fine, both in pie and non-pie modes.
g++ doesn't generate or reference any of the '.L_ZTI3bar.DW.stub', '_ZTI3bar', or '_ZTS3bar' symbols in the output.

Owner: rahulchaudhry@chromium.org
Status: Assigned (was: Untriaged)
Sent a patch upstream for review: https://reviews.llvm.org/D44848
Project Member

Comment 7 by bugdroid1@chromium.org, Mar 30 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/9615b4b6f3febf815571ec4e45f221af4f981113

commit 9615b4b6f3febf815571ec4e45f221af4f981113
Author: Rahul Chaudhry <rahulchaudhry@chromium.org>
Date: Fri Mar 30 02:51:32 2018

sys-devel/llvm: apply a patch to align compiler generated stubs.

Align stubs for external and common global variables to pointer size.

Locally patch differential revision https://reviews.llvm.org/D44848
until it is merged upstream.

BUG= chromium:822053 
BUG= chromium:824983 
TEST='sudo emerge sys-devel/llvm' works.
TEST='emerge-chell sys-devel/gdb' works with SHT_RELR sections enabled in gold.
TEST='emerge-guado_moblab media-libs/qhull' works with SHT_RELR sections enabled in gold.

Change-Id: I4305fda5b801664be2090f103808ef32655e6931
Reviewed-on: https://chromium-review.googlesource.com/984778
Commit-Ready: Rahul Chaudhry <rahulchaudhry@chromium.org>
Tested-by: Rahul Chaudhry <rahulchaudhry@chromium.org>
Reviewed-by: Manoj Gupta <manojgupta@chromium.org>

[rename] https://crrev.com/9615b4b6f3febf815571ec4e45f221af4f981113/sys-devel/llvm/llvm-7.0_pre326829_p20180318-r3.ebuild
[rename] https://crrev.com/9615b4b6f3febf815571ec4e45f221af4f981113/sys-devel/gdb/gdb-8.0.1.20171030-r5.ebuild
[modify] https://crrev.com/9615b4b6f3febf815571ec4e45f221af4f981113/sys-devel/gdb/gdb-8.0.1.20171030.ebuild
[add] https://crrev.com/9615b4b6f3febf815571ec4e45f221af4f981113/sys-devel/llvm/files/llvm-7.0-stub-alignment.patch

Sign in to add a comment