diff options
author | Davide Italiano <davide@freebsd.org> | 2017-09-20 23:49:50 +0000 |
---|---|---|
committer | Davide Italiano <davide@freebsd.org> | 2017-09-20 23:49:50 +0000 |
commit | f681a8fa3a7bd46edee8d0483c72f2a05794b2fd (patch) | |
tree | 785fb1922f01e298c0256b967d174e56c6a7b7cd | |
parent | 18887bf1795715fd3b52c22ca543ff7290defa1b (diff) | |
download | bcm5719-llvm-f681a8fa3a7bd46edee8d0483c72f2a05794b2fd.tar.gz bcm5719-llvm-f681a8fa3a7bd46edee8d0483c72f2a05794b2fd.zip |
[AArch64] Implement R_AARCH64_ LD_PREL_LO19.
Fixes PR34660.
Differential Revision: https://reviews.llvm.org/D38053
llvm-svn: 313841
-rw-r--r-- | lld/ELF/Arch/AArch64.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/InputSection.cpp | 1 | ||||
-rw-r--r-- | lld/test/ELF/aarch64-undefined-weak.s | 4 | ||||
-rw-r--r-- | lld/test/ELF/pr34660.s | 25 |
4 files changed, 32 insertions, 0 deletions
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index 8fa79c092d2..7493b6c5e83 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -92,6 +92,7 @@ RelExpr AArch64::getRelExpr(uint32_t Type, const SymbolBody &S, case R_AARCH64_PREL32: case R_AARCH64_PREL64: case R_AARCH64_ADR_PREL_LO21: + case R_AARCH64_LD_PREL_LO19: return R_PC; case R_AARCH64_ADR_PREL_PG_HI21: return R_PAGE_PC; @@ -247,6 +248,7 @@ void AArch64::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { or32le(Loc, (Val & 0x0FFFFFFC) >> 2); break; case R_AARCH64_CONDBR19: + case R_AARCH64_LD_PREL_LO19: checkInt<21>(Loc, Val, Type); or32le(Loc, (Val & 0x1FFFFC) << 3); break; diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 016234abc90..338efcbea28 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -487,6 +487,7 @@ static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t Type, uint64_t A, case R_AARCH64_PREL32: case R_AARCH64_PREL64: case R_AARCH64_ADR_PREL_LO21: + case R_AARCH64_LD_PREL_LO19: return P + A; } llvm_unreachable("AArch64 pc-relative relocation expected\n"); diff --git a/lld/test/ELF/aarch64-undefined-weak.s b/lld/test/ELF/aarch64-undefined-weak.s index 1c21213643a..c0f6ffe99aa 100644 --- a/lld/test/ELF/aarch64-undefined-weak.s +++ b/lld/test/ELF/aarch64-undefined-weak.s @@ -30,6 +30,8 @@ _start: .xword target - . // R_AARCH64_PREL16 .hword target - . +// R_AARCH64_LD_PREL_LO19 + ldr x8, target // CHECK: Disassembly of section .text: // 131076 = 0x20004 @@ -43,3 +45,5 @@ _start: // CHECK-NEXT: 2001c: {{.*}} .word 0x00000000 // CHECK-NEXT: 20020: {{.*}} .word 0x00000000 // CHECK-NEXT: 20024: {{.*}} .short 0x0000 +// CHECK: $x.2: +// CHECK-NEXT: 20026: {{.*}} ldr x8, #0 diff --git a/lld/test/ELF/pr34660.s b/lld/test/ELF/pr34660.s new file mode 100644 index 00000000000..11191169659 --- /dev/null +++ b/lld/test/ELF/pr34660.s @@ -0,0 +1,25 @@ +# REQUIRES: aarch64 + +# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t +# RUN: llvm-objdump %t -d | FileCheck %s --check-prefix=DISASM +# RUN: llvm-readobj -elf-output-style=GNU %t -t | FileCheck %s --check-prefix=SYM + +# It would be much easier to understand/read this test if llvm-objdump would print +# the immediates in hex. +# IMM = hex(65540) = 0x10004 +# PC = 0x10000 +# As the relocation is PC-relative, IMM + PC = 0x20004 which is the VA of the +# correct symbol. + +# DISASM: Disassembly of section .text: +# DISASM-NEXT: $x.0: +# DISASM-NEXT: 10000: 28 00 08 58 ldr x8, #65540 + +# SYM: Symbol table '.symtab' +# SYM: 0000000000020004 0 NOTYPE LOCAL DEFAULT 5 patatino + + ldr x8, patatino + .data + .zero 4 +patatino: |