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;) {  | 
