forked from OSchip/llvm-project
[MinGW] [AArch64] Add stubs for potential automatic dllimported variables
The runtime pseudo relocations can't handle the AArch64 format PC relative addressing in adrp+add/ldr pairs. By using stubs, the potentially dllimported addresses can be touched up by the runtime pseudo relocation framework. Differential Revision: https://reviews.llvm.org/D51452 llvm-svn: 341401
This commit is contained in:
parent
792a4f8a21
commit
fed420d6b6
|
@ -3951,7 +3951,7 @@ SDValue AArch64TargetLowering::LowerGlobalAddress(SDValue Op,
|
|||
}
|
||||
EVT PtrVT = getPointerTy(DAG.getDataLayout());
|
||||
SDLoc DL(GN);
|
||||
if (GV->hasDLLImportStorageClass())
|
||||
if (OpFlags & (AArch64II::MO_DLLIMPORT | AArch64II::MO_COFFSTUB))
|
||||
Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Result,
|
||||
MachinePointerInfo::getGOT(DAG.getMachineFunction()));
|
||||
return Result;
|
||||
|
|
|
@ -1607,7 +1607,7 @@ bool AArch64InstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
|
|||
|
||||
if ((OpFlags & AArch64II::MO_GOT) != 0) {
|
||||
BuildMI(MBB, MI, DL, get(AArch64::LOADgot), Reg)
|
||||
.addGlobalAddress(GV, 0, AArch64II::MO_GOT);
|
||||
.addGlobalAddress(GV, 0, OpFlags);
|
||||
BuildMI(MBB, MI, DL, get(AArch64::LDRXui), Reg)
|
||||
.addReg(Reg, RegState::Kill)
|
||||
.addImm(0)
|
||||
|
@ -4842,6 +4842,7 @@ AArch64InstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
|
|||
using namespace AArch64II;
|
||||
|
||||
static const std::pair<unsigned, const char *> TargetFlags[] = {
|
||||
{MO_COFFSTUB, "aarch64-coffstub"},
|
||||
{MO_GOT, "aarch64-got"}, {MO_NC, "aarch64-nc"},
|
||||
{MO_TLS, "aarch64-tls"}, {MO_DLLIMPORT, "aarch64-dllimport"}};
|
||||
return makeArrayRef(TargetFlags);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
|
@ -44,16 +45,31 @@ AArch64MCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
|
|||
assert(TheTriple.isOSWindows() &&
|
||||
"Windows is the only supported COFF target");
|
||||
|
||||
bool IsIndirect = (TargetFlags & AArch64II::MO_DLLIMPORT);
|
||||
bool IsIndirect = (TargetFlags & (AArch64II::MO_DLLIMPORT | AArch64II::MO_COFFSTUB));
|
||||
if (!IsIndirect)
|
||||
return Printer.getSymbol(GV);
|
||||
|
||||
SmallString<128> Name;
|
||||
Name = "__imp_";
|
||||
if (TargetFlags & AArch64II::MO_DLLIMPORT)
|
||||
Name = "__imp_";
|
||||
else if (TargetFlags & AArch64II::MO_COFFSTUB)
|
||||
Name = ".refptr.";
|
||||
Printer.TM.getNameWithPrefix(Name, GV,
|
||||
Printer.getObjFileLowering().getMangler());
|
||||
|
||||
return Ctx.getOrCreateSymbol(Name);
|
||||
MCSymbol *MCSym = Ctx.getOrCreateSymbol(Name);
|
||||
|
||||
if (TargetFlags & AArch64II::MO_COFFSTUB) {
|
||||
MachineModuleInfoCOFF &MMICOFF =
|
||||
Printer.MMI->getObjFileInfo<MachineModuleInfoCOFF>();
|
||||
MachineModuleInfoImpl::StubValueTy &StubSym =
|
||||
MMICOFF.getGVStubEntry(MCSym);
|
||||
|
||||
if (!StubSym.getPointer())
|
||||
StubSym = MachineModuleInfoImpl::StubValueTy(Printer.getSymbol(GV), true);
|
||||
}
|
||||
|
||||
return MCSym;
|
||||
}
|
||||
|
||||
MCSymbol *
|
||||
|
|
|
@ -196,8 +196,13 @@ AArch64Subtarget::ClassifyGlobalReference(const GlobalValue *GV,
|
|||
if (TM.getCodeModel() == CodeModel::Large && isTargetMachO())
|
||||
return AArch64II::MO_GOT;
|
||||
|
||||
unsigned Flags = GV->hasDLLImportStorageClass() ? AArch64II::MO_DLLIMPORT
|
||||
: AArch64II::MO_NO_FLAG;
|
||||
unsigned Flags = AArch64II::MO_NO_FLAG;
|
||||
if (GV->hasDLLImportStorageClass())
|
||||
Flags = AArch64II::MO_DLLIMPORT;
|
||||
else if (getTargetTriple().isWindowsGNUEnvironment() &&
|
||||
!GV->isDSOLocal() && GV->isDeclarationForLinker() &&
|
||||
isa<GlobalVariable>(GV))
|
||||
Flags = AArch64II::MO_COFFSTUB | AArch64II::MO_GOT;
|
||||
|
||||
if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
|
||||
return AArch64II::MO_GOT | Flags;
|
||||
|
|
|
@ -507,7 +507,7 @@ namespace AArch64II {
|
|||
|
||||
MO_NO_FLAG,
|
||||
|
||||
MO_FRAGMENT = 0xf,
|
||||
MO_FRAGMENT = 0x7,
|
||||
|
||||
/// MO_PAGE - A symbol operand with this flag represents the pc-relative
|
||||
/// offset of the 4K page containing the symbol. This is used with the
|
||||
|
@ -540,6 +540,11 @@ namespace AArch64II {
|
|||
/// by-12-bits instruction.
|
||||
MO_HI12 = 7,
|
||||
|
||||
/// MO_COFFSTUB - On a symbol operand "FOO", this indicates that the
|
||||
/// reference is actually to the ".refptrp.FOO" symbol. This is used for
|
||||
/// stub symbols on windows.
|
||||
MO_COFFSTUB = 0x8,
|
||||
|
||||
/// MO_GOT - This flag indicates that a symbol operand represents the
|
||||
/// address of the GOT entry for the symbol, rather than the address of
|
||||
/// the symbol itself.
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
; RUN: llc < %s -mtriple=aarch64-w64-mingw32 | FileCheck %s
|
||||
|
||||
@var = external local_unnamed_addr global i32, align 4
|
||||
@dsolocalvar = external dso_local local_unnamed_addr global i32, align 4
|
||||
@localvar = dso_local local_unnamed_addr global i32 0, align 4
|
||||
@localcommon = common dso_local local_unnamed_addr global i32 0, align 4
|
||||
@extvar = external dllimport local_unnamed_addr global i32, align 4
|
||||
|
||||
define dso_local i32 @getVar() {
|
||||
; CHECK-LABEL: getVar:
|
||||
; CHECK: adrp x8, .refptr.var
|
||||
; CHECK: ldr x8, [x8, .refptr.var]
|
||||
; CHECK: ldr w0, [x8]
|
||||
; CHECK: ret
|
||||
entry:
|
||||
%0 = load i32, i32* @var, align 4
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
define dso_local i32 @getDsoLocalVar() {
|
||||
; CHECK-LABEL: getDsoLocalVar:
|
||||
; CHECK: adrp x8, dsolocalvar
|
||||
; CHECK: ldr w0, [x8, dsolocalvar]
|
||||
; CHECK: ret
|
||||
entry:
|
||||
%0 = load i32, i32* @dsolocalvar, align 4
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
define dso_local i32 @getLocalVar() {
|
||||
; CHECK-LABEL: getLocalVar:
|
||||
; CHECK: adrp x8, localvar
|
||||
; CHECK: ldr w0, [x8, localvar]
|
||||
; CHECK: ret
|
||||
entry:
|
||||
%0 = load i32, i32* @localvar, align 4
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
define dso_local i32 @getLocalCommon() {
|
||||
; CHECK-LABEL: getLocalCommon:
|
||||
; CHECK: adrp x8, localcommon
|
||||
; CHECK: ldr w0, [x8, localcommon]
|
||||
; CHECK: ret
|
||||
entry:
|
||||
%0 = load i32, i32* @localcommon, align 4
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
define dso_local i32 @getExtVar() {
|
||||
; CHECK-LABEL: getExtVar:
|
||||
; CHECK: adrp x8, __imp_extvar
|
||||
; CHECK: ldr x8, [x8, __imp_extvar]
|
||||
; CHECK: ldr w0, [x8]
|
||||
; CHECK: ret
|
||||
entry:
|
||||
%0 = load i32, i32* @extvar, align 4
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
define dso_local void @callFunc() {
|
||||
; CHECK-LABEL: callFunc:
|
||||
; CHECK: b otherFunc
|
||||
entry:
|
||||
tail call void @otherFunc()
|
||||
ret void
|
||||
}
|
||||
|
||||
declare dso_local void @otherFunc()
|
||||
|
||||
define dso_local void @sspFunc() #0 {
|
||||
; CHECK-LABEL: sspFunc:
|
||||
; CHECK: adrp x8, .refptr.__stack_chk_guard
|
||||
; CHECK: ldr x8, [x8, .refptr.__stack_chk_guard]
|
||||
; CHECK: ldr x8, [x8]
|
||||
entry:
|
||||
%c = alloca i8, align 1
|
||||
call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %c)
|
||||
call void @ptrUser(i8* nonnull %c)
|
||||
call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull %c)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
|
||||
declare dso_local void @ptrUser(i8*) local_unnamed_addr #2
|
||||
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
|
||||
|
||||
attributes #0 = { sspstrong }
|
||||
|
||||
; CHECK: .section .rdata$.refptr.__stack_chk_guard,"dr",discard,.refptr.__stack_chk_guard
|
||||
; CHECK: .globl .refptr.__stack_chk_guard
|
||||
; CHECK: .refptr.__stack_chk_guard:
|
||||
; CHECK: .xword __stack_chk_guard
|
||||
; CHECK: .section .rdata$.refptr.var,"dr",discard,.refptr.var
|
||||
; CHECK: .globl .refptr.var
|
||||
; CHECK: .refptr.var:
|
||||
; CHECK: .xword var
|
Loading…
Reference in New Issue