[PATCH] D91965: Revert "[X86] Produce R_X86_64_GOTPCRELX for test/binop instructions (MOV32rm/TEST32rm/...) when -Wa,-mrelax-relocations=yes is enabled"
Stephan Bergmann via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 23 07:07:04 PST 2020
sberg created this revision.
sberg added reviewers: MaskRay, craig.topper.
Herald added subscribers: pengfei, hiraditya, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.
sberg requested review of this revision.
After just having wasted a day scratching my head why a UBSan build on another machine now started to fail, after I had already forgotten about this issue again, here's a revert now:
This reverts commit f04d92af94a8d763e91ae38fe35319e426dc466c, which causes
miscompilation, as first reported at
<http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20201026/845488.html>
"Re: [llvm] f04d92a - [X86] Produce R_X86_64_GOTPCRELX for test/binop
instructions (MOV32rm/TEST32rm/...) when -Wa, -mrelax-relocations=yes is
enabled":
At least on Linux x86-64 in combination with lld, this causes miscompilation
when an expression like
((long) otherfunction) >> 32
computing the upper 32 bits of a function's address is emitted as
movl otherfunction at GOTPCREL+4(%rip), %eax
which lld then optimizes as
lea otherfunction+4(%rip), %eax
computing the lower 32 bits of the function's address + 4.
The simplest reproducer I came up with is
> $ cat test.c
> void otherfunction(void);
> int __attribute__ ((visibility("default"))) test1(void) { return (long) otherfunction; }
> int __attribute__ ((visibility("default"))) test2(void) { return ((long) otherfunction) >> 32; }
>
> $ cat otherfunction.c
> void otherfunction(void) {}
>
> $ cat main.c
> #include <stdio.h>
> int test1(void);
> int test2(void);
> int main() {
> printf("%08X %08X\n", test1(), test2());
> return 0;
> }
>
> $ llvm/inst/bin/clang -fpic -fvisibility=hidden -O -c test.c
> $ objdump -dr test.o | grep -F -A3 '<test'
> 0000000000000000 <test1>:
> 0: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 6 <test1+0x6>
> 2: R_X86_64_GOTPCRELX otherfunction-0x4
> 6: c3 retq
> 7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
> --
> 0000000000000010 <test2>:
> 10: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 16 <test2+0x6>
> 12: R_X86_64_GOTPCRELX otherfunction
> 16: c3 retq
>
> $ llvm/inst/bin/clang -fpic -fvisibility=hidden -c otherfunction.c
>
> $ llvm/inst/bin/clang -fuse-ld=lld --ld-path=/.../llvm/inst/bin/ld.lld -shared test.o otherfunction.o -o libtest.so
> $ objdump -dR libtest.so | grep -F -A3 '<test'
> 00000000000015d0 <test1>:
> 15d0: 8d 05 1a 00 00 00 lea 0x1a(%rip),%eax # 15f0 <otherfunction>
> 15d6: c3 retq
> 15d7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
> --
> 00000000000015e0 <test2>:
> 15e0: 8d 05 0e 00 00 00 lea 0xe(%rip),%eax # 15f4 <otherfunction+0x4>
> 15e6: c3 retq
> 15e7: cc int3
>
> $ llvm/inst/bin/clang main.c libtest.so
> $ LD_LIBRARY_PATH=. ./a.out
> 602065F0 602065F4
where using R_X86_64_GOTPCRELX instead of R_X86_64_GOTPCREL in test2 causes the
second value printed out to be (first value + 4) instead of some 00007F55 or
similar.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D91965
Files:
llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
llvm/test/MC/ELF/got-relaxed.s
llvm/test/MC/ELF/got.s
llvm/test/MC/X86/gotpcrelx.s
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D91965.307069.patch
Type: text/x-patch
Size: 4717 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201123/5a42416d/attachment.bin>
More information about the llvm-commits
mailing list