diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -399,6 +399,13 @@ case ELF::R_AARCH64_ABS64: write(isBE, TargetPtr, Value + Addend); break; + case ELF::R_AARCH64_PLT32: { + uint64_t Result = Value + Addend - FinalAddress; + assert(static_cast(Result) >= INT32_MIN && + static_cast(Result) <= INT32_MAX); + write(isBE, TargetPtr, static_cast(Result)); + break; + } case ELF::R_AARCH64_PREL32: { uint64_t Result = Value + Addend - FinalAddress; assert(static_cast(Result) >= INT32_MIN && diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h --- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h +++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h @@ -18,6 +18,11 @@ /// This implementation is used for AArch64 ELF targets (Linux in particular). class AArch64_ELFTargetObjectFile : public TargetLoweringObjectFileELF { void Initialize(MCContext &Ctx, const TargetMachine &TM) override; + +public: + AArch64_ELFTargetObjectFile() { + PLTRelativeVariantKind = MCSymbolRefExpr::VK_PLT; + } }; /// AArch64_MachoTargetObjectFile - This TLOF implementation is used for Darwin. diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp @@ -115,7 +115,8 @@ bool IsNC = AArch64MCExpr::isNotChecked(RefKind); assert((!Target.getSymA() || - Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None) && + Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None || + Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT) && "Should only be expression-level modifiers here"); assert((!Target.getSymB() || @@ -129,8 +130,11 @@ return ELF::R_AARCH64_NONE; case FK_Data_2: return R_CLS(PREL16); - case FK_Data_4: - return R_CLS(PREL32); + case FK_Data_4: { + return Target.getAccessVariant() == MCSymbolRefExpr::VK_PLT + ? R_CLS(PLT32) + : R_CLS(PREL32); + } case FK_Data_8: if (IsILP32) { Ctx.reportError(Fixup.getLoc(), diff --git a/llvm/test/MC/AArch64/elf-reloc-plt32.s b/llvm/test/MC/AArch64/elf-reloc-plt32.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/elf-reloc-plt32.s @@ -0,0 +1,10 @@ +// RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o - | \ +// RUN: llvm-readobj -r | FileCheck %s + + .section .data +this: + .word extern_func@PLT - this + 4 + +// CHECK: Section ({{.*}}) .rela.data +// CHECK-NEXT: 0x0 R_AARCH64_PLT32 extern_func 0x4 +// CHECK-NEXT: }