summaryrefslogtreecommitdiff
path: root/lib/CodeGen/StackProtector.cpp
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2008-11-05 00:00:21 +0000
committerBill Wendling <isanbard@gmail.com>2008-11-05 00:00:21 +0000
commit613f77439eb6e1f660e615e0e851187da13255ae (patch)
tree8ae9b3b2bae9fee455e6f1b865c14b1c09e144d0 /lib/CodeGen/StackProtector.cpp
parent8f027c7fea068394be9026a80a8cbe045ed021ee (diff)
downloadllvm-613f77439eb6e1f660e615e0e851187da13255ae.tar.gz
llvm-613f77439eb6e1f660e615e0e851187da13255ae.tar.bz2
llvm-613f77439eb6e1f660e615e0e851187da13255ae.tar.xz
Some code simplification. It now doesn't generate a prologue if the epilogue
isn't going to be generated. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58734 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/StackProtector.cpp')
-rw-r--r--lib/CodeGen/StackProtector.cpp108
1 files changed, 47 insertions, 61 deletions
diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp
index 12d56c44b2..fefa3c379f 100644
--- a/lib/CodeGen/StackProtector.cpp
+++ b/lib/CodeGen/StackProtector.cpp
@@ -43,42 +43,29 @@ namespace {
/// target type sizes.
const TargetLowering *TLI;
- /// FailBB - Holds the basic block to jump to when the stack protector check
- /// fails.
- BasicBlock *FailBB;
-
- /// StackProtFrameSlot - The place on the stack that the stack protector
- /// guard is kept.
- AllocaInst *StackProtFrameSlot;
-
- /// StackGuardVar - The global variable for the stack guard.
- Constant *StackGuardVar;
-
Function *F;
Module *M;
- /// InsertStackProtectorPrologue - Insert code into the entry block that
- /// stores the __stack_chk_guard variable onto the stack.
- void InsertStackProtectorPrologue();
-
- /// InsertStackProtectorEpilogue - Insert code before the return
- /// instructions checking the stack value that was stored in the
- /// prologue. If it isn't the same as the original value, then call a
- /// "failure" function.
- void InsertStackProtectorEpilogue();
+ /// InsertStackProtectors - Insert code into the prologue and epilogue of
+ /// the function.
+ ///
+ /// - The prologue code loads and stores the stack guard onto the stack.
+ /// - The epilogue checks the value stored in the prologue against the
+ /// original value. It calls __stack_chk_fail if they differ.
+ bool InsertStackProtectors();
/// CreateFailBB - Create a basic block to jump to when the stack protector
/// check fails.
- void CreateFailBB();
+ BasicBlock *CreateFailBB();
/// RequiresStackProtector - Check whether or not this function needs a
/// stack protector based upon the stack protector level.
bool RequiresStackProtector() const;
public:
static char ID; // Pass identification, replacement for typeid.
- StackProtector() : FunctionPass(&ID), Level(SSP::OFF), TLI(0), FailBB(0) {}
+ StackProtector() : FunctionPass(&ID), Level(SSP::OFF), TLI(0) {}
StackProtector(SSP::StackProtectorLevel lvl, const TargetLowering *tli)
- : FunctionPass(&ID), Level(lvl), TLI(tli), FailBB(0) {}
+ : FunctionPass(&ID), Level(lvl), TLI(tli) {}
virtual bool runOnFunction(Function &Fn);
};
@@ -99,45 +86,42 @@ bool StackProtector::runOnFunction(Function &Fn) {
if (!RequiresStackProtector()) return false;
- InsertStackProtectorPrologue();
- InsertStackProtectorEpilogue();
-
- // Cleanup.
- FailBB = 0;
- StackProtFrameSlot = 0;
- StackGuardVar = 0;
- return true;
-}
-
-/// InsertStackProtectorPrologue - Insert code into the entry block that stores
-/// the __stack_chk_guard variable onto the stack.
-void StackProtector::InsertStackProtectorPrologue() {
- BasicBlock &Entry = F->getEntryBlock();
- Instruction &InsertPt = Entry.front();
- const PointerType *GuardTy = PointerType::getUnqual(Type::Int8Ty);
-
- StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", GuardTy);
- StackProtFrameSlot = new AllocaInst(GuardTy, "StackProt_Frame", &InsertPt);
- LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, &InsertPt);
- new StoreInst(LI, StackProtFrameSlot, false, &InsertPt);
+ return InsertStackProtectors();
}
-/// InsertStackProtectorEpilogue - Insert code before the return instructions
-/// checking the stack value that was stored in the prologue. If it isn't the
-/// same as the original value, then call a "failure" function.
-void StackProtector::InsertStackProtectorEpilogue() {
- // Create the basic block to jump to when the guard check fails.
- CreateFailBB();
-
- Function::iterator I = F->begin(), E = F->end();
+/// InsertStackProtectors - Insert code into the prologue and epilogue of the
+/// function.
+///
+/// - The prologue code loads and stores the stack guard onto the stack.
+/// - The epilogue checks the value stored in the prologue against the original
+/// value. It calls __stack_chk_fail if they differ.
+bool StackProtector::InsertStackProtectors() {
std::vector<BasicBlock*> ReturnBBs;
- ReturnBBs.reserve(F->size());
- for (; I != E; ++I)
+ for (Function::iterator I = F->begin(); I != F->end(); ++I)
if (isa<ReturnInst>(I->getTerminator()))
ReturnBBs.push_back(I);
- if (ReturnBBs.empty()) return; // Odd, but could happen. . .
+ // If this function doesn't return, don't bother with stack protectors.
+ if (ReturnBBs.empty()) 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();
+ const PointerType *GuardTy = PointerType::getUnqual(Type::Int8Ty);
+
+ // The global variable for the stack guard.
+ Constant *StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", GuardTy);
+
+ // The place on the stack that the stack protector guard is kept.
+ AllocaInst *StackProtFrameSlot =
+ new AllocaInst(GuardTy, "StackProt_Frame", InsertPt);
+ LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, InsertPt);
+ new StoreInst(LI, StackProtFrameSlot, false, InsertPt);
+
+ // Create the basic block to jump to when the guard check fails.
+ BasicBlock *FailBB = CreateFailBB();
// Loop through the basic blocks that have return instructions. Convert this:
//
@@ -162,8 +146,8 @@ void StackProtector::InsertStackProtectorEpilogue() {
// unreachable
//
for (std::vector<BasicBlock*>::iterator
- II = ReturnBBs.begin(), IE = ReturnBBs.end(); II != IE; ++II) {
- BasicBlock *BB = *II;
+ I = ReturnBBs.begin(), E = ReturnBBs.end(); I != E; ++I) {
+ BasicBlock *BB = *I;
ReturnInst *RI = cast<ReturnInst>(BB->getTerminator());
Function::iterator InsPt = BB; ++InsPt; // Insertion point for new BB.
@@ -171,7 +155,7 @@ void StackProtector::InsertStackProtectorEpilogue() {
BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return");
// Move the newly created basic block to the point right after the old basic
- // block.
+ // block so that it's in the "fall through" position.
NewBB->removeFromParent();
F->getBasicBlockList().insert(InsPt, NewBB);
@@ -181,18 +165,20 @@ void StackProtector::InsertStackProtectorEpilogue() {
ICmpInst *Cmp = new ICmpInst(CmpInst::ICMP_EQ, LI1, LI2, "", BB);
BranchInst::Create(NewBB, FailBB, Cmp, BB);
}
+
+ return true;
}
/// CreateFailBB - Create a basic block to jump to when the stack protector
/// check fails.
-void StackProtector::CreateFailBB() {
- assert(!FailBB && "Failure basic block already created?!");
- FailBB = BasicBlock::Create("CallStackCheckFailBlk", F);
+BasicBlock *StackProtector::CreateFailBB() {
+ BasicBlock *FailBB = BasicBlock::Create("CallStackCheckFailBlk", F);
std::vector<const Type*> Params;
Constant *StackChkFail =
M->getOrInsertFunction("__stack_chk_fail", Type::VoidTy, NULL);
CallInst::Create(StackChkFail, "", FailBB);
new UnreachableInst(FailBB);
+ return FailBB;
}
/// RequiresStackProtector - Check whether or not this function needs a stack