diff options
Diffstat (limited to 'lib/CodeGen/StackProtector.cpp')
-rw-r--r-- | lib/CodeGen/StackProtector.cpp | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp index d8e7840a2576..62cef95a4af2 100644 --- a/lib/CodeGen/StackProtector.cpp +++ b/lib/CodeGen/StackProtector.cpp @@ -14,14 +14,16 @@ // //===----------------------------------------------------------------------===// +#include "llvm/CodeGen/StackProtector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/EHPersonalities.h" -#include "llvm/Analysis/OptimizationDiagnosticInfo.h" +#include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/CodeGen/Passes.h" -#include "llvm/CodeGen/StackProtector.h" +#include "llvm/CodeGen/TargetLowering.h" #include "llvm/CodeGen/TargetPassConfig.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" @@ -42,10 +44,8 @@ #include "llvm/Pass.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetSubtargetInfo.h" #include <utility> using namespace llvm; @@ -247,10 +247,12 @@ bool StackProtector::RequiresStackProtector() { OptimizationRemarkEmitter ORE(F); if (F->hasFnAttribute(Attribute::StackProtectReq)) { - ORE.emit(OptimizationRemark(DEBUG_TYPE, "StackProtectorRequested", F) + ORE.emit([&]() { + return OptimizationRemark(DEBUG_TYPE, "StackProtectorRequested", F) << "Stack protection applied to function " << ore::NV("Function", F) - << " due to a function attribute or command-line switch"); + << " due to a function attribute or command-line switch"; + }); NeedsProtector = true; Strong = true; // Use the same heuristic as strong to determine SSPLayout } else if (F->hasFnAttribute(Attribute::StackProtectStrong)) @@ -264,29 +266,31 @@ bool StackProtector::RequiresStackProtector() { for (const Instruction &I : BB) { if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) { if (AI->isArrayAllocation()) { - OptimizationRemark Remark(DEBUG_TYPE, "StackProtectorAllocaOrArray", - &I); - Remark - << "Stack protection applied to function " - << ore::NV("Function", F) - << " due to a call to alloca or use of a variable length array"; + auto RemarkBuilder = [&]() { + return OptimizationRemark(DEBUG_TYPE, "StackProtectorAllocaOrArray", + &I) + << "Stack protection applied to function " + << ore::NV("Function", F) + << " due to a call to alloca or use of a variable length " + "array"; + }; if (const auto *CI = dyn_cast<ConstantInt>(AI->getArraySize())) { if (CI->getLimitedValue(SSPBufferSize) >= SSPBufferSize) { // A call to alloca with size >= SSPBufferSize requires // stack protectors. Layout.insert(std::make_pair(AI, SSPLK_LargeArray)); - ORE.emit(Remark); + 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)); - ORE.emit(Remark); + ORE.emit(RemarkBuilder); NeedsProtector = true; } } else { // A call to alloca with a variable size requires protectors. Layout.insert(std::make_pair(AI, SSPLK_LargeArray)); - ORE.emit(Remark); + ORE.emit(RemarkBuilder); NeedsProtector = true; } continue; @@ -296,11 +300,13 @@ bool StackProtector::RequiresStackProtector() { if (ContainsProtectableArray(AI->getAllocatedType(), IsLarge, Strong)) { Layout.insert(std::make_pair(AI, IsLarge ? SSPLK_LargeArray : SSPLK_SmallArray)); - ORE.emit(OptimizationRemark(DEBUG_TYPE, "StackProtectorBuffer", &I) + ORE.emit([&]() { + return OptimizationRemark(DEBUG_TYPE, "StackProtectorBuffer", &I) << "Stack protection applied to function " << ore::NV("Function", F) << " due to a stack allocated buffer or struct containing a " - "buffer"); + "buffer"; + }); NeedsProtector = true; continue; } @@ -308,11 +314,13 @@ bool StackProtector::RequiresStackProtector() { if (Strong && HasAddressTaken(AI)) { ++NumAddrTaken; Layout.insert(std::make_pair(AI, SSPLK_AddrOf)); - ORE.emit( - OptimizationRemark(DEBUG_TYPE, "StackProtectorAddressTaken", &I) - << "Stack protection applied to function " - << ore::NV("Function", F) - << " due to the address of a local variable being taken"); + ORE.emit([&]() { + return OptimizationRemark(DEBUG_TYPE, "StackProtectorAddressTaken", + &I) + << "Stack protection applied to function " + << ore::NV("Function", F) + << " due to the address of a local variable being taken"; + }); NeedsProtector = true; } } @@ -377,8 +385,12 @@ static bool CreatePrologue(Function *F, Module *M, ReturnInst *RI, /// - The epilogue checks the value stored in the prologue against the original /// value. It calls __stack_chk_fail if they differ. bool StackProtector::InsertStackProtectors() { + // If the target wants to XOR the frame pointer into the guard value, it's + // impossible to emit the check in IR, so the target *must* support stack + // protection in SDAG. bool SupportsSelectionDAGSP = - EnableSelectionDAGSP && !TM->Options.EnableFastISel; + TLI->useStackGuardXorFP() || + (EnableSelectionDAGSP && !TM->Options.EnableFastISel); AllocaInst *AI = nullptr; // Place on stack that stores the stack guard. for (Function::iterator I = F->begin(), E = F->end(); I != E;) { |