diff options
Diffstat (limited to 'lib/CodeGen/StackProtector.cpp')
-rw-r--r-- | lib/CodeGen/StackProtector.cpp | 79 |
1 files changed, 44 insertions, 35 deletions
diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp index 62cef95a4af2..cb12c7ce6e82 100644 --- a/lib/CodeGen/StackProtector.cpp +++ b/lib/CodeGen/StackProtector.cpp @@ -36,6 +36,7 @@ #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Module.h" @@ -69,32 +70,6 @@ INITIALIZE_PASS_END(StackProtector, DEBUG_TYPE, FunctionPass *llvm::createStackProtectorPass() { return new StackProtector(); } -StackProtector::SSPLayoutKind -StackProtector::getSSPLayout(const AllocaInst *AI) const { - return AI ? Layout.lookup(AI) : SSPLK_None; -} - -void StackProtector::adjustForColoring(const AllocaInst *From, - const AllocaInst *To) { - // When coloring replaces one alloca with another, transfer the SSPLayoutKind - // tag from the remapped to the target alloca. The remapped alloca should - // have a size smaller than or equal to the replacement alloca. - SSPLayoutMap::iterator I = Layout.find(From); - if (I != Layout.end()) { - SSPLayoutKind Kind = I->second; - Layout.erase(I); - - // Transfer the tag, but make sure that SSPLK_AddrOf does not overwrite - // SSPLK_SmallArray or SSPLK_LargeArray, and make sure that - // SSPLK_SmallArray does not overwrite SSPLK_LargeArray. - I = Layout.find(To); - if (I == Layout.end()) - Layout.insert(std::make_pair(To, Kind)); - else if (I->second != SSPLK_LargeArray && Kind != SSPLK_AddrOf) - I->second = Kind; - } -} - void StackProtector::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<TargetPassConfig>(); AU.addPreserved<DominatorTreeWrapperPass>(); @@ -182,6 +157,14 @@ bool StackProtector::ContainsProtectableArray(Type *Ty, bool &IsLarge, return NeedsProtector; } +static bool isLifetimeInst(const Instruction *I) { + if (const auto Intrinsic = dyn_cast<IntrinsicInst>(I)) { + const auto Id = Intrinsic->getIntrinsicID(); + return Id == Intrinsic::lifetime_start || Id == Intrinsic::lifetime_end; + } + return false; +} + bool StackProtector::HasAddressTaken(const Instruction *AI) { for (const User *U : AI->users()) { if (const StoreInst *SI = dyn_cast<StoreInst>(U)) { @@ -190,8 +173,10 @@ bool StackProtector::HasAddressTaken(const Instruction *AI) { } else if (const PtrToIntInst *SI = dyn_cast<PtrToIntInst>(U)) { if (AI == SI->getOperand(0)) return true; - } else if (isa<CallInst>(U)) { - return true; + } else if (const CallInst *CI = dyn_cast<CallInst>(U)) { + // Ignore intrinsics that are not calls. TODO: Use isLoweredToCall(). + if (!isa<DbgInfoIntrinsic>(CI) && !isLifetimeInst(CI)) + return true; } else if (isa<InvokeInst>(U)) { return true; } else if (const SelectInst *SI = dyn_cast<SelectInst>(U)) { @@ -214,7 +199,7 @@ bool StackProtector::HasAddressTaken(const Instruction *AI) { return false; } -/// \brief Check whether or not this function needs a stack protector based +/// Check whether or not this function needs a stack protector based /// upon the stack protector level. /// /// We use two heuristics: a standard (ssp) and strong (sspstrong). @@ -278,18 +263,21 @@ bool StackProtector::RequiresStackProtector() { if (CI->getLimitedValue(SSPBufferSize) >= SSPBufferSize) { // A call to alloca with size >= SSPBufferSize requires // stack protectors. - Layout.insert(std::make_pair(AI, SSPLK_LargeArray)); + Layout.insert(std::make_pair(AI, + MachineFrameInfo::SSPLK_LargeArray)); ORE.emit(RemarkBuilder); NeedsProtector = true; } else if (Strong) { // Require protectors for all alloca calls in strong mode. - Layout.insert(std::make_pair(AI, SSPLK_SmallArray)); + Layout.insert(std::make_pair(AI, + MachineFrameInfo::SSPLK_SmallArray)); ORE.emit(RemarkBuilder); NeedsProtector = true; } } else { // A call to alloca with a variable size requires protectors. - Layout.insert(std::make_pair(AI, SSPLK_LargeArray)); + Layout.insert(std::make_pair(AI, + MachineFrameInfo::SSPLK_LargeArray)); ORE.emit(RemarkBuilder); NeedsProtector = true; } @@ -298,8 +286,9 @@ bool StackProtector::RequiresStackProtector() { bool IsLarge = false; if (ContainsProtectableArray(AI->getAllocatedType(), IsLarge, Strong)) { - Layout.insert(std::make_pair(AI, IsLarge ? SSPLK_LargeArray - : SSPLK_SmallArray)); + Layout.insert(std::make_pair(AI, IsLarge + ? MachineFrameInfo::SSPLK_LargeArray + : MachineFrameInfo::SSPLK_SmallArray)); ORE.emit([&]() { return OptimizationRemark(DEBUG_TYPE, "StackProtectorBuffer", &I) << "Stack protection applied to function " @@ -313,7 +302,7 @@ bool StackProtector::RequiresStackProtector() { if (Strong && HasAddressTaken(AI)) { ++NumAddrTaken; - Layout.insert(std::make_pair(AI, SSPLK_AddrOf)); + Layout.insert(std::make_pair(AI, MachineFrameInfo::SSPLK_AddrOf)); ORE.emit([&]() { return OptimizationRemark(DEBUG_TYPE, "StackProtectorAddressTaken", &I) @@ -523,3 +512,23 @@ BasicBlock *StackProtector::CreateFailBB() { bool StackProtector::shouldEmitSDCheck(const BasicBlock &BB) const { return HasPrologue && !HasIRCheck && dyn_cast<ReturnInst>(BB.getTerminator()); } + +void StackProtector::copyToMachineFrameInfo(MachineFrameInfo &MFI) const { + if (Layout.empty()) + return; + + for (int I = 0, E = MFI.getObjectIndexEnd(); I != E; ++I) { + if (MFI.isDeadObjectIndex(I)) + continue; + + const AllocaInst *AI = MFI.getObjectAllocation(I); + if (!AI) + continue; + + SSPLayoutMap::const_iterator LI = Layout.find(AI); + if (LI == Layout.end()) + continue; + + MFI.setObjectSSPLayout(I, LI->second); + } +} |