[llvm] f04d92a - [X86] Produce R_X86_64_GOTPCRELX for test/binop instructions (MOV32rm/TEST32rm/...) when -Wa, -mrelax-relocations=yes is enabled

Stephan Bergmann via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 2 01:13:00 PST 2020


On 26/10/2020 23:07, Stephan Bergmann wrote:
> On 25/10/2020 00:14, Fangrui Song via llvm-commits wrote:
>>
>> Author: Fangrui Song
>> Date: 2020-10-24T15:14:17-07:00
>> New Revision: f04d92af94a8d763e91ae38fe35319e426dc466c
>>
>> URL: 
>> https://github.com/llvm/llvm-project/commit/f04d92af94a8d763e91ae38fe35319e426dc466c 
>>
>> DIFF: 
>> https://github.com/llvm/llvm-project/commit/f04d92af94a8d763e91ae38fe35319e426dc466c.diff 
>>
>>
>> LOG: [X86] Produce R_X86_64_GOTPCRELX for test/binop instructions 
>> (MOV32rm/TEST32rm/...) when -Wa,-mrelax-relocations=yes is enabled
>>
>> We have been producing R_X86_64_REX_GOTPCRELX (MOV64rm/TEST64rm/...) and
>> R_X86_64_GOTPCRELX for CALL64m/JMP64m without the REX prefix since 
>> 2016 (to be
>> consistent with GNU as), but not for MOV32rm/TEST32rm/...
>>
>> Added:
>>      llvm/test/MC/X86/gotpcrelx.s
>>
>> Modified:
>>      llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
>>      llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
>>      llvm/test/MC/ELF/got.s
>>
>> Removed:
>>      llvm/test/MC/ELF/got-relaxed.s
> 
> 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=/home/sbergman/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.

Any update on this?  Shall we revert 
<https://github.com/llvm/llvm-project/commit/f04d92af94a8d763e91ae38fe35319e426dc466c> 
"[X86] Produce R_X86_64_GOTPCRELX for test/binop instructions 
(MOV32rm/TEST32rm/...) when -Wa,-mrelax-relocations=yes is enabled" for now?



More information about the llvm-commits mailing list