StackProtector.cpp revision 1299422ee1e7834a8a697b2c915a8bfdada77246
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- StackProtector.cpp - Stack Protector Insertion --------------------===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This pass inserts stack protectors into functions which need them. A variable 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with a random value in it is stored onto the stack before the local variables 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are allocated. Upon exiting the block, the stored value is checked. If it's 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// changed, then there was some sort of violation and the program aborts. 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEBUG_TYPE "stack-protector" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/CodeGen/Passes.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Analysis/Dominators.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Attributes.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Constants.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/DerivedTypes.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Function.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Instructions.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Intrinsics.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Module.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Pass.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/CommandLine.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Target/TargetData.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Target/TargetLowering.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/Triple.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace llvm; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SSPBufferSize - The lower bound for a buffer to be considered for stack 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// smashing protection. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static cl::opt<unsigned> 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SSPBufferSize("stack-protector-buffer-size", cl::init(8), 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cl::desc("Lower bound for a buffer to be considered for " 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "stack protection")); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class StackProtector : public FunctionPass { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// TLI - Keep a pointer of a TargetLowering to consult for determining 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// target type sizes. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TargetLowering *TLI; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Function *F; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Module *M; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DominatorTree* DT; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// InsertStackProtectors - Insert code into the prologue and epilogue of 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// the function. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// - The prologue code loads and stores the stack guard onto the stack. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// - The epilogue checks the value stored in the prologue against the 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// original value. It calls __stack_chk_fail if they differ. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool InsertStackProtectors(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// CreateFailBB - Create a basic block to jump to when the stack protector 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// check fails. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BasicBlock *CreateFailBB(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// RequiresStackProtector - Check whether or not this function needs a 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// stack protector based upon the stack protector level. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool RequiresStackProtector() const; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static char ID; // Pass identification, replacement for typeid. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StackProtector() : FunctionPass(ID), TLI(0) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initializeStackProtectorPass(*PassRegistry::getPassRegistry()); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StackProtector(const TargetLowering *tli) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : FunctionPass(ID), TLI(tli) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initializeStackProtectorPass(*PassRegistry::getPassRegistry()); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void getAnalysisUsage(AnalysisUsage &AU) const { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AU.addPreserved<DominatorTree>(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool runOnFunction(Function &Fn); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // end anonymous namespace 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char StackProtector::ID = 0; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INITIALIZE_PASS(StackProtector, "stack-protector", 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Insert stack protectors", false, false) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FunctionPass *llvm::createStackProtectorPass(const TargetLowering *tli) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new StackProtector(tli); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StackProtector::runOnFunction(Function &Fn) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) F = &Fn; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) M = F->getParent(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DT = getAnalysisIfAvailable<DominatorTree>(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!RequiresStackProtector()) return false; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return InsertStackProtectors(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// RequiresStackProtector - Check whether or not this function needs a stack 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// protector based upon the stack protector level. The heuristic we use is to 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// add a guard variable to functions that call alloca, and functions with 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// buffers larger than SSPBufferSize bytes. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StackProtector::RequiresStackProtector() const { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (F->hasFnAttr(Attribute::StackProtectReq)) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!F->hasFnAttr(Attribute::StackProtect)) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TargetData *TD = TLI->getTargetData(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TargetMachine &TM = TLI->getTargetMachine(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Triple Trip(TM.getTargetTriple()); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BasicBlock *BB = I; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (BasicBlock::iterator 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) II = BB->begin(), IE = BB->end(); II != IE; ++II) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (AllocaInst *AI = dyn_cast<AllocaInst>(II)) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (AI->isArrayAllocation()) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is a call to alloca with a variable size. Emit stack 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // protectors. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ArrayType *AT = dyn_cast<ArrayType>(AI->getAllocatedType())) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we're on a non-Darwin platform, don't add stack protectors 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unless the array is a character array. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Trip.isOSDarwin() && !AT->getElementType()->isIntegerTy(8)) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If an array has more than SSPBufferSize bytes of allocated space, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // then we emit stack protectors. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SSPBufferSize <= TD->getTypeAllocSize(AT)) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// InsertStackProtectors - Insert code into the prologue and epilogue of the 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// function. 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// - The prologue code loads and stores the stack guard onto the stack. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// - The epilogue checks the value stored in the prologue against the original 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// value. It calls __stack_chk_fail if they differ. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StackProtector::InsertStackProtectors() { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BasicBlock *FailBB = 0; // The basic block to jump to if check fails. 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BasicBlock *FailBBDom = 0; // FailBB's dominator. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllocaInst *AI = 0; // Place on stack that stores the stack guard. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Value *StackGuardVar = 0; // The stack guard variable. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Function::iterator I = F->begin(), E = F->end(); I != E; ) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BasicBlock *BB = I++; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator()); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!RI) continue; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FailBB) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Insert code into the entry block that stores the __stack_chk_guard 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // variable onto the stack: 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // entry: 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // StackGuardSlot = alloca i8* 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // StackGuard = load __stack_chk_guard 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // call void @llvm.stackprotect.create(StackGuard, StackGuardSlot) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext()); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned AddressSpace, Offset; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (TLI->getStackCookieLocation(AddressSpace, Offset)) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Constant *OffsetVal = 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConstantInt::get(Type::getInt32Ty(RI->getContext()), Offset); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StackGuardVar = ConstantExpr::getIntToPtr(OffsetVal, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointerType::get(PtrTy, AddressSpace)); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BasicBlock &Entry = F->getEntryBlock(); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Instruction *InsPt = &Entry.front(); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AI = new AllocaInst(PtrTy, "StackGuardSlot", InsPt); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, InsPt); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Value *Args[] = { LI, AI }; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallInst:: 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector), 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Args, "", InsPt); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the basic block to jump to when the guard check fails. 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FailBB = CreateFailBB(); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For each block with a return instruction, convert this: 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return: 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ... 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ret ... 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // into this: 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return: 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ... 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // %1 = load __stack_chk_guard 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // %2 = load StackGuardSlot 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // %3 = cmp i1 %1, %2 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // br i1 %3, label %SP_return, label %CallStackCheckFailBlk 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SP_return: 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ret ... 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CallStackCheckFailBlk: 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // call void @__stack_chk_fail() 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unreachable 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Split the basic block before the return instruction. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return"); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (DT && DT->isReachableFromEntry(BB)) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DT->addNewBlock(NewBB, BB); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FailBBDom = FailBBDom ? DT->findNearestCommonDominator(FailBBDom, BB) :BB; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove default branch instruction to the new BB. 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BB->getTerminator()->eraseFromParent(); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Move the newly created basic block to the point right after the old basic 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // block so that it's in the "fall through" position. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NewBB->moveAfter(BB); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate the stack protector instructions in the old basic block. 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadInst *LI1 = new LoadInst(StackGuardVar, "", false, BB); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadInst *LI2 = new LoadInst(AI, "", true, BB); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ICmpInst *Cmp = new ICmpInst(*BB, CmpInst::ICMP_EQ, LI1, LI2, ""); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BranchInst::Create(NewBB, FailBB, Cmp, BB); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return if we didn't modify any basic blocks. I.e., there are no return 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // statements in the function. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FailBB) return false; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (DT && FailBBDom) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DT->addNewBlock(FailBB, FailBBDom); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// CreateFailBB - Create a basic block to jump to when the stack protector 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// check fails. 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BasicBlock *StackProtector::CreateFailBB() { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BasicBlock *FailBB = BasicBlock::Create(F->getContext(), 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CallStackCheckFailBlk", F); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Constant *StackChkFail = 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) M->getOrInsertFunction("__stack_chk_fail", 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type::getVoidTy(F->getContext()), NULL); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallInst::Create(StackChkFail, "", FailBB); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new UnreachableInst(F->getContext(), FailBB); 263 return FailBB; 264} 265