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