Index: lld/ELF/Arch/AArch64.cpp =================================================================== --- lld/ELF/Arch/AArch64.cpp +++ lld/ELF/Arch/AArch64.cpp @@ -147,6 +147,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; @@ -399,6 +401,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; Index: lld/ELF/InputSection.cpp =================================================================== --- lld/ELF/InputSection.cpp +++ 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() + a - getAArch64Page(in.got->getVA()); case R_GOT_PC: case R_RELAX_TLS_GD_TO_IE: return sym.getGotVA() + a - p; Index: lld/ELF/Relocations.h =================================================================== --- lld/ELF/Relocations.h +++ 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, Index: lld/ELF/Relocations.cpp =================================================================== --- lld/ELF/Relocations.cpp +++ lld/ELF/Relocations.cpp @@ -381,8 +381,8 @@ // TLS variables uses GOT differently than the regular variables. static bool needsGot(RelExpr expr) { return oneof( - expr); + R_MIPS_GOT_OFF32, R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTPLT, + R_AARCH64_GOT_PAGE>(expr); } // True if this expression is of the form Sym - X, where X is a position in the @@ -411,7 +411,8 @@ R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC, R_GOTPLTONLY_PC, R_PLT_PC, R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC, R_PPC32_PLTREL, R_PPC64_CALL_PLT, R_PPC64_RELAX_TOC, R_RISCV_ADD, R_TLSDESC_CALL, - R_TLSDESC_PC, R_AARCH64_TLSDESC_PAGE, R_TLSLD_HINT, R_TLSIE_HINT>( + R_TLSDESC_PC, R_AARCH64_TLSDESC_PAGE, R_TLSLD_HINT, R_TLSIE_HINT, + R_AARCH64_GOT_PAGE>( e)) return true; Index: lld/test/ELF/aarch64-gotpage.s =================================================================== --- /dev/null +++ lld/test/ELF/aarch64-gotpage.s @@ -0,0 +1,46 @@ +# REQUIRES: aarch64 +# RUN: split-file %s %t + +# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %t/test.s -o %t.o +# RUN: ld.lld -shared --script %t/script %t.o -o %t.so +# RUN: ld.lld -pie --script %t/script %t.o -o %t.exe +# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=RELOCS-SHARED %s +# RUN: llvm-readobj -r %t.exe | FileCheck --check-prefix=RELOCS-PIE %s +# RUN: llvm-objdump --no-show-raw-insn -d %t.so | FileCheck --check-prefix=DISAS %s + +## Check if the R_AARCH64_LD64_GOTPAGE_LO15 generates the GOT entries. +# RELOCS-SHARED: Relocations [ +# RELOCS-SHARED-NEXT: Section (5) .rela.dyn { +# RELOCS-SHARED-NEXT: 0x{{[0-9A-F]+}} R_AARCH64_GLOB_DAT global1 0x{{[0-9A-F]+}} +# RELOCS-SHARED-NEXT: 0x{{[0-9A-F]+}} R_AARCH64_GLOB_DAT global2 0x{{[0-9A-F]+}} +# RELOCS-SHARED-NEXT: } +# RELOCS-SHARED-NEXT: ] + +# RELOCS-PIE: Relocations [ +# RELOCS-PIE-NEXT: Section (5) .rela.dyn { +# RELOCS-PIE-NEXT: 0x{{[0-9A-F]+}} R_AARCH64_RELATIVE - 0x{{[0-9A-F]+}} +# RELOCS-PIE-NEXT: 0x{{[0-9A-F]+}} R_AARCH64_RELATIVE - 0x{{[0-9A-F]+}} +# RELOCS-PIE-NEXT: } +# RELOCS-PIE-NEXT: ] + +# DISAS: adrp x0, 0xf000 +# DISAS-NEXT: ldr x0, [x0, #4088] +# DISAS-NEXT: ldr x1, [x0, #4096] + +#--- script +SECTIONS { + .got (0x10000 - 8) : { *.got } +} + +#--- test.s +.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,8,8 +.type global2,@object +.comm global2,8,8