diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
commit | d8e91e46262bc44006913e6796843909f1ac7bcd (patch) | |
tree | 7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/CodeGen/StackProtector.cpp | |
parent | b7eb8e35e481a74962664b63dfb09483b200209a (diff) |
Notes
Diffstat (limited to 'lib/CodeGen/StackProtector.cpp')
-rw-r--r-- | lib/CodeGen/StackProtector.cpp | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp index cb12c7ce6e82..3b578c7391da 100644 --- a/lib/CodeGen/StackProtector.cpp +++ b/lib/CodeGen/StackProtector.cpp @@ -157,14 +157,6 @@ 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)) { @@ -175,7 +167,7 @@ bool StackProtector::HasAddressTaken(const Instruction *AI) { 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)) + if (!isa<DbgInfoIntrinsic>(CI) && !CI->isLifetimeStartOrEnd()) return true; } else if (isa<InvokeInst>(U)) { return true; @@ -199,6 +191,18 @@ bool StackProtector::HasAddressTaken(const Instruction *AI) { return false; } +/// Search for the first call to the llvm.stackprotector intrinsic and return it +/// if present. +static const CallInst *findStackProtectorIntrinsic(Function &F) { + for (const BasicBlock &BB : F) + for (const Instruction &I : BB) + if (const CallInst *CI = dyn_cast<CallInst>(&I)) + if (CI->getCalledFunction() == + Intrinsic::getDeclaration(F.getParent(), Intrinsic::stackprotector)) + return CI; + return nullptr; +} + /// Check whether or not this function needs a stack protector based /// upon the stack protector level. /// @@ -215,13 +219,7 @@ bool StackProtector::HasAddressTaken(const Instruction *AI) { bool StackProtector::RequiresStackProtector() { bool Strong = false; bool NeedsProtector = false; - for (const BasicBlock &BB : *F) - for (const Instruction &I : BB) - if (const CallInst *CI = dyn_cast<CallInst>(&I)) - if (CI->getCalledFunction() == - Intrinsic::getDeclaration(F->getParent(), - Intrinsic::stackprotector)) - HasPrologue = true; + HasPrologue = findStackProtectorIntrinsic(*F); if (F->hasFnAttribute(Attribute::SafeStack)) return false; @@ -379,7 +377,8 @@ bool StackProtector::InsertStackProtectors() { // protection in SDAG. bool SupportsSelectionDAGSP = TLI->useStackGuardXorFP() || - (EnableSelectionDAGSP && !TM->Options.EnableFastISel); + (EnableSelectionDAGSP && !TM->Options.EnableFastISel && + !TM->Options.EnableGlobalISel); AllocaInst *AI = nullptr; // Place on stack that stores the stack guard. for (Function::iterator I = F->begin(), E = F->end(); I != E;) { @@ -399,6 +398,14 @@ bool StackProtector::InsertStackProtectors() { if (SupportsSelectionDAGSP) break; + // Find the stack guard slot if the prologue was not created by this pass + // itself via a previous call to CreatePrologue(). + if (!AI) { + const CallInst *SPCall = findStackProtectorIntrinsic(*F); + assert(SPCall && "Call to llvm.stackprotector is missing"); + AI = cast<AllocaInst>(SPCall->getArgOperand(1)); + } + // Set HasIRCheck to true, so that SelectionDAG will not generate its own // version. SelectionDAG called 'shouldEmitSDCheck' to check whether // instrumentation has already been generated. |