summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2016-03-24 20:20:07 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2016-03-24 20:20:07 +0000
commitc9d4caa32c02c8bfa29c1e5af610c28f7592df5b (patch)
tree1cc1aee57e5b6e51cf1a7f870b10d087d4f26d55 /llvm/lib
parent3b0290570b031a579b17e5cfad0e381576779489 (diff)
downloadbcm5719-llvm-c9d4caa32c02c8bfa29c1e5af610c28f7592df5b.tar.gz
bcm5719-llvm-c9d4caa32c02c8bfa29c1e5af610c28f7592df5b.zip
[Hexagon] Add support for run-time stack overflow checking
Patch by Sundeep Kushwaha. llvm-svn: 264328
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp56
-rw-r--r--llvm/lib/Target/Hexagon/HexagonFrameLowering.h4
-rw-r--r--llvm/lib/Target/Hexagon/HexagonInstrInfoV3.td3
-rw-r--r--llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td14
4 files changed, 64 insertions, 13 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
index 6ad82e8c21f..6ee2e8bef61 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -137,6 +137,10 @@ static cl::opt<int> SpillFuncThresholdOs("spill-func-threshold-Os",
cl::Hidden, cl::desc("Specify Os spill func threshold"),
cl::init(1), cl::ZeroOrMore);
+static cl::opt<bool> EnableStackOVFSanitizer("enable-stackovf-sanitizer",
+ cl::Hidden, cl::desc("Enable runtime checks for stack overflow."),
+ cl::init(false), cl::ZeroOrMore);
+
static cl::opt<bool> EnableShrinkWrapping("hexagon-shrink-frame",
cl::init(true), cl::Hidden, cl::ZeroOrMore,
cl::desc("Enable stack frame shrink wrapping"));
@@ -387,6 +391,7 @@ void HexagonFrameLowering::findShrunkPrologEpilog(MachineFunction &MF,
EpilogB = PDomB;
}
+
/// Perform most of the PEI work here:
/// - saving/restoring of the callee-saved registers,
/// - stack frame creation and destruction.
@@ -404,8 +409,9 @@ void HexagonFrameLowering::emitPrologue(MachineFunction &MF,
if (EnableShrinkWrapping)
findShrunkPrologEpilog(MF, PrologB, EpilogB);
- insertCSRSpillsInBlock(*PrologB, CSI, HRI);
- insertPrologueInBlock(*PrologB);
+ bool PrologueStubs = false;
+ insertCSRSpillsInBlock(*PrologB, CSI, HRI, PrologueStubs);
+ insertPrologueInBlock(*PrologB, PrologueStubs);
if (EpilogB) {
insertCSRRestoresInBlock(*EpilogB, CSI, HRI);
@@ -422,7 +428,8 @@ void HexagonFrameLowering::emitPrologue(MachineFunction &MF,
}
-void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB) const {
+void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB,
+ bool PrologueStubs) const {
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo *MFI = MF.getFrameInfo();
auto &HST = MF.getSubtarget<HexagonSubtarget>();
@@ -497,6 +504,13 @@ void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB) const {
.addReg(SP)
.addImm(-int64_t(MaxAlign));
}
+
+ // If the stack-checking is enabled, and we spilled the callee-saved
+ // registers inline (i.e. did not use a spill function), then call
+ // the stack checker directly.
+ if (EnableStackOVFSanitizer && !PrologueStubs)
+ BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::CALLstk))
+ .addExternalSymbol("__runtime_stack_check");
}
void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &MBB) const {
@@ -736,7 +750,7 @@ bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const {
return true;
if (MFI.getStackSize() > 0) {
- if (UseAllocframe)
+ if (EnableStackOVFSanitizer || UseAllocframe)
return true;
}
@@ -754,8 +768,8 @@ enum SpillKind {
SK_FromMemTailcall
};
-static const char *
-getSpillFunctionFor(unsigned MaxReg, SpillKind SpillType) {
+static const char *getSpillFunctionFor(unsigned MaxReg, SpillKind SpillType,
+ bool Stkchk = false) {
const char * V4SpillToMemoryFunctions[] = {
"__save_r16_through_r17",
"__save_r16_through_r19",
@@ -764,6 +778,14 @@ getSpillFunctionFor(unsigned MaxReg, SpillKind SpillType) {
"__save_r16_through_r25",
"__save_r16_through_r27" };
+ const char * V4SpillToMemoryStkchkFunctions[] = {
+ "__save_r16_through_r17_stkchk",
+ "__save_r16_through_r19_stkchk",
+ "__save_r16_through_r21_stkchk",
+ "__save_r16_through_r23_stkchk",
+ "__save_r16_through_r25_stkchk",
+ "__save_r16_through_r27_stkchk" };
+
const char * V4SpillFromMemoryFunctions[] = {
"__restore_r16_through_r17_and_deallocframe",
"__restore_r16_through_r19_and_deallocframe",
@@ -785,7 +807,8 @@ getSpillFunctionFor(unsigned MaxReg, SpillKind SpillType) {
switch(SpillType) {
case SK_ToMem:
- SpillFunc = V4SpillToMemoryFunctions;
+ SpillFunc = Stkchk ? V4SpillToMemoryStkchkFunctions
+ : V4SpillToMemoryFunctions;
break;
case SK_FromMem:
SpillFunc = V4SpillFromMemoryFunctions;
@@ -913,24 +936,34 @@ int HexagonFrameLowering::getFrameIndexReference(const MachineFunction &MF,
bool HexagonFrameLowering::insertCSRSpillsInBlock(MachineBasicBlock &MBB,
- const CSIVect &CSI, const HexagonRegisterInfo &HRI) const {
+ const CSIVect &CSI, const HexagonRegisterInfo &HRI,
+ bool &PrologueStubs) const {
if (CSI.empty())
return true;
MachineBasicBlock::iterator MI = MBB.begin();
+ PrologueStubs = false;
MachineFunction &MF = *MBB.getParent();
auto &HII = *MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
if (useSpillFunction(MF, CSI)) {
+ PrologueStubs = true;
unsigned MaxReg = getMaxCalleeSavedReg(CSI, HRI);
- const char *SpillFun = getSpillFunctionFor(MaxReg, SK_ToMem);
+ bool StkOvrFlowEnabled = EnableStackOVFSanitizer;
+ const char *SpillFun = getSpillFunctionFor(MaxReg, SK_ToMem,
+ StkOvrFlowEnabled);
auto &HTM = static_cast<const HexagonTargetMachine&>(MF.getTarget());
bool IsPIC = HTM.getRelocationModel() == Reloc::PIC_;
// Call spill function.
DebugLoc DL = MI != MBB.end() ? MI->getDebugLoc() : DebugLoc();
- unsigned SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_PIC
- : Hexagon::SAVE_REGISTERS_CALL_V4;
+ unsigned SpillOpc;
+ if (StkOvrFlowEnabled)
+ SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_PIC
+ : Hexagon::SAVE_REGISTERS_CALL_V4STK;
+ else
+ SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_PIC
+ : Hexagon::SAVE_REGISTERS_CALL_V4;
MachineInstr *SaveRegsCall =
BuildMI(MBB, MI, DL, HII.get(SpillOpc))
@@ -1007,6 +1040,7 @@ bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &MBB,
int FI = CSI[i].getFrameIdx();
HII.loadRegFromStackSlot(MBB, MI, Reg, FI, RC, &HRI);
}
+
return true;
}
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
index c9cae04cb30..dc6b0515f0a 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
@@ -84,10 +84,10 @@ private:
void expandAlloca(MachineInstr *AI, const HexagonInstrInfo &TII,
unsigned SP, unsigned CF) const;
- void insertPrologueInBlock(MachineBasicBlock &MBB) const;
+ void insertPrologueInBlock(MachineBasicBlock &MBB, bool PrologueStubs) const;
void insertEpilogueInBlock(MachineBasicBlock &MBB) const;
bool insertCSRSpillsInBlock(MachineBasicBlock &MBB, const CSIVect &CSI,
- const HexagonRegisterInfo &HRI) const;
+ const HexagonRegisterInfo &HRI, bool &PrologueStubs) const;
bool insertCSRRestoresInBlock(MachineBasicBlock &MBB, const CSIVect &CSI,
const HexagonRegisterInfo &HRI) const;
void insertCFIInstructionsAt(MachineBasicBlock &MBB,
diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfoV3.td b/llvm/lib/Target/Hexagon/HexagonInstrInfoV3.td
index 84d035da451..ead3b41c891 100644
--- a/llvm/lib/Target/Hexagon/HexagonInstrInfoV3.td
+++ b/llvm/lib/Target/Hexagon/HexagonInstrInfoV3.td
@@ -67,6 +67,9 @@ defm J2_call: T_Calls<"">, PredRel;
let isCodeGenOnly = 1, isCall = 1, hasSideEffects = 1, Defs = VolatileV3.Regs in
def CALLv3nr : T_Call<"">, PredRel;
+let isCodeGenOnly = 1, isCall = 1, hasSideEffects = 1, Defs = [PC, R31, R6, R7, P0] in
+def CALLstk : T_Call<"">, PredRel;
+
//===----------------------------------------------------------------------===//
// J -
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td b/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td
index f79837ad1c8..4bfc7e21f5b 100644
--- a/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td
+++ b/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td
@@ -3295,6 +3295,7 @@ let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
// Restore registers and dealloc frame before a tail call.
let isCall = 1, Defs = [R29, R30, R31, PC], isAsmParserOnly = 1 in {
def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : T_Call<"">, PredRel;
+
let isExtended = 1, opExtendable = 0 in
def RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT : T_Call<"">, PredRel;
@@ -3309,14 +3310,27 @@ let isCall = 1, Defs = [R29, R30, R31, PC], isAsmParserOnly = 1 in {
// Save registers function call.
let isCall = 1, Uses = [R29, R31], isAsmParserOnly = 1 in {
def SAVE_REGISTERS_CALL_V4 : T_Call<"">, PredRel;
+
let isExtended = 1, opExtendable = 0 in
def SAVE_REGISTERS_CALL_V4_EXT : T_Call<"">, PredRel;
+ let Defs = [P0] in
+ def SAVE_REGISTERS_CALL_V4STK : T_Call<"">, PredRel;
+
+ let Defs = [P0], isExtended = 1, opExtendable = 0 in
+ def SAVE_REGISTERS_CALL_V4STK_EXT : T_Call<"">, PredRel;
+
let Defs = [R14, R15, R28] in
def SAVE_REGISTERS_CALL_V4_PIC : T_Call<"">, PredRel;
let Defs = [R14, R15, R28], isExtended = 1, opExtendable = 0 in
def SAVE_REGISTERS_CALL_V4_EXT_PIC : T_Call<"">, PredRel;
+
+ let Defs = [R14, R15, R28, P0] in
+ def SAVE_REGISTERS_CALL_V4STK_PIC : T_Call<"">, PredRel;
+
+ let Defs = [R14, R15, R28, P0], isExtended = 1, opExtendable = 0 in
+ def SAVE_REGISTERS_CALL_V4STK_EXT_PIC : T_Call<"">, PredRel;
}
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud