Index: llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -750,7 +750,8 @@ ELFRefKind == AArch64MCExpr::VK_GOTTPREL_LO12_NC || ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 || ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 || - ELFRefKind == AArch64MCExpr::VK_SECREL_HI12) { + ELFRefKind == AArch64MCExpr::VK_SECREL_HI12 || + ELFRefKind == AArch64MCExpr::VK_GOT_PAGE_LO15) { // Note that we don't range-check the addend. It's adjusted modulo page // size when converted, so there is no "out of range" condition when using // @pageoff. @@ -2569,6 +2570,7 @@ DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE && ELFRefKind != AArch64MCExpr::VK_ABS_PAGE_NC && ELFRefKind != AArch64MCExpr::VK_GOT_PAGE && + ELFRefKind != AArch64MCExpr::VK_GOT_PAGE_LO15 && ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE && ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) { // The operand must be an @page or @gotpage qualified symbolref. @@ -3434,6 +3436,7 @@ .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC) .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12) .Case("got", AArch64MCExpr::VK_GOT_PAGE) + .Case("gotpage_lo15", AArch64MCExpr::VK_GOT_PAGE_LO15) .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12) .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE) .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC) Index: llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp =================================================================== --- llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp +++ llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp @@ -322,8 +322,13 @@ if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) return R_CLS(LDST64_ABS_LO12_NC); if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) { + AArch64MCExpr::VariantKind AddressLoc = + AArch64MCExpr::getAddressFrag(RefKind); if (!IsILP32) { - return ELF::R_AARCH64_LD64_GOT_LO12_NC; + if (AddressLoc == AArch64MCExpr::VK_LO15) + return ELF::R_AARCH64_LD64_GOTPAGE_LO15; + else + return ELF::R_AARCH64_LD64_GOT_LO12_NC; } else { Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store " "relocation not supported (LP64 eqv: " Index: llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h =================================================================== --- llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h +++ llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h @@ -46,6 +46,7 @@ VK_G1 = 0x050, VK_G2 = 0x060, VK_G3 = 0x070, + VK_LO15 = 0x080, VK_AddressFragBits = 0x0f0, // Whether the final relocation is a checked one (where a linker should @@ -82,6 +83,7 @@ VK_PREL_G0_NC = VK_PREL | VK_G0 | VK_NC, VK_GOT_LO12 = VK_GOT | VK_PAGEOFF | VK_NC, VK_GOT_PAGE = VK_GOT | VK_PAGE, + VK_GOT_PAGE_LO15 = VK_GOT | VK_LO15 | VK_NC, VK_DTPREL_G2 = VK_DTPREL | VK_G2, VK_DTPREL_G1 = VK_DTPREL | VK_G1, VK_DTPREL_G1_NC = VK_DTPREL | VK_G1 | VK_NC, Index: llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp =================================================================== --- llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp +++ llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp @@ -70,6 +70,7 @@ case VK_ABS_PAGE_NC: return ":pg_hi21_nc:"; case VK_GOT: return ":got:"; case VK_GOT_PAGE: return ":got:"; + case VK_GOT_PAGE_LO15: return ":gotpage_lo15:"; case VK_GOT_LO12: return ":got_lo12:"; case VK_GOTTPREL: return ":gottprel:"; case VK_GOTTPREL_PAGE: return ":gottprel:"; Index: llvm/test/MC/AArch64/arm64-elf-relocs.s =================================================================== --- llvm/test/MC/AArch64/arm64-elf-relocs.s +++ llvm/test/MC/AArch64/arm64-elf-relocs.s @@ -245,6 +245,16 @@ // CHECK-OBJ-LP64: R_AARCH64_LD64_GOT_LO12_NC sym // CHECK-OBJ-LP64: R_AARCH64_LD64_GOT_LO12_NC sym+0x7 + ldr x24, [x23, #:gotpage_lo15:sym] + ldr d22, [x21, :gotpage_lo15:sym] + ldr d22, [x23, :gotpage_lo15:sym+7] +// CHECK: ldr x24, [x23, :gotpage_lo15:sym] +// CHECK: ldr d22, [x21, :gotpage_lo15:sym] +// CHECK: ldr d22, [x23, :gotpage_lo15:sym+7] +// CHECK-OBJ-LP64: R_AARCH64_LD64_GOTPAGE_LO15 sym{{$}} +// CHECK-OBJ-LP64: R_AARCH64_LD64_GOTPAGE_LO15 sym{{$}} +// CHECK-OBJ-LP64: R_AARCH64_LD64_GOTPAGE_LO15 sym+0x7 + ldr x24, [x23, :dtprel_lo12_nc:sym] ldr d22, [x21, #:dtprel_lo12:sym] // CHECK: ldr x24, [x23, :dtprel_lo12_nc:sym] @@ -305,4 +315,4 @@ // CHECK: ldr x24, :got:sym // CHECK: ldr d22, :got:sym // CHECK-OBJ-LP64: R_AARCH64_GOT_LD_PREL19 sym -// CHECK-OBJ-LP64: R_AARCH64_GOT_LD_PREL19 sym \ No newline at end of file +// CHECK-OBJ-LP64: R_AARCH64_GOT_LD_PREL19 sym