mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-13 17:00:01 +00:00
[PPC, SSP] Support PowerPC Linux stack protection.
llvm-svn: 266809
This commit is contained in:
parent
3a75cd4bf9
commit
a12f27cb73
@ -1024,7 +1024,7 @@ public:
|
|||||||
/// Return the variable that's previously inserted by insertSSPDeclarations,
|
/// Return the variable that's previously inserted by insertSSPDeclarations,
|
||||||
/// if any, otherwise return nullptr. Should be used only when
|
/// if any, otherwise return nullptr. Should be used only when
|
||||||
/// getIRStackGuard returns nullptr.
|
/// getIRStackGuard returns nullptr.
|
||||||
virtual Value *getSDStackGuard(const Module &M) const;
|
virtual Value *getSDagStackGuard(const Module &M) const;
|
||||||
|
|
||||||
/// If the target has a standard location for the unsafe stack pointer,
|
/// If the target has a standard location for the unsafe stack pointer,
|
||||||
/// returns the address of that location. Otherwise, returns nullptr.
|
/// returns the address of that location. Otherwise, returns nullptr.
|
||||||
|
@ -2004,7 +2004,7 @@ static SDValue getLoadStackGuard(SelectionDAG &DAG, SDLoc DL, SDValue &Chain) {
|
|||||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||||
EVT PtrTy = TLI.getPointerTy(DAG.getDataLayout());
|
EVT PtrTy = TLI.getPointerTy(DAG.getDataLayout());
|
||||||
MachineFunction &MF = DAG.getMachineFunction();
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
Value *Global = TLI.getSDStackGuard(*MF.getFunction()->getParent());
|
Value *Global = TLI.getSDagStackGuard(*MF.getFunction()->getParent());
|
||||||
MachineSDNode *Node =
|
MachineSDNode *Node =
|
||||||
DAG.getMachineNode(TargetOpcode::LOAD_STACK_GUARD, DL, PtrTy, Chain);
|
DAG.getMachineNode(TargetOpcode::LOAD_STACK_GUARD, DL, PtrTy, Chain);
|
||||||
if (Global) {
|
if (Global) {
|
||||||
@ -2034,27 +2034,25 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
|
|||||||
MachineFrameInfo *MFI = ParentBB->getParent()->getFrameInfo();
|
MachineFrameInfo *MFI = ParentBB->getParent()->getFrameInfo();
|
||||||
int FI = MFI->getStackProtectorIndex();
|
int FI = MFI->getStackProtectorIndex();
|
||||||
|
|
||||||
const Module &M = *ParentBB->getParent()->getFunction()->getParent();
|
|
||||||
const Value *IRGuard = TLI.getSDStackGuard(M);
|
|
||||||
assert(IRGuard && "Currently there must be an IR guard in order to use "
|
|
||||||
"SelectionDAG SSP");
|
|
||||||
SDValue GuardPtr = getValue(IRGuard);
|
|
||||||
SDValue StackSlotPtr = DAG.getFrameIndex(FI, PtrTy);
|
|
||||||
|
|
||||||
unsigned Align = DL->getPrefTypeAlignment(IRGuard->getType());
|
|
||||||
|
|
||||||
SDValue Guard;
|
SDValue Guard;
|
||||||
SDLoc dl = getCurSDLoc();
|
SDLoc dl = getCurSDLoc();
|
||||||
|
SDValue StackSlotPtr = DAG.getFrameIndex(FI, PtrTy);
|
||||||
|
const Module &M = *ParentBB->getParent()->getFunction()->getParent();
|
||||||
|
unsigned Align = DL->getPrefTypeAlignment(Type::getInt8PtrTy(M.getContext()));
|
||||||
|
|
||||||
// If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD.
|
// If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD.
|
||||||
// Otherwise, emit a volatile load to retrieve the stack guard value.
|
// Otherwise, emit a volatile load to retrieve the stack guard value.
|
||||||
SDValue Chain = DAG.getEntryNode();
|
SDValue Chain = DAG.getEntryNode();
|
||||||
if (TLI.useLoadStackGuardNode())
|
if (TLI.useLoadStackGuardNode()) {
|
||||||
Guard = getLoadStackGuard(DAG, dl, Chain);
|
Guard = getLoadStackGuard(DAG, dl, Chain);
|
||||||
else
|
} else {
|
||||||
|
const Value *IRGuard = TLI.getSDagStackGuard(M);
|
||||||
|
SDValue GuardPtr = getValue(IRGuard);
|
||||||
|
|
||||||
Guard =
|
Guard =
|
||||||
DAG.getLoad(PtrTy, dl, Chain, GuardPtr, MachinePointerInfo(IRGuard, 0),
|
DAG.getLoad(PtrTy, dl, Chain, GuardPtr, MachinePointerInfo(IRGuard, 0),
|
||||||
true, false, false, Align);
|
true, false, false, Align);
|
||||||
|
}
|
||||||
|
|
||||||
SDValue StackSlot = DAG.getLoad(
|
SDValue StackSlot = DAG.getLoad(
|
||||||
PtrTy, dl, DAG.getEntryNode(), StackSlotPtr,
|
PtrTy, dl, DAG.getEntryNode(), StackSlotPtr,
|
||||||
@ -5313,7 +5311,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
|||||||
if (TLI.useLoadStackGuardNode()) {
|
if (TLI.useLoadStackGuardNode()) {
|
||||||
Res = getLoadStackGuard(DAG, sdl, Chain);
|
Res = getLoadStackGuard(DAG, sdl, Chain);
|
||||||
} else {
|
} else {
|
||||||
const Value *Global = TLI.getSDStackGuard(M);
|
const Value *Global = TLI.getSDagStackGuard(M);
|
||||||
unsigned Align = DL->getPrefTypeAlignment(Global->getType());
|
unsigned Align = DL->getPrefTypeAlignment(Global->getType());
|
||||||
Res =
|
Res =
|
||||||
DAG.getLoad(PtrTy, sdl, Chain, getValue(Global),
|
DAG.getLoad(PtrTy, sdl, Chain, getValue(Global),
|
||||||
|
@ -1814,6 +1814,6 @@ void TargetLoweringBase::insertSSPDeclarations(Module &M) const {
|
|||||||
|
|
||||||
// Currently only support "standard" __stack_chk_guard.
|
// Currently only support "standard" __stack_chk_guard.
|
||||||
// TODO: add LOAD_STACK_GUARD support.
|
// TODO: add LOAD_STACK_GUARD support.
|
||||||
Value *TargetLoweringBase::getSDStackGuard(const Module &M) const {
|
Value *TargetLoweringBase::getSDagStackGuard(const Module &M) const {
|
||||||
return M.getGlobalVariable("__stack_chk_guard");
|
return M.getGlobalVariable("__stack_chk_guard");
|
||||||
}
|
}
|
||||||
|
@ -12013,3 +12013,16 @@ void PPCTargetLowering::insertCopiesSplitCSR(
|
|||||||
.addReg(NewVR);
|
.addReg(NewVR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Override to enable LOAD_STACK_GUARD lowering on Linux.
|
||||||
|
bool PPCTargetLowering::useLoadStackGuardNode() const {
|
||||||
|
if (!Subtarget.isTargetLinux())
|
||||||
|
return TargetLowering::useLoadStackGuardNode();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override to disable global variable loading on Linux.
|
||||||
|
void PPCTargetLowering::insertSSPDeclarations(Module &M) const {
|
||||||
|
if (!Subtarget.isTargetLinux())
|
||||||
|
return TargetLowering::insertSSPDeclarations(M);
|
||||||
|
}
|
||||||
|
@ -688,6 +688,10 @@ namespace llvm {
|
|||||||
unsigned
|
unsigned
|
||||||
getExceptionSelectorRegister(const Constant *PersonalityFn) const override;
|
getExceptionSelectorRegister(const Constant *PersonalityFn) const override;
|
||||||
|
|
||||||
|
/// Override to support customized stack guard loading.
|
||||||
|
bool useLoadStackGuardNode() const override;
|
||||||
|
void insertSSPDeclarations(Module &M) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ReuseLoadInfo {
|
struct ReuseLoadInfo {
|
||||||
SDValue Ptr;
|
SDValue Ptr;
|
||||||
|
@ -1857,3 +1857,19 @@ PPCInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
|
|||||||
return makeArrayRef(TargetFlags);
|
return makeArrayRef(TargetFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PPCInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
|
||||||
|
switch (MI->getOpcode()) {
|
||||||
|
case TargetOpcode::LOAD_STACK_GUARD: {
|
||||||
|
assert(Subtarget.isTargetLinux() &&
|
||||||
|
"Only Linux target is expected to contain LOAD_STACK_GUARD");
|
||||||
|
const int64_t Offset = Subtarget.isPPC64() ? -0x7010 : -0x7008;
|
||||||
|
const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
|
||||||
|
MI->setDesc(get(PPC::LD));
|
||||||
|
MachineInstrBuilder(*MI->getParent()->getParent(), MI)
|
||||||
|
.addImm(Offset)
|
||||||
|
.addReg(Reg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@ -272,6 +272,9 @@ public:
|
|||||||
|
|
||||||
ArrayRef<std::pair<unsigned, const char *>>
|
ArrayRef<std::pair<unsigned, const char *>>
|
||||||
getSerializableBitmaskMachineOperandTargetFlags() const override;
|
getSerializableBitmaskMachineOperandTargetFlags() const override;
|
||||||
|
|
||||||
|
// Lower pseudo instructions after register allocation.
|
||||||
|
bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -286,6 +286,7 @@ public:
|
|||||||
|
|
||||||
bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
|
bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
|
||||||
bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
|
bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
|
||||||
|
bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
|
||||||
|
|
||||||
bool isDarwinABI() const { return isTargetMachO() || isDarwin(); }
|
bool isDarwinABI() const { return isTargetMachO() || isDarwin(); }
|
||||||
bool isSVR4ABI() const { return !isDarwinABI(); }
|
bool isSVR4ABI() const { return !isDarwinABI(); }
|
||||||
|
@ -2018,12 +2018,6 @@ void X86TargetLowering::insertSSPDeclarations(Module &M) const {
|
|||||||
TargetLowering::insertSSPDeclarations(M);
|
TargetLowering::insertSSPDeclarations(M);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *X86TargetLowering::getSDStackGuard(const Module &M) const {
|
|
||||||
if (!Subtarget.isTargetLinux())
|
|
||||||
return TargetLowering::getSDStackGuard(M);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *X86TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
|
Value *X86TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
|
||||||
if (!Subtarget.isTargetAndroid())
|
if (!Subtarget.isTargetAndroid())
|
||||||
return TargetLowering::getSafeStackPointerLocation(IRB);
|
return TargetLowering::getSafeStackPointerLocation(IRB);
|
||||||
|
@ -966,8 +966,6 @@ namespace llvm {
|
|||||||
|
|
||||||
void insertSSPDeclarations(Module &M) const override;
|
void insertSSPDeclarations(Module &M) const override;
|
||||||
|
|
||||||
Value *getSDStackGuard(const Module &M) const override;
|
|
||||||
|
|
||||||
/// Return true if the target stores SafeStack pointer at a fixed offset in
|
/// Return true if the target stores SafeStack pointer at a fixed offset in
|
||||||
/// some non-standard address space, and populates the address space and
|
/// some non-standard address space, and populates the address space and
|
||||||
/// offset as appropriate.
|
/// offset as appropriate.
|
||||||
|
@ -1,6 +1,17 @@
|
|||||||
; RUN: llc -march=ppc32 -mtriple=ppc32-unknown-linux < %s | FileCheck %s
|
; RUN: llc -mtriple=powerpc-apple-darwin8 < %s | FileCheck -check-prefix=DARWIN32 %s
|
||||||
; CHECK: __stack_chk_guard
|
; RUN: llc -mtriple=powerpc64-apple-darwin < %s | FileCheck -check-prefix=DARWIN64 %s
|
||||||
; CHECK: __stack_chk_fail
|
; RUN: llc -mtriple=ppc32-unknown-linux < %s | FileCheck -check-prefix=LINUX32 %s
|
||||||
|
; RUN: llc -mtriple=powerpc64le-unknown-linux < %s | FileCheck -check-prefix=LINUX64 %s
|
||||||
|
|
||||||
|
; DARWIN32: __stack_chk_guard
|
||||||
|
; DARWIN64: __stack_chk_guard
|
||||||
|
; LINUX32: ld {{[0-9]+}}, -28680(2)
|
||||||
|
; LINUX64: ld {{[0-9]+}}, -28688(13)
|
||||||
|
|
||||||
|
; DARWIN32: __stack_chk_fail
|
||||||
|
; DARWIN64: __stack_chk_fail
|
||||||
|
; LINUX32: __stack_chk_fail
|
||||||
|
; LINUX64: __stack_chk_fail
|
||||||
|
|
||||||
@"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <[11 x i8]*> [#uses=1]
|
@"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <[11 x i8]*> [#uses=1]
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user