diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h index db90f2e4cc7cc..5bba0c0046fb2 100644 --- a/llvm/include/llvm/Target/TargetOptions.h +++ b/llvm/include/llvm/Target/TargetOptions.h @@ -140,6 +140,7 @@ class TargetOptions { DebugStrictDwarf(false), Hotpatch(false), PPCGenScalarMASSEntries(false), JMCInstrument(false), EnableCFIFixup(false), MisExpect(false), XCOFFReadOnlyPointers(false), + SupportIndirectSymViaGOTPCRel_AArch64_ELF(true), VerifyArgABICompliance(true), FPDenormalMode(DenormalMode::IEEE, DenormalMode::IEEE) {} @@ -373,6 +374,10 @@ class TargetOptions { /// into the RO data section. unsigned XCOFFReadOnlyPointers : 1; + /// When set to true, enables indirect symbol replacement with GOTPCREL for + /// AArch64/ELF. The default is `true`. + unsigned SupportIndirectSymViaGOTPCRel_AArch64_ELF : 1; + /// When set to true, call/return argument extensions of narrow integers /// are verified in the target backend if it cares about them. This is /// not done with internal tools like llc that run many tests that ignore diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp index 95eab16511e5a..0a7b1f14fff75 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -280,13 +280,15 @@ void AArch64TargetMachine::reset() { SubtargetMap.clear(); } //===----------------------------------------------------------------------===// // AArch64 Lowering public interface. //===----------------------------------------------------------------------===// -static std::unique_ptr createTLOF(const Triple &TT) { +static std::unique_ptr +createTLOF(const Triple &TT, const TargetOptions &Options) { if (TT.isOSBinFormatMachO()) return std::make_unique(); if (TT.isOSBinFormatCOFF()) return std::make_unique(); - return std::make_unique(); + return std::make_unique( + Options.SupportIndirectSymViaGOTPCRel_AArch64_ELF); } // Helper function to build a DataLayout string @@ -367,7 +369,7 @@ AArch64TargetMachine::AArch64TargetMachine(const Target &T, const Triple &TT, computeDefaultCPU(TT, CPU), FS, Options, getEffectiveRelocModel(TT, RM), getEffectiveAArch64CodeModel(TT, CM, JIT), OL), - TLOF(createTLOF(getTargetTriple())), isLittle(LittleEndian) { + TLOF(createTLOF(getTargetTriple(), Options)), isLittle(LittleEndian) { initAsmInfo(); if (TT.isOSBinFormatMachO()) { diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp index 85de2d5010286..0b94b76b1aae8 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp @@ -26,7 +26,6 @@ void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) { TargetLoweringObjectFileELF::Initialize(Ctx, TM); PLTRelativeSpecifier = AArch64::S_PLT; - SupportIndirectSymViaGOTPCRel = true; // AARCH64 ELF ABI does not define static relocation type for TLS offset // within a module. Do not generate AT_location for TLS variables. diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h index 6b3381452c70b..45fdcb949b402 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h +++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h @@ -20,6 +20,10 @@ class AArch64_ELFTargetObjectFile : public TargetLoweringObjectFileELF { void Initialize(MCContext &Ctx, const TargetMachine &TM) override; public: + AArch64_ELFTargetObjectFile(bool SupportIndirectSymViaGOTPCRel) { + this->SupportIndirectSymViaGOTPCRel = SupportIndirectSymViaGOTPCRel; + } + const MCExpr *getIndirectSymViaGOTPCRel(const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV, int64_t Offset,