StackProtector.cpp revision 35907e98626b33f6406dc498201fc59ced282c8a
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===-- StackProtector.cpp - Stack Protector Insertion --------------------===// 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// 304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt// The LLVM Compiler Infrastructure 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt// This file is distributed under the University of Illinois Open Source 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt// License. See LICENSE.TXT for details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===----------------------------------------------------------------------===// 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// This pass inserts stack protectors into functions which need them. A variable 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// with a random value in it is stored onto the stack before the local variables 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// are allocated. Upon exiting the block, the stored value is checked. If it's 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// changed, then there was some sort of violation and the program aborts. 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// 1561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt//===----------------------------------------------------------------------===// 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define DEBUG_TYPE "stack-protector" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/CodeGen/Passes.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Analysis/Dominators.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Attributes.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Constants.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/DerivedTypes.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Function.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Instructions.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Intrinsics.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Module.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Pass.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Support/CommandLine.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Target/TargetData.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Target/TargetLowering.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Target/TargetOptions.h" 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/ADT/Triple.h" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtusing namespace llvm; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtnamespace { 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt class StackProtector : public FunctionPass { 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /// TLI - Keep a pointer of a TargetLowering to consult for determining 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /// target type sizes. 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const TargetLowering *TLI; 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Function *F; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Module *M; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DominatorTree *DT; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /// InsertStackProtectors - Insert code into the prologue and epilogue of 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /// the function. 48f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /// 49f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /// - The prologue code loads and stores the stack guard onto the stack. 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /// - The epilogue checks the value stored in the prologue against the 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /// original value. It calls __stack_chk_fail if they differ. 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool InsertStackProtectors(); 5361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /// CreateFailBB - Create a basic block to jump to when the stack protector 55a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /// check fails. 56a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt BasicBlock *CreateFailBB(); 57cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 58cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /// ContainsProtectableArray - Check whether the type either is an array or 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /// contains an array of sufficient size so that we need stack protectors 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /// for it. 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool ContainsProtectableArray(Type *Ty, bool InStruct = false) const; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /// RequiresStackProtector - Check whether or not this function needs a 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /// stack protector based upon the stack protector level. 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool RequiresStackProtector() const; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt public: 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static char ID; // Pass identification, replacement for typeid. 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt StackProtector() : FunctionPass(ID), TLI(0) { 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt initializeStackProtectorPass(*PassRegistry::getPassRegistry()); 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt StackProtector(const TargetLowering *tli) 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt : FunctionPass(ID), TLI(tli) { 7361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt initializeStackProtectorPass(*PassRegistry::getPassRegistry()); 7461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 7561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 7661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt virtual void getAnalysisUsage(AnalysisUsage &AU) const { 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AU.addPreserved<DominatorTree>(); 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt virtual bool runOnFunction(Function &Fn); 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} // end anonymous namespace 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtchar StackProtector::ID = 0; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtINITIALIZE_PASS(StackProtector, "stack-protector", 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Insert stack protectors", false, false) 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtFunctionPass *llvm::createStackProtectorPass(const TargetLowering *tli) { 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return new StackProtector(tli); 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool StackProtector::runOnFunction(Function &Fn) { 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt F = &Fn; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt M = F->getParent(); 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DT = getAnalysisIfAvailable<DominatorTree>(); 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!RequiresStackProtector()) return false; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return InsertStackProtectors(); 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 101d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 102d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt/// ContainsProtectableArray - Check whether the type either is an array or 103d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt/// contains a char array of sufficient size so that we need stack protectors 104d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt/// for it. 105d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtbool StackProtector::ContainsProtectableArray(Type *Ty, bool InStruct) const { 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!Ty) return false; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ArrayType *AT = dyn_cast<ArrayType>(Ty)) { 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const TargetMachine &TM = TLI->getTargetMachine(); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!AT->getElementType()->isIntegerTy(8)) { 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Triple Trip(TM.getTargetTriple()); 111391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // If we're on a non-Darwin platform or we're inside of a structure, don't 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // add stack protectors unless the array is a character array. 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (InStruct || !Trip.isOSDarwin()) 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // If an array has more than SSPBufferSize bytes of allocated space, then we 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // emit stack protectors. 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (TM.Options.SSPBufferSize <= TLI->getTargetData()->getTypeAllocSize(AT)) 1211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return true; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const StructType *ST = dyn_cast<StructType>(Ty); 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ST) return false; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (StructType::element_iterator I = ST->element_begin(), 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt E = ST->element_end(); I != E; ++I) 129f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (ContainsProtectableArray(*I, true)) 130df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt return true; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 132818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return false; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// RequiresStackProtector - Check whether or not this function needs a stack 13604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// protector based upon the stack protector level. The heuristic we use is to 13704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// add a guard variable to functions that call alloca, and functions with 13804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// buffers larger than SSPBufferSize bytes. 13904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtbool StackProtector::RequiresStackProtector() const { 14004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (F->hasFnAttr(Attribute::StackProtectReq)) 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!F->hasFnAttr(Attribute::StackProtect)) 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) { 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BasicBlock *BB = I; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (BasicBlock::iterator 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt II = BB->begin(), IE = BB->end(); II != IE; ++II) 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (AllocaInst *AI = dyn_cast<AllocaInst>(II)) { 1521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (AI->isArrayAllocation()) 1531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // This is a call to alloca with a variable size. Emit stack 1541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // protectors. 1551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return true; 1561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ContainsProtectableArray(AI->getAllocatedType())) 1581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return true; 15961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 16004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 16104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 16204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return false; 16304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 16404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 16561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// InsertStackProtectors - Insert code into the prologue and epilogue of the 16661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// function. 16761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// 16861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// - The prologue code loads and stores the stack guard onto the stack. 16961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// - The epilogue checks the value stored in the prologue against the original 17061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// value. It calls __stack_chk_fail if they differ. 17161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtbool StackProtector::InsertStackProtectors() { 17261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt BasicBlock *FailBB = 0; // The basic block to jump to if check fails. 17361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt BasicBlock *FailBBDom = 0; // FailBB's dominator. 17461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt AllocaInst *AI = 0; // Place on stack that stores the stack guard. 17561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Value *StackGuardVar = 0; // The stack guard variable. 17661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 17761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (Function::iterator I = F->begin(), E = F->end(); I != E; ) { 17861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt BasicBlock *BB = I++; 17961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator()); 18061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!RI) continue; 18161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!FailBB) { 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Insert code into the entry block that stores the __stack_chk_guard 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // variable onto the stack: 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // entry: 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // StackGuardSlot = alloca i8* 18834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt // StackGuard = load __stack_chk_guard 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // call void @llvm.stackprotect.create(StackGuard, StackGuardSlot) 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext()); 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned AddressSpace, Offset; 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (TLI->getStackCookieLocation(AddressSpace, Offset)) { 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Constant *OffsetVal = 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ConstantInt::get(Type::getInt32Ty(RI->getContext()), Offset); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt StackGuardVar = ConstantExpr::getIntToPtr(OffsetVal, 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PointerType::get(PtrTy, AddressSpace)); 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BasicBlock &Entry = F->getEntryBlock(); 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Instruction *InsPt = &Entry.front(); 205d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AI = new AllocaInst(PtrTy, "StackGuardSlot", InsPt); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, InsPt); 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Value *Args[] = { LI, AI }; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CallInst:: 21104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector), 21204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt Args, "", InsPt); 21304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 21404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt // Create the basic block to jump to when the guard check fails. 21504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt FailBB = CreateFailBB(); 21604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 21704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 21804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt // For each block with a return instruction, convert this: 21904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt // 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // return: 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // ... 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // ret ... 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // into this: 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // return: 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // ... 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // %1 = load __stack_chk_guard 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // %2 = load StackGuardSlot 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // %3 = cmp i1 %1, %2 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // br i1 %3, label %SP_return, label %CallStackCheckFailBlk 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // SP_return: 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // ret ... 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // CallStackCheckFailBlk: 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // call void @__stack_chk_fail() 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // unreachable 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Split the basic block before the return instruction. 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return"); 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (DT && DT->isReachableFromEntry(BB)) { 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DT->addNewBlock(NewBB, BB); 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FailBBDom = FailBBDom ? DT->findNearestCommonDominator(FailBBDom, BB) :BB; 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Remove default branch instruction to the new BB. 249c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt BB->getTerminator()->eraseFromParent(); 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Move the newly created basic block to the point right after the old basic 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // block so that it's in the "fall through" position. 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NewBB->moveAfter(BB); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Generate the stack protector instructions in the old basic block. 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LoadInst *LI1 = new LoadInst(StackGuardVar, "", false, BB); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LoadInst *LI2 = new LoadInst(AI, "", true, BB); 258b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt ICmpInst *Cmp = new ICmpInst(*BB, CmpInst::ICMP_EQ, LI1, LI2, ""); 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BranchInst::Create(NewBB, FailBB, Cmp, BB); 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Return if we didn't modify any basic blocks. I.e., there are no return 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // statements in the function. 2641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!FailBB) return false; 2651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (DT && FailBBDom) 2671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt DT->addNewBlock(FailBB, FailBBDom); 2681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// CreateFailBB - Create a basic block to jump to when the stack protector 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// check fails. 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtBasicBlock *StackProtector::CreateFailBB() { 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BasicBlock *FailBB = BasicBlock::Create(F->getContext(), 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "CallStackCheckFailBlk", F); 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Constant *StackChkFail = 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt M->getOrInsertFunction("__stack_chk_fail", 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Type::getVoidTy(F->getContext()), NULL); 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CallInst::Create(StackChkFail, "", FailBB); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt new UnreachableInst(F->getContext(), FailBB); 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return FailBB; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt