mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[SPARC] [SSP] Add support for LOAD_STACK_GUARD.
This fixes PR22248 on sparc. Differential Revision: http://reviews.llvm.org/D19386 llvm-svn: 267545
This commit is contained in:
parent
470e89bab4
commit
599068857b
@ -3302,3 +3302,16 @@ void SparcTargetLowering::ReplaceNodeResults(SDNode *N,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Override to enable LOAD_STACK_GUARD lowering on Linux.
|
||||
bool SparcTargetLowering::useLoadStackGuardNode() const {
|
||||
if (!Subtarget->isTargetLinux())
|
||||
return TargetLowering::useLoadStackGuardNode();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Override to disable global variable loading on Linux.
|
||||
void SparcTargetLowering::insertSSPDeclarations(Module &M) const {
|
||||
if (!Subtarget->isTargetLinux())
|
||||
return TargetLowering::insertSSPDeclarations(M);
|
||||
}
|
||||
|
@ -103,6 +103,10 @@ namespace llvm {
|
||||
return SP::I1;
|
||||
}
|
||||
|
||||
/// Override to support customized stack guard loading.
|
||||
bool useLoadStackGuardNode() const override;
|
||||
void insertSSPDeclarations(Module &M) const override;
|
||||
|
||||
/// getSetCCResultType - Return the ISD::SETCC ValueType
|
||||
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
|
||||
EVT VT) const override;
|
||||
|
@ -491,3 +491,19 @@ unsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const
|
||||
SparcFI->setGlobalBaseReg(GlobalBaseReg);
|
||||
return GlobalBaseReg;
|
||||
}
|
||||
|
||||
bool SparcInstrInfo::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");
|
||||
// offsetof(tcbhead_t, stack_guard) from sysdeps/sparc/nptl/tls.h in glibc.
|
||||
const int64_t Offset = Subtarget.is64Bit() ? 0x28 : 0x14;
|
||||
MI->setDesc(get(Subtarget.is64Bit() ? SP::LDXri : SP::LDri));
|
||||
MachineInstrBuilder(*MI->getParent()->getParent(), MI)
|
||||
.addReg(SP::G7).addImm(Offset);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -97,6 +97,9 @@ public:
|
||||
const TargetRegisterInfo *TRI) const override;
|
||||
|
||||
unsigned getGlobalBaseReg(MachineFunction *MF) const;
|
||||
|
||||
// Lower pseudo instructions after register allocation.
|
||||
bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(StringRef CPU,
|
||||
SparcSubtarget::SparcSubtarget(const Triple &TT, const std::string &CPU,
|
||||
const std::string &FS, TargetMachine &TM,
|
||||
bool is64Bit)
|
||||
: SparcGenSubtargetInfo(TT, CPU, FS), Is64Bit(is64Bit),
|
||||
: SparcGenSubtargetInfo(TT, CPU, FS), TargetTriple(TT), Is64Bit(is64Bit),
|
||||
InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM, *this),
|
||||
FrameLowering(*this) {}
|
||||
|
||||
|
@ -30,6 +30,7 @@ namespace llvm {
|
||||
class StringRef;
|
||||
|
||||
class SparcSubtarget : public SparcGenSubtargetInfo {
|
||||
Triple TargetTriple;
|
||||
virtual void anchor();
|
||||
bool IsV9;
|
||||
bool IsLeon;
|
||||
@ -89,6 +90,8 @@ public:
|
||||
/// returns adjusted framesize which includes space for register window
|
||||
/// spills and arguments.
|
||||
int getAdjustedFrameSize(int stackSize) const;
|
||||
|
||||
bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
33
test/CodeGen/SPARC/stack-protector.ll
Normal file
33
test/CodeGen/SPARC/stack-protector.ll
Normal file
@ -0,0 +1,33 @@
|
||||
; RUN: llc -mtriple=sparc-unknown-linux < %s | FileCheck %s --check-prefix=LINUX-32
|
||||
; RUN: llc -mtriple=sparc64-unknown-linux < %s | FileCheck %s --check-prefix=LINUX-64
|
||||
; RUN: llc -mtriple=sparc-unknown-solaris < %s | FileCheck %s --check-prefix=GENERIC
|
||||
; RUN: llc -mtriple=sparc64-unknown-solaris < %s | FileCheck %s --check-prefix=GENERIC
|
||||
|
||||
; LINUX-32: ld [%g7+20], [[REG1:%[ilo][0-9]*]]
|
||||
; LINUX-64: ldx [%g7+40], [[REG1:%[ilo][0-9]*]]
|
||||
; LINUX-32-NOT: __stack_chk_guard
|
||||
; LINUX-64-NOT: __stack_chk_guard
|
||||
; GENERIC: __stack_chk_guard
|
||||
|
||||
@"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <[11 x i8]*> [#uses=1]
|
||||
|
||||
define void @test(i8* %a) nounwind ssp {
|
||||
entry:
|
||||
%a_addr = alloca i8* ; <i8**> [#uses=2]
|
||||
%buf = alloca [8 x i8] ; <[8 x i8]*> [#uses=2]
|
||||
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
|
||||
store i8* %a, i8** %a_addr
|
||||
%buf1 = bitcast [8 x i8]* %buf to i8* ; <i8*> [#uses=1]
|
||||
%0 = load i8*, i8** %a_addr, align 4 ; <i8*> [#uses=1]
|
||||
%1 = call i8* @strcpy(i8* %buf1, i8* %0) nounwind ; <i8*> [#uses=0]
|
||||
%buf2 = bitcast [8 x i8]* %buf to i8* ; <i8*> [#uses=1]
|
||||
%2 = call i32 (i8*, ...) @printf(i8* getelementptr ([11 x i8], [11 x i8]* @"\01LC", i32 0, i32 0), i8* %buf2) nounwind ; <i32> [#uses=0]
|
||||
br label %return
|
||||
|
||||
return: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i8* @strcpy(i8*, i8*) nounwind
|
||||
|
||||
declare i32 @printf(i8*, ...) nounwind
|
Loading…
Reference in New Issue
Block a user