https://sourceware.org/bugzilla/show_bug.cgi?id=23968
Bug ID: 23968 Summary: GOTPCREL(%rip) references against .local symbols generate invalid code in -mrelax-relocations=no mode (chromium build crashes) Product: binutils Version: 2.31 Status: UNCONFIRMED Severity: normal Priority: P2 Component: gas Assignee: unassigned at sourceware dot org Reporter: slyfox at inbox dot ru Target Milestone: --- sultan on freenode/#gentoo-toolchain reported a chromium build failure when CFLAGS=-Wa,-mrelax-relocations=no is used. sultan uses it to have whole system compatible with old binutils without R_X86_64_REX_GOTPCRELX support. I expored a failure a bit and am not sure if it's a chromium bug or binutils/gas bug. I'm leaning towards binutils/gas. Here is the minimal single-file example: typedef unsigned char u8; /* extracted from chromium-71.0.3578.80/work/chromium-71.0.3578.80/out/Release/gen/v8/embedded.cc # --enable-x86-relax-relocations $ x86_64-pc-linux-gnu-g++ -fPIC -O0 -Wa,-mrelax-relocations=yes a-yes.o -o a-yes $ ./a-yes 42 # works # --disable-x86-relax-relocations $ x86_64-pc-linux-gnu-g++ -fPIC -O0 -Wa,-mrelax-relocations=no a-no.o -o a-no $ ./a-no <SIGSEGV> # fails */ namespace { __asm__( ".section .text\n" ".local v8_Default_embedded_blob_\n" //This would work: //".global v8_Default_embedded_blob_\n" //".hidden v8_Default_embedded_blob_\n" "v8_Default_embedded_blob_:\n" // some raw injected data ".byte 0x42\n" ); extern "C" const u8 v8_Default_embedded_blob_[]; } const u8* DefaultEmbeddedBlob(void) { // generates reference // movq v8_Default_embedded_blob_@GOTPCREL(%rip), %rax // is it valid for .local symbols? // If it's invalid should it be forbidden by gas? If it's valid // should it always generate a reloc here? return v8_Default_embedded_blob_; } // test main.c: #include <stdio.h> int main() { printf ("b0=%02X\n", DefaultEmbeddedBlob()[0]); } The culprit here is in a mix of .local / @GOTPCREL(%rip) references. It works for -mrelax-relocations=yes but does not for -mrelax-relocations=no. Can binutils do the same thing in both cases? I would suggest: - either generate relocation in both cases - or forbid @GOTPCREL references against .local symbols and fail the assembly Investigation notes: Assembly file is the same in both cases. Object file difference is the following: $ x86_64-pc-linux-gnu-g++ -fPIC -O0 -Wa,-mrelax-relocations=no -c embedded.o.cc -o a-no.o $ x86_64-pc-linux-gnu-g++ -fPIC -O0 -Wa,-mrelax-relocations=yes -c embedded.o.cc -o a-yes.o $ objdump -d -r a-no.o > a-no.od $ objdump -d -r a-yes.o > a-yes.od $ diff -u a-no.od a-yes.od Disassembly of section .text: @@ -10,7 +10,8 @@ 0000000000000001 <_Z19DefaultEmbeddedBlobv>: 1: 55 push %rbp 2: 48 89 e5 mov %rsp,%rbp - 5: 48 8b 05 f4 ff ff ff mov -0xc(%rip),%rax # 0 <v8_Default_embedded_blob_> + 5: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # c <_Z19DefaultEmbeddedBlobv+0xb> + 8: R_X86_64_REX_GOTPCRELX v8_Default_embedded_blob_-0x4 c: 5d pop %rbp d: c3 retq Here 'no' case has extra memory dereference as if '-0xc(%rip)' would be a GOT entry for v8_Default_embedded_blob_. Or 'mov' was used by accident instead of 'lea'. Final binary change: $ x86_64-pc-linux-gnu-g++ -fPIC -O0 -Wa,-mrelax-relocations=no a-no.o -o a-no $ x86_64-pc-linux-gnu-g++ -fPIC -O0 -Wa,-mrelax-relocations=yes a-yes.o -o a-yes $ objdump -d -R a-no > a-no.od $ objdump -d -R a-yes > a-yes.od $ diff -u a-no.od a-yes.od Disassembly of section .init: @@ -115,7 +115,7 @@ 000000000000064b <_Z19DefaultEmbeddedBlobv>: 64b: 55 push %rbp 64c: 48 89 e5 mov %rsp,%rbp - 64f: 48 8b 05 f4 ff ff ff mov -0xc(%rip),%rax # 64a <v8_Default_embedded_blob_> + 64f: 48 8d 05 f4 ff ff ff lea -0xc(%rip),%rax # 64a <v8_Default_embedded_blob_> 656: 5d pop %rbp 657: c3 retq Thanks! -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils