diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -828,7 +828,8 @@ write32le(loc, val); } -void X86_64::relaxGot(uint8_t *loc, const Relocation &, uint64_t val) const { +void X86_64::relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const { + checkInt(loc, val, 32, rel); const uint8_t op = loc[-2]; const uint8_t modRm = loc[-1]; diff --git a/lld/test/ELF/x86-64-gotpc-err.s b/lld/test/ELF/x86-64-gotpc-err.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/x86-64-gotpc-err.s @@ -0,0 +1,25 @@ +# REQUIRES: x86 +# RUN: split-file %s %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 %t/a.s -o %t/a.o +# RUN: not ld.lld -T %t/lds %t/a.o -o /dev/null 2>&1 | FileCheck %s + +# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483655 is not in [-2147483648, 2147483647]; references data +# CHECK: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483648 is not in [-2147483648, 2147483647]; references data +# CHECK-NOT: error: + +#--- a.s + movl data@GOTPCREL(%rip), %eax # out of range + movq data@GOTPCREL(%rip), %rax # out of range + movq data@GOTPCREL(%rip), %rax # in range + +.data +.space 13 +.globl data +data: + .long 0 + +#--- lds +SECTIONS { + .text 0x200000 : { *(.text) } + .data 0x80200000 : { *(.data) } +}