[ELF] Don't crash on R_X86_64_GOTPCRELX for test/binop instructions
authorFangrui Song <i@maskray.me>
Sat, 24 Oct 2020 22:13:47 +0000 (15:13 -0700)
committerFangrui Song <i@maskray.me>
Sat, 24 Oct 2020 22:14:17 +0000 (15:14 -0700)
While MC did not produce R_X86_64_GOTPCRELX for test/binop instructions
(movl/adcl/addl/andl/...) before the previous commit, this code path has been
exercised by -fno-integrated-as for GNU as since 2016: -no-pie relaxing
may incorrectly access loc[-3] and produce a corrupted instruction.

Simply handle test/binop R_X86_64_GOTPCRELX like R_X86_64_GOTPCREL.

lld/ELF/Arch/X86_64.cpp
lld/test/ELF/x86-64-gotpc-relax-nopic.s

index 24711ec..93fd8ec 100644 (file)
@@ -746,11 +746,12 @@ RelExpr X86_64::adjustRelaxExpr(RelType type, const uint8_t *data,
   if (op == 0xff && (modRm == 0x15 || modRm == 0x25))
     return R_RELAX_GOT_PC;
 
+  // We don't support test/binop instructions without a REX prefix.
+  if (type == R_X86_64_GOTPCRELX)
+    return relExpr;
+
   // Relaxation of test, adc, add, and, cmp, or, sbb, sub, xor.
   // If PIC then no relaxation is available.
-  // We also don't relax test/binop instructions without REX byte,
-  // they are 32bit operations and not common to have.
-  assert(type == R_X86_64_REX_GOTPCRELX);
   return config->isPic ? relExpr : R_RELAX_GOT_PC_NOPIC;
 }
 
index b927ecf..501414f 100644 (file)
@@ -1,8 +1,8 @@
 # REQUIRES: x86
 # RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-unknown-linux %s -o %t.o
-# RUN: ld.lld --hash-style=sysv %t.o -o %t1
+# RUN: ld.lld %t.o -o %t1
 # RUN: llvm-readobj --symbols -r %t1 | FileCheck --check-prefix=SYMRELOC %s
-# RUN: llvm-objdump -d --no-show-raw-insn %t1 | FileCheck --check-prefix=DISASM %s
+# RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t1 | FileCheck --check-prefix=DISASM %s
 
 ## There is no relocations.
 # SYMRELOC:      Relocations [
 # SYMRELOC:      Symbols [
 # SYMRELOC:       Symbol {
 # SYMRELOC:        Name: bar
-# SYMRELOC-NEXT:   Value: 0x202197
+# SYMRELOC-NEXT:   Value: 0x203248
 
 ## 2105751 = 0x202197 (bar)
 # DISASM:      Disassembly of section .text:
 # DISASM-EMPTY:
 # DISASM-NEXT: <_start>:
-# DISASM-NEXT:   201158:       adcq  $2105751, %rax
-# DISASM-NEXT:                 addq  $2105751, %rbx
-# DISASM-NEXT:                 andq  $2105751, %rcx
-# DISASM-NEXT:                 cmpq  $2105751, %rdx
-# DISASM-NEXT:                 orq   $2105751, %rdi
-# DISASM-NEXT:                 sbbq  $2105751, %rsi
-# DISASM-NEXT:                 subq  $2105751, %rbp
-# DISASM-NEXT:                 xorq  $2105751, %r8
-# DISASM-NEXT:                 testq $2105751, %r15
+# DISASM-NEXT:   2011c8:       adcl  {{.*}}(%rip), %eax  # 202240
+# DISASM-NEXT:                 addl  {{.*}}(%rip), %ebx  # 202240
+# DISASM-NEXT:                 andl  {{.*}}(%rip), %ecx  # 202240
+# DISASM-NEXT:                 cmpl  {{.*}}(%rip), %edx  # 202240
+# DISASM-NEXT:                 orl   {{.*}}(%rip), %edi  # 202240
+# DISASM-NEXT:                 sbbl  {{.*}}(%rip), %esi  # 202240
+# DISASM-NEXT:                 subl  {{.*}}(%rip), %ebp  # 202240
+# DISASM-NEXT:                 xorl  {{.*}}(%rip), %r8d  # 202240
+# DISASM-NEXT:                 testl %r15d, {{.*}}(%rip) # 202240
+# DISASM-NEXT:   201200:       adcq  $0x203248, %rax
+# DISASM-NEXT:                 addq  $0x203248, %rbx
+# DISASM-NEXT:                 andq  $0x203248, %rcx
+# DISASM-NEXT:                 cmpq  $0x203248, %rdx
+# DISASM-NEXT:                 orq   $0x203248, %rdi
+# DISASM-NEXT:                 sbbq  $0x203248, %rsi
+# DISASM-NEXT:                 subq  $0x203248, %rbp
+# DISASM-NEXT:                 xorq  $0x203248, %r8
+# DISASM-NEXT:                 testq $0x203248, %r15
 
 # RUN: ld.lld --hash-style=sysv -shared %t.o -o %t2
 # RUN: llvm-readobj -S -r -d %t2 | FileCheck --check-prefix=SEC-PIC    %s
