diff options
| -rw-r--r-- | lld/ELF/Writer.cpp | 10 | ||||
| -rw-r--r-- | lld/test/elf2/relocation-32S-error.s | 9 | ||||
| -rw-r--r-- | lld/test/elf2/relocation.s | 11 |
3 files changed, 27 insertions, 3 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index ae996e197bd..5c27c418314 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -501,12 +501,18 @@ template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) { support::endian::write64le(Location, SymVA + RI.r_addend); break; case llvm::ELF::R_X86_64_32: { + case llvm::ELF::R_X86_64_32S: APInt VA(64, SymVA); APInt Addend(64, RI.r_addend, true); APInt Result64 = VA + Addend; APInt Result = Result64.trunc(32); - if (Result.zext(64) != Result64) - error("Relocation out of range"); + if (Type == llvm::ELF::R_X86_64_32) { + if (Result.zext(64) != Result64) + error("Relocation out of range"); + } else + if (Result.sext(64) != Result64) + error("R_X86_64_32S out of range"); + support::endian::write32le(Location, Result.getZExtValue()); break; } diff --git a/lld/test/elf2/relocation-32S-error.s b/lld/test/elf2/relocation-32S-error.s new file mode 100644 index 00000000000..8f19a17e2ff --- /dev/null +++ b/lld/test/elf2/relocation-32S-error.s @@ -0,0 +1,9 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t +// RUN: not lld -flavor gnu2 %t -o %t2 2>&1 | FileCheck %s +// REQUIRES: x86 + +.global _start +_start: + movq _start - 0x1000000000000, %rdx + +#CHECK: R_X86_64_32S out of range diff --git a/lld/test/elf2/relocation.s b/lld/test/elf2/relocation.s index be8a07343dd..a432cf4c8b5 100644 --- a/lld/test/elf2/relocation.s +++ b/lld/test/elf2/relocation.s @@ -35,10 +35,19 @@ R_X86_64_32: // CHECK-NEXT: R_X86_64_32: // CHECK-NEXT: 12000: {{.*}} movl $73728, %edx +.section .R_X86_64_32S,"ax",@progbits +.global R_X86_64_32S +R_X86_64_32S: + movq lulz - 0x100000, %rdx + +// CHECK: Disassembly of section .R_X86_64_32S: +// CHECK-NEXT: R_X86_64_32S: +// CHECK-NEXT: {{.*}}: {{.*}} movq -978935, %rdx + .section .R_X86_64_64,"a",@progbits .global R_X86_64_64 R_X86_64_64: .quad R_X86_64_64 // CHECK: Contents of section .R_X86_64_64: -// CHECK-NEXT: 13000 00300100 00000000 +// CHECK-NEXT: 14000 00400100 00000000 |

