Index: lib/Target/AArch64/AArch64TargetMachine.cpp =================================================================== --- lib/Target/AArch64/AArch64TargetMachine.cpp +++ lib/Target/AArch64/AArch64TargetMachine.cpp @@ -172,6 +172,8 @@ static std::unique_ptr createTLOF(const Triple &TT) { if (TT.isOSBinFormatMachO()) return llvm::make_unique(); + if (TT.isKnownWindowsMSVCEnvironment() || TT.isWindowsCoreCLREnvironment()) + return llvm::make_unique(); if (TT.isOSBinFormatCOFF()) return llvm::make_unique(); Index: lib/Target/AArch64/AArch64TargetObjectFile.h =================================================================== --- lib/Target/AArch64/AArch64TargetObjectFile.h +++ lib/Target/AArch64/AArch64TargetObjectFile.h @@ -48,6 +48,14 @@ /// This implementation is used for AArch64 COFF targets. class AArch64_COFFTargetObjectFile : public TargetLoweringObjectFileCOFF {}; +/// This implementation is used for Windows targets on aarch64. +class AArch64_WindowsTargetObjectFile : public AArch64_COFFTargetObjectFile { +public: + const MCExpr * + lowerRelativeReference(const GlobalValue *LHS, const GlobalValue *RHS, + const TargetMachine &TM) const override; +}; + } // end namespace llvm #endif Index: lib/Target/AArch64/AArch64TargetObjectFile.cpp =================================================================== --- lib/Target/AArch64/AArch64TargetObjectFile.cpp +++ lib/Target/AArch64/AArch64TargetObjectFile.cpp @@ -78,3 +78,30 @@ // be accessed via at least a linker-private symbol. getMangler().getNameWithPrefix(OutName, GV, /* CannotUsePrivateLabel */ true); } + +const MCExpr *AArch64_WindowsTargetObjectFile::lowerRelativeReference( + const GlobalValue *LHS, const GlobalValue *RHS, + const TargetMachine &TM) const { + // Our symbols should exist in address space zero, cowardly no-op if + // otherwise. + if (LHS->getType()->getPointerAddressSpace() != 0 || + RHS->getType()->getPointerAddressSpace() != 0) + return nullptr; + + // Both ptrtoint instructions must wrap global objects: + // - Only global variables are eligible for image relative relocations. + // - The subtrahend refers to the special symbol __ImageBase, a GlobalVariable. + // We expect __ImageBase to be a global variable without a section, externally + // defined. + // + // It should look something like this: @__ImageBase = external constant i8 + if (!isa(LHS) || !isa(RHS) || + LHS->isThreadLocal() || RHS->isThreadLocal() || + RHS->getName() != "__ImageBase" || !RHS->hasExternalLinkage() || + cast(RHS)->hasInitializer() || RHS->hasSection()) + return nullptr; + + return MCSymbolRefExpr::create(TM.getSymbol(LHS), + MCSymbolRefExpr::VK_COFF_IMGREL32, + getContext()); +}