@@ -37,8 +46,8 @@
 # SEC-PIC-NEXT:     SHF_ALLOC
 # SEC-PIC-NEXT:     SHF_WRITE
 # SEC-PIC-NEXT:   ]
-# SEC-PIC-NEXT:   Address: 0x2348
-# SEC-PIC-NEXT:   Offset: 0x348
+# SEC-PIC-NEXT:   Address: 0x2380
+# SEC-PIC-NEXT:   Offset: 0x380
 # SEC-PIC-NEXT:   Size: 8
 # SEC-PIC-NEXT:   Link:
 # SEC-PIC-NEXT:   Info:
 # SEC-PIC:      0x000000006FFFFFF9 RELACOUNT            1
 # SEC-PIC:      Relocations [
 # SEC-PIC-NEXT:   Section ({{.*}}) .rela.dyn {
-# SEC-PIC-NEXT:     0x2348 R_X86_64_RELATIVE - 0x3350
+# SEC-PIC-NEXT:     0x2380 R_X86_64_RELATIVE - 0x3388
 # SEC-PIC-NEXT:   }
 # SEC-PIC-NEXT: ]
 
 ## Check that there was no relaxation performed. All values refer to got entry.
-## Ex: 0x1000 + 4249 + 7 = 0x20A0
-##     0x102a + 4207 + 7 = 0x20A0
 # DISASM-PIC:      Disassembly of section .text:
 # DISASM-PIC-EMPTY:
 # DISASM-PIC-NEXT: <_start>:
-# DISASM-PIC-NEXT: 1268:       adcq  4313(%rip), %rax
-# DISASM-PIC-NEXT:             addq  4306(%rip), %rbx
-# DISASM-PIC-NEXT:             andq  4299(%rip), %rcx
-# DISASM-PIC-NEXT:             cmpq  4292(%rip), %rdx
-# DISASM-PIC-NEXT:             orq   4285(%rip), %rdi
-# DISASM-PIC-NEXT:             sbbq  4278(%rip), %rsi
-# DISASM-PIC-NEXT:             subq  4271(%rip), %rbp
-# DISASM-PIC-NEXT:             xorq  4264(%rip), %r8
-# DISASM-PIC-NEXT:             testq %r15, 4257(%rip)
+# DISASM-PIC-NEXT: 1268:       adcl  {{.*}}(%rip), %eax  # 2380
+# DISASM-PIC-NEXT:             addl  {{.*}}(%rip), %ebx  # 2380
+# DISASM-PIC-NEXT:             andl  {{.*}}(%rip), %ecx  # 2380
+# DISASM-PIC-NEXT:             cmpl  {{.*}}(%rip), %edx  # 2380
+# DISASM-PIC-NEXT:             orl   {{.*}}(%rip), %edi  # 2380
+# DISASM-PIC-NEXT:             sbbl  {{.*}}(%rip), %esi  # 2380
+# DISASM-PIC-NEXT:             subl  {{.*}}(%rip), %ebp  # 2380
+# DISASM-PIC-NEXT:             xorl  {{.*}}(%rip), %r8d  # 2380
+# DISASM-PIC-NEXT:             testl %r15d, {{.*}}(%rip) # 2380
+# DISASM-PIC-NEXT: 12a0:       adcq  {{.*}}(%rip), %rax  # 2380
+# DISASM-PIC-NEXT:             addq  {{.*}}(%rip), %rbx  # 2380
+# DISASM-PIC-NEXT:             andq  {{.*}}(%rip), %rcx  # 2380
+# DISASM-PIC-NEXT:             cmpq  {{.*}}(%rip), %rdx  # 2380
+# DISASM-PIC-NEXT:             orq   {{.*}}(%rip), %rdi  # 2380
+# DISASM-PIC-NEXT:             sbbq  {{.*}}(%rip), %rsi  # 2380
+# DISASM-PIC-NEXT:             subq  {{.*}}(%rip), %rbp  # 2380
+# DISASM-PIC-NEXT:             xorq  {{.*}}(%rip), %r8   # 2380
+# DISASM-PIC-NEXT:             testq %r15, {{.*}}(%rip)  # 2380
 
 .data
 .type   bar, @object
@@ -78,6 +94,18 @@ bar:
 .globl  _start
 .type   _start, @function
 _start:
+## R_X86_64_GOTPCRELX
+  adcl    bar@GOTPCREL(%rip), %eax
+  addl    bar@GOTPCREL(%rip), %ebx
+  andl    bar@GOTPCREL(%rip), %ecx
+  cmpl    bar@GOTPCREL(%rip), %edx
+  orl     bar@GOTPCREL(%rip), %edi
+  sbbl    bar@GOTPCREL(%rip), %esi
+  subl    bar@GOTPCREL(%rip), %ebp
+  xorl    bar@GOTPCREL(%rip), %r8d
+  testl   %r15d, bar@GOTPCREL(%rip)
+
+## R_X86_64_REX_GOTPCRELX
   adcq    bar@GOTPCREL(%rip), %rax
   addq    bar@GOTPCREL(%rip), %rbx
   andq    bar@GOTPCREL(%rip), %rcx