diff options
author | Bill Wendling <isanbard@gmail.com> | 2008-11-07 01:23:58 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2008-11-07 01:23:58 +0000 |
commit | b7c6ebcb4732302310cfaca81e1d26c3802c1646 (patch) | |
tree | a5d148dcb2aa4d8795973e94eabea5d8fef74803 /lib/CodeGen/StackProtector.cpp | |
parent | 848693c254c1fc4d4956cbe1778b244bb035e0a0 (diff) |
- Modify the stack protector algorithm so that the stack slot is allocated in
LLVM IR code and not in the selection DAG ISel. This is a cleaner solution.
- Fix the heuristic for determining if protectors are necessary. The previous
one wasn't checking the proper type size.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58824 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/StackProtector.cpp')
-rw-r--r-- | lib/CodeGen/StackProtector.cpp | 60 |
1 files changed, 29 insertions, 31 deletions
diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp index 3f5e9802e7..19fd45cbac 100644 --- a/lib/CodeGen/StackProtector.cpp +++ b/lib/CodeGen/StackProtector.cpp @@ -97,9 +97,6 @@ bool StackProtector::runOnFunction(Function &Fn) { /// - The epilogue checks the value stored in the prologue against the original /// value. It calls __stack_chk_fail if they differ. bool StackProtector::InsertStackProtectors() { - Constant *StackGuardVar = 0; // The global variable for the stack guard. - BasicBlock *FailBB = 0; // The basic block to jump to if check fails. - // Loop through the basic blocks that have return instructions. Convert this: // // return: @@ -122,18 +119,34 @@ bool StackProtector::InsertStackProtectors() { // call void @__stack_chk_fail() // unreachable // + BasicBlock *FailBB = 0; // The basic block to jump to if check fails. + AllocaInst *AI = 0; // Place on stack that stores the stack guard. + Constant *StackGuardVar = 0; // The stack guard variable. + for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) { BasicBlock *BB = I; if (isa<ReturnInst>(BB->getTerminator())) { - // Create the basic block to jump to when the guard check fails. - if (!FailBB) + if (!FailBB) { + // Create the basic block to jump to when the guard check fails. FailBB = CreateFailBB(); - if (!StackGuardVar) - StackGuardVar = - M->getOrInsertGlobal("__stack_chk_guard", - PointerType::getUnqual(Type::Int8Ty)); + // Insert code into the entry block that stores the __stack_chk_guard + // variable onto the stack. + PointerType *PtrTy = PointerType::getUnqual(Type::Int8Ty); + StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); + + BasicBlock &Entry = F->getEntryBlock(); + Instruction *InsPt = &Entry.front(); + + AI = new AllocaInst(PtrTy, "StackGuardSlot", InsPt); + LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, InsPt); + + Value *Args[] = { LI, AI }; + CallInst:: + Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_create), + &Args[0], array_endof(Args), "", InsPt); + } ReturnInst *RI = cast<ReturnInst>(BB->getTerminator()); Function::iterator InsPt = BB; ++InsPt; // Insertion point for new BB. @@ -151,7 +164,7 @@ bool StackProtector::InsertStackProtectors() { LoadInst *LI1 = new LoadInst(StackGuardVar, "", false, BB); CallInst *CI = CallInst:: Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_check), - "", BB); + AI, "", BB); ICmpInst *Cmp = new ICmpInst(CmpInst::ICMP_EQ, CI, LI1, "", BB); BranchInst::Create(NewBB, FailBB, Cmp, BB); } @@ -161,16 +174,6 @@ bool StackProtector::InsertStackProtectors() { // statements in the function. if (!FailBB) return false; - // Insert code into the entry block that stores the __stack_chk_guard variable - // onto the stack. - BasicBlock &Entry = F->getEntryBlock(); - Instruction *InsertPt = &Entry.front(); - - LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, InsertPt); - CallInst:: - Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_create), - LI, "", InsertPt); - return true; } @@ -202,21 +205,16 @@ bool StackProtector::RequiresStackProtector() const { for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE; ++II) if (AllocaInst *AI = dyn_cast<AllocaInst>(II)) { - if (!AI->isArrayAllocation()) continue; // Only care about arrays. - - if (ConstantInt *CI = dyn_cast<ConstantInt>(AI->getArraySize())) { - const Type *Ty = AI->getAllocatedType(); - uint64_t TySize = TD->getABITypeSize(Ty); + if (AI->isArrayAllocation()) + // This is a call to alloca with a variable size. Emit stack + // protectors. + return true; + if (const ArrayType *AT = dyn_cast<ArrayType>(AI->getAllocatedType())) // If an array has more than 8 bytes of allocated space, then we // emit stack protectors. - if (SSPBufferSize <= TySize * CI->getZExtValue()) + if (SSPBufferSize <= TD->getABITypeSize(AT)) return true; - } else { - // This is a call to alloca with a variable size. Default to adding - // stack protectors. - return true; - } } } |