diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -146,6 +146,8 @@ case R_AARCH64_LD64_GOT_LO12_NC: case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: return R_GOT; + case R_AARCH64_LD64_GOTPAGE_LO15: + return R_AARCH64_GOT_PAGE; case R_AARCH64_ADR_GOT_PAGE: case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: return R_AARCH64_GOT_PAGE_PC; @@ -398,6 +400,10 @@ checkAlignment(loc, val, 16, rel); or32AArch64Imm(loc, getBits(val, 4, 11)); break; + case R_AARCH64_LD64_GOTPAGE_LO15: + checkAlignment(loc, val, 8, rel); + or32AArch64Imm(loc, getBits(val, 3, 14)); + break; case R_AARCH64_MOVW_UABS_G0: checkUInt(loc, val, 16, rel); LLVM_FALLTHROUGH; diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -705,6 +705,8 @@ case R_AARCH64_GOT_PAGE_PC: case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC: return getAArch64Page(sym.getGotVA() + a) - getAArch64Page(p); + case R_AARCH64_GOT_PAGE: + return sym.getGotVA() - getAArch64Page(p); case R_GOT_PC: case R_RELAX_TLS_GD_TO_IE: return sym.getGotVA() + a - p; diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h --- a/lld/ELF/Relocations.h +++ b/lld/ELF/Relocations.h @@ -78,6 +78,7 @@ // of a relocation type, there are some relocations whose semantics are // unique to a target. Such relocation are marked with R_. R_AARCH64_GOT_PAGE_PC, + R_AARCH64_GOT_PAGE, R_AARCH64_PAGE_PC, R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC, R_AARCH64_TLSDESC_PAGE, diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -381,7 +381,8 @@ // TLS variables uses GOT differently than the regular variables. static bool needsGot(RelExpr expr) { return oneof( + R_MIPS_GOT_OFF32, R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTPLT, + R_AARCH64_GOT_PAGE>( expr); } diff --git a/lld/test/ELF/aarch64-gotpage.s b/lld/test/ELF/aarch64-gotpage.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/aarch64-gotpage.s @@ -0,0 +1,24 @@ +# REQUIRES: aarch64 +# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.o +# RUN: ld.lld -pie %t.o -o %t +# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOCS %s + +# Check if the R_AARCH64_LD64_GOTPAGE_LO15 generates the GOT entries. +# RELOCS: Relocations [ +# RELOCS-NEXT: Section (5) .rela.dyn { +# RELOCS-NEXT: 0x{{[0-9A-F]+}} R_AARCH64_RELATIVE - 0x{{[0-9A-F]+}} +# RELOCS-NEXT: 0x{{[0-9A-F]+}} R_AARCH64_RELATIVE - 0x{{[0-9A-F]+}} +# RELOCS-NEXT: } +# RELOCS-NEXT: ] + + .globl _start + .type _start,@function +_start: + adrp x0, _GLOBAL_OFFSET_TABLE_ + ldr x0, [x0, #:gotpage_lo15:global1] + ldr x1, [x0, #:gotpage_lo15:global2] + + .type global1,@object + .comm global1,4,4 + .type global2,@object + .comm global2,8,8