X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FStackProtector.cpp;h=f0a44abaf5cda1b4d4267752a46fc73f18a2a492;hb=2b33f4cbad43dcaca944d02a6ea67991ff9db9cf;hp=c333acd42a8b543e2ba23f33a266b16ef4a5d568;hpb=5601699d7c36b819179a7d89270100c34b3d0a32;p=oota-llvm.git diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp index c333acd42a8..f0a44abaf5c 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" @@ -37,7 +38,7 @@ SSPBufferSize("stack-protector-buffer-size", cl::init(8), "stack protection")); namespace { - class VISIBILITY_HIDDEN StackProtector : public FunctionPass { + class StackProtector : public FunctionPass { /// TLI - Keep a pointer of a TargetLowering to consult for determining /// target type sizes. const TargetLowering *TLI; @@ -45,6 +46,8 @@ namespace { Function *F; Module *M; + DominatorTree* DT; + /// InsertStackProtectors - Insert code into the prologue and epilogue of /// the function. /// @@ -62,17 +65,25 @@ 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(); + } virtual bool runOnFunction(Function &Fn); }; } // end anonymous namespace char StackProtector::ID = 0; -static RegisterPass -X("stack-protector", "Insert stack protectors"); +INITIALIZE_PASS(StackProtector, "stack-protector", + "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(); if (!RequiresStackProtector()) return false; @@ -111,11 +123,16 @@ bool StackProtector::RequiresStackProtector() const { // protectors. return true; - if (const ArrayType *AT = dyn_cast(AI->getAllocatedType())) + if (const ArrayType *AT = dyn_cast(AI->getAllocatedType())) { + // We apparently only care about character arrays. + if (!AT->getElementType()->isIntegerTy(8)) + continue; + // If an array has more than SSPBufferSize bytes of allocated space, // then we emit stack protectors. - if (SSPBufferSize <= TD->getTypePaddedSize(AT)) + if (SSPBufferSize <= TD->getTypeAllocSize(AT)) return true; + } } } @@ -130,12 +147,12 @@ 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. - Constant *StackGuardVar = 0; // The stack guard variable. + Value *StackGuardVar = 0; // The stack guard variable. for (Function::iterator I = F->begin(), E = F->end(); I != E; ) { BasicBlock *BB = I++; - ReturnInst *RI = dyn_cast(BB->getTerminator()); if (!RI) continue; @@ -148,8 +165,17 @@ bool StackProtector::InsertStackProtectors() { // StackGuard = load __stack_chk_guard // call void @llvm.stackprotect.create(StackGuard, StackGuardSlot) // - PointerType *PtrTy = PointerType::getUnqual(Type::Int8Ty); - StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); + const PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext()); + unsigned AddressSpace, Offset; + if (TLI->getStackCookieLocation(AddressSpace, Offset)) { + Constant *OffsetVal = + ConstantInt::get(Type::getInt32Ty(RI->getContext()), Offset); + + StackGuardVar = ConstantExpr::getIntToPtr(OffsetVal, + PointerType::get(PtrTy, AddressSpace)); + } else { + StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); + } BasicBlock &Entry = F->getEntryBlock(); Instruction *InsPt = &Entry.front(); @@ -191,6 +217,11 @@ bool StackProtector::InsertStackProtectors() { // Split the basic block before the return instruction. BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return"); + if (DT && DT->isReachableFromEntry(BB)) { + DT->addNewBlock(NewBB, BB); + FailBBDom = FailBBDom ? DT->findNearestCommonDominator(FailBBDom, BB) :BB; + } + // Remove default branch instruction to the new BB. BB->getTerminator()->eraseFromParent(); @@ -201,7 +232,7 @@ bool StackProtector::InsertStackProtectors() { // Generate the stack protector instructions in the old basic block. LoadInst *LI1 = new LoadInst(StackGuardVar, "", false, BB); LoadInst *LI2 = new LoadInst(AI, "", true, BB); - ICmpInst *Cmp = new ICmpInst(CmpInst::ICMP_EQ, LI1, LI2, "", BB); + ICmpInst *Cmp = new ICmpInst(*BB, CmpInst::ICMP_EQ, LI1, LI2, ""); BranchInst::Create(NewBB, FailBB, Cmp, BB); } @@ -209,16 +240,21 @@ bool StackProtector::InsertStackProtectors() { // statements in the function. if (!FailBB) return false; + if (DT && FailBBDom) + DT->addNewBlock(FailBB, FailBBDom); + return true; } /// CreateFailBB - Create a basic block to jump to when the stack protector /// check fails. BasicBlock *StackProtector::CreateFailBB() { - BasicBlock *FailBB = BasicBlock::Create("CallStackCheckFailBlk", F); + BasicBlock *FailBB = BasicBlock::Create(F->getContext(), + "CallStackCheckFailBlk", F); Constant *StackChkFail = - M->getOrInsertFunction("__stack_chk_fail", Type::VoidTy, NULL); + M->getOrInsertFunction("__stack_chk_fail", + Type::getVoidTy(F->getContext()), NULL); CallInst::Create(StackChkFail, "", FailBB); - new UnreachableInst(FailBB); + new UnreachableInst(F->getContext(), FailBB); return FailBB; }