llvm/lld/test/ELF/x86-64-gotpc-relax-too-far.s

# REQUIRES: x86
# RUN: split-file %s %t
# RUN: llvm-mc -filetype=obj -triple=x86_64 %t/a.s -o %t/a.o
# RUN: ld.lld -T %t/lds1 %t/a.o -o %t/bin
# RUN: llvm-objdump -d %t/bin | FileCheck --check-prefix=DISASM %s
# RUN: llvm-readelf -S %t/bin | FileCheck --check-prefixes=GOT %s
# RUN: ld.lld -T %t/lds2 %t/a.o -o %t/bin2
# RUN: llvm-objdump -d %t/bin2 | FileCheck --check-prefix=DISASM %s
# RUN: llvm-readelf -S %t/bin2 | FileCheck --check-prefixes=GOT %s
# RUN: ld.lld -T %t/lds3 %t/a.o -o %t/bin3
# RUN: llvm-readelf -S %t/bin3 | FileCheck --check-prefixes=UNNECESSARY-GOT %s
# RUN: ld.lld -T %t/lds4 %t/a.o -o %t/bin4
# RUN: llvm-objdump -d %t/bin4 | FileCheck --check-prefix=DISASM4 %s

# DISASM:      <_foo>:
# DISASM-NEXT: movl    0x1ffffa(%rip), %eax
# DISASM-NEXT: addq    0x1ffffb(%rip), %rax
# DISASM-NEXT: addq    $0x7fffffff, %rax
# DISASM:      <_start>:
# DISASM-NEXT: movl    0x10000a(%rip), %eax
# DISASM-NEXT: movq    0x100003(%rip), %rax
# DISASM-NEXT: leaq    0x7ffffff9(%rip), %rax
# DISASM-NEXT: leal    0x7ffffff3(%rip), %eax

# DISASM4:      <_foo>:
# DISASM4-NEXT: leal    0x7fffeffa(%rip), %eax
# DISASM4-NEXT: addq    0x1ff3(%rip), %rax
# DISASM4-NEXT: addq    $0x7fffffff, %rax

# In our implementation, .got is retained even if all GOT-generating relocations are optimized.
# Make sure .got still exists with the right size.
# UNNECESSARY-GOT: .got PROGBITS 0000000000300000 101020 000000 00 WA 0 0 8
#             GOT: .got PROGBITS 0000000000300000 102000 000018 00 WA 0 0 8

#--- a.s
.section .text.foo,"ax"
.globl _foo
.type _foo, @function
_foo:
  movl __start_data@GOTPCREL(%rip), %eax  # out of range
  addq foo_1@GOTPCREL(%rip), %rax         # out of range
  addq foo@GOTPCREL(%rip), %rax           # in range

.section .text,"ax"
.globl _start
.type _start, @function
_start:
  movl __stop_data@GOTPCREL(%rip), %eax  # out of range
  movq __stop_data@GOTPCREL(%rip), %rax  # out of range
  movq __stop_data@GOTPCREL(%rip), %rax  # in range
  movl __stop_data@GOTPCREL(%rip), %eax  # in range

.section foo,"aw",@progbits
.space 1
foo_1:
.space 1

.section data,"aw",@progbits
.space 13

#--- lds1
SECTIONS {
  .text.foo 0x100000 : { *(.text.foo) }
  .text 0x200000 : { *(.text) }
  .got 0x300000 : { *(.got) }
  foo 0x7fffffff : { *(foo) }
  data 0x80200000 : { *(data) }
}
#--- lds2
SECTIONS {
  .text.foo 0x100000 : { *(.text.foo) }
  .text 0x1ff000 : { . = . + 0x1000 ; *(.text) }
  .got 0x300000 : { *(.got) }
  foo 0x7fffffff : { *(foo) }
  data 0x80200000 : { *(data) }
}
#--- lds3
SECTIONS {
  .text.foo 0x100000 : { *(.text.foo) }
  .text 0x200000 : { *(.text) }
  .got 0x300000 : { *(.got) }
  data 0x400000 : { *(data) }
}

#--- lds4
## Max VA difference < 0x80000000
SECTIONS {
  .text.foo 0x02000 : { *(.text.foo) }
  .text 0x3000 : { *(.text) }
  .got 0x4000 : { *(.got) }
  foo 0x7fffffff : { *(foo) }
  data 0x80001000 : { *(data) }
}