diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-03-24 20:20:07 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-03-24 20:20:07 +0000 |
commit | c9d4caa32c02c8bfa29c1e5af610c28f7592df5b (patch) | |
tree | 1cc1aee57e5b6e51cf1a7f870b10d087d4f26d55 /llvm/lib | |
parent | 3b0290570b031a579b17e5cfad0e381576779489 (diff) | |
download | bcm5719-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.cpp | 56 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonFrameLowering.h | 4 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonInstrInfoV3.td | 3 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td | 14 |
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; } //===----------------------------------------------------------------------===// |