diff options
author | Rui Ueyama <ruiu@google.com> | 2019-02-07 18:12:57 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2019-02-07 18:12:57 +0000 |
commit | 04cbd988f9452c24dcb0353d674f859761952d21 (patch) | |
tree | c80c1160414dbccb4106d55043fed714e885363e | |
parent | 93fdec739bd05df0193e52584db3218678270d72 (diff) | |
download | bcm5719-llvm-04cbd988f9452c24dcb0353d674f859761952d21.tar.gz bcm5719-llvm-04cbd988f9452c24dcb0353d674f859761952d21.zip |
Fix a bug in R_X86_64_PC{8,16} relocation handling.
R_X86_64_PC{8,16} relocations are sign-extended, so when we check
for relocation overflow, we had to use checkInt instead of checkUInt.
I confirmed that GNU linkers create the same output for the test case.
llvm-svn: 353437
-rw-r--r-- | lld/ELF/Arch/X86_64.cpp | 10 | ||||
-rw-r--r-- | lld/test/ELF/Inputs/x86-64-pcrel.s | 8 | ||||
-rw-r--r-- | lld/test/ELF/x86-64-pcrel.s | 10 |
3 files changed, 22 insertions, 6 deletions
diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 822a1a4f01d..bfe2ba82498 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -324,15 +324,21 @@ template <class ELFT> void X86_64<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { switch (Type) { case R_X86_64_8: - case R_X86_64_PC8: checkUInt(Loc, Val, 8, Type); *Loc = Val; break; + case R_X86_64_PC8: + checkInt(Loc, Val, 8, Type); + *Loc = Val; + break; case R_X86_64_16: - case R_X86_64_PC16: checkUInt(Loc, Val, 16, Type); write16le(Loc, Val); break; + case R_X86_64_PC16: + checkInt(Loc, Val, 16, Type); + write16le(Loc, Val); + break; case R_X86_64_32: checkUInt(Loc, Val, 32, Type); write32le(Loc, Val); diff --git a/lld/test/ELF/Inputs/x86-64-pcrel.s b/lld/test/ELF/Inputs/x86-64-pcrel.s new file mode 100644 index 00000000000..dea824ae719 --- /dev/null +++ b/lld/test/ELF/Inputs/x86-64-pcrel.s @@ -0,0 +1,8 @@ +.globl foo +foo: + +.word _start - foo +.fill 14,1,0xcc + +.byte _start - foo +.fill 15,1,0xcc diff --git a/lld/test/ELF/x86-64-pcrel.s b/lld/test/ELF/x86-64-pcrel.s index dd62242e99f..8129c9cab2d 100644 --- a/lld/test/ELF/x86-64-pcrel.s +++ b/lld/test/ELF/x86-64-pcrel.s @@ -3,13 +3,15 @@ // This is a test for R_X86_64_PC8 and R_X86_64_PC16. // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o -// RUN: echo '.globl foo; foo:' | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t2.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/x86-64-pcrel.s -o %t2.o // RUN: ld.lld -o %t.exe %t1.o %t2.o // RUN: llvm-objdump -s %t.exe | FileCheck %s -// CHECK: Contents of section .text: -// CHECK: 2000cccc cccccccc cccccccc cccccccc -// CHECK: 20cccccc cccccccc cccccccc cccccccc +// CHECK: Contents of section .text: +// CHECK-NEXT: 2000cccc cccccccc cccccccc cccccccc +// CHECK-NEXT: 20cccccc cccccccc cccccccc cccccccc +// CHECK-NEXT: e0ffcccc cccccccc cccccccc cccccccc +// CHECK-NEXT: e0cccccc cccccccc cccccccc cccccccc .globl _start _start: |