diff options
Diffstat (limited to 'lib/CodeGen/StackProtector.cpp')
| -rw-r--r-- | lib/CodeGen/StackProtector.cpp | 28 | 
1 files changed, 25 insertions, 3 deletions
diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp index 9f51778da756..fcaee4208ba3 100644 --- a/lib/CodeGen/StackProtector.cpp +++ b/lib/CodeGen/StackProtector.cpp @@ -16,6 +16,7 @@  #define DEBUG_TYPE "stack-protector"  #include "llvm/CodeGen/Passes.h" +#include "llvm/Analysis/Dominators.h"  #include "llvm/Attributes.h"  #include "llvm/Constants.h"  #include "llvm/DerivedTypes.h" @@ -45,6 +46,8 @@ namespace {      Function *F;      Module *M; +    DominatorTree* DT; +      /// InsertStackProtectors - Insert code into the prologue and epilogue of      /// the function.      /// @@ -62,9 +65,17 @@ namespace {      bool RequiresStackProtector() const;    public:      static char ID;             // Pass identification, replacement for typeid. -    StackProtector() : FunctionPass(ID), TLI(0) {} +    StackProtector() : FunctionPass(ID), TLI(0) { +      initializeStackProtectorPass(*PassRegistry::getPassRegistry()); +    }      StackProtector(const TargetLowering *tli) -      : FunctionPass(ID), TLI(tli) {} +      : FunctionPass(ID), TLI(tli) { +        initializeStackProtectorPass(*PassRegistry::getPassRegistry()); +      } + +    virtual void getAnalysisUsage(AnalysisUsage &AU) const { +      AU.addPreserved<DominatorTree>(); +    }      virtual bool runOnFunction(Function &Fn);    }; @@ -72,7 +83,7 @@ namespace {  char StackProtector::ID = 0;  INITIALIZE_PASS(StackProtector, "stack-protector", -                "Insert stack protectors", false, false); +                "Insert stack protectors", false, false)  FunctionPass *llvm::createStackProtectorPass(const TargetLowering *tli) {    return new StackProtector(tli); @@ -81,6 +92,7 @@ FunctionPass *llvm::createStackProtectorPass(const TargetLowering *tli) {  bool StackProtector::runOnFunction(Function &Fn) {    F = &Fn;    M = F->getParent(); +  DT = getAnalysisIfAvailable<DominatorTree>();    if (!RequiresStackProtector()) return false; @@ -135,6 +147,7 @@ bool StackProtector::RequiresStackProtector() const {  ///    value. It calls __stack_chk_fail if they differ.  bool StackProtector::InsertStackProtectors() {    BasicBlock *FailBB = 0;       // The basic block to jump to if check fails. +  BasicBlock *FailBBDom = 0;    // FailBB's dominator.    AllocaInst *AI = 0;           // Place on stack that stores the stack guard.    Value *StackGuardVar = 0;  // The stack guard variable. @@ -178,6 +191,8 @@ bool StackProtector::InsertStackProtectors() {        // Create the basic block to jump to when the guard check fails.        FailBB = CreateFailBB(); +      if (DT) +        FailBBDom = DT->isReachableFromEntry(BB) ? BB : 0;      }      // For each block with a return instruction, convert this: @@ -204,6 +219,10 @@ bool StackProtector::InsertStackProtectors() {      // Split the basic block before the return instruction.      BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return"); +    if (DT) { +      DT->addNewBlock(NewBB, DT->isReachableFromEntry(BB) ? BB : 0); +      FailBBDom = DT->findNearestCommonDominator(FailBBDom, BB); +    }      // Remove default branch instruction to the new BB.      BB->getTerminator()->eraseFromParent(); @@ -223,6 +242,9 @@ bool StackProtector::InsertStackProtectors() {    // statements in the function.    if (!FailBB) return false; +  if (DT) +    DT->addNewBlock(FailBB, FailBBDom); +    return true;  }  | 
