StackProtector.cpp revision 7205677a46d02867004826218942dab3b466c926
18c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen//===-- StackProtector.cpp - Stack Protector Insertion --------------------===//
28c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen//
3ecc6b8c25a7e8d9d2b78889e88224354a1cc3160tuexen//                     The LLVM Compiler Infrastructure
4ecc6b8c25a7e8d9d2b78889e88224354a1cc3160tuexen//
58c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen// This file is distributed under the University of Illinois Open Source
68c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen// License. See LICENSE.TXT for details.
78c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen//
88c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen//===----------------------------------------------------------------------===//
98c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen//
100ac02f34d6041cd0018437596a5a9a94685e6919tuexen// This pass inserts stack protectors into functions which need them. A variable
118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen// with a random value in it is stored onto the stack before the local variables
128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen// are allocated. Upon exiting the block, the stored value is checked. If it's
138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen// changed, then there was some sort of violation and the program aborts.
140ac02f34d6041cd0018437596a5a9a94685e6919tuexen//
158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen//===----------------------------------------------------------------------===//
168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#define DEBUG_TYPE "stack-protector"
188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include "llvm/CodeGen/Passes.h"
198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include "llvm/Constants.h"
208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include "llvm/DerivedTypes.h"
218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include "llvm/Function.h"
228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include "llvm/Instructions.h"
238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include "llvm/Intrinsics.h"
248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include "llvm/Module.h"
258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include "llvm/Pass.h"
268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include "llvm/Support/CommandLine.h"
278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include "llvm/Target/TargetData.h"
288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include "llvm/Target/TargetLowering.h"
298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenusing namespace llvm;
308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen// SSPBufferSize - The lower bound for a buffer to be considered for stack
328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen// smashing protection.
338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic cl::opt<unsigned>
348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenSSPBufferSize("stack-protector-buffer-size", cl::init(8),
351b77b4778bf4ea247d4e18d1694d8dc2d3d1d150t              cl::desc("The lower bound for a buffer to be considered for "
368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen                       "stack smashing protection."));
37ecc6b8c25a7e8d9d2b78889e88224354a1cc3160tuexen
388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexennamespace {
398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  class VISIBILITY_HIDDEN StackProtector : public FunctionPass {
408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    /// Level - The level of stack protection.
418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    SSP::StackProtectorLevel Level;
428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    /// TLI - Keep a pointer of a TargetLowering to consult for determining
448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    /// target type sizes.
458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    const TargetLowering *TLI;
468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    Function *F;
488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    Module *M;
498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    /// InsertStackProtectors - Insert code into the prologue and epilogue of
518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    /// the function.
528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    ///
538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    ///  - The prologue code loads and stores the stack guard onto the stack.
548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    ///  - The epilogue checks the value stored in the prologue against the
558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    ///    original value. It calls __stack_chk_fail if they differ.
568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    bool InsertStackProtectors();
578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    /// CreateFailBB - Create a basic block to jump to when the stack protector
59e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen    /// check fails.
608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    BasicBlock *CreateFailBB();
618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    /// RequiresStackProtector - Check whether or not this function needs a
638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    /// stack protector based upon the stack protector level.
648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    bool RequiresStackProtector() const;
658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  public:
668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    static char ID;             // Pass identification, replacement for typeid.
678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    StackProtector() : FunctionPass(&ID), Level(SSP::OFF), TLI(0) {}
688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    StackProtector(SSP::StackProtectorLevel lvl, const TargetLowering *tli)
698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen      : FunctionPass(&ID), Level(lvl), TLI(tli) {}
708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    virtual bool runOnFunction(Function &Fn);
728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  };
738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} // end anonymous namespace
748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenchar StackProtector::ID = 0;
768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic RegisterPass<StackProtector>
778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenX("stack-protector", "Insert stack protectors");
788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenFunctionPass *llvm::createStackProtectorPass(SSP::StackProtectorLevel lvl,
808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen                                             const TargetLowering *tli) {
818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  return new StackProtector(lvl, tli);
828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenbool StackProtector::runOnFunction(Function &Fn) {
858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  F = &Fn;
868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  M = F->getParent();
878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
8868beeca578347438d9c434680197647ed551935ft  if (!RequiresStackProtector()) return false;
898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  return InsertStackProtectors();
918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
92b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen
938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/// InsertStackProtectors - Insert code into the prologue and epilogue of the
948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/// function.
958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen///
968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen///  - The prologue code loads and stores the stack guard onto the stack.
978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen///  - The epilogue checks the value stored in the prologue against the original
988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen///    value. It calls __stack_chk_fail if they differ.
998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenbool StackProtector::InsertStackProtectors() {
1008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  // Loop through the basic blocks that have return instructions. Convert this:
101b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen  //
1028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //   return:
1038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //     ...
1048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //     ret ...
1058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //
1068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  // into this:
1078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //
1088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //   return:
1098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //     ...
1108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //     %1 = load __stack_chk_guard
1118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //     %2 = load <stored stack guard>
1128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //     %3 = cmp i1 %1, %2
1138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //     br i1 %3, label %SP_return, label %CallStackCheckFailBlk
1148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //
1158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //   SP_return:
11668beeca578347438d9c434680197647ed551935ft  //     ret ...
1178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //
1188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //   CallStackCheckFailBlk:
1198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //     call void @__stack_chk_fail()
120b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen  //     unreachable
1218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  //
1228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  BasicBlock *FailBB = 0;       // The basic block to jump to if check fails.
1238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  AllocaInst *AI = 0;           // Place on stack that stores the stack guard.
1248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  Constant *StackGuardVar = 0;  // The stack guard variable.
1258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
1268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  for (Function::iterator I = F->begin(), E = F->end(); I != E; ) {
1278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    BasicBlock *BB = I;
1288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
1298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
1308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen      if (!FailBB) {
1318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        // Insert code into the entry block that stores the __stack_chk_guard
1328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        // variable onto the stack.
1338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        PointerType *PtrTy = PointerType::getUnqual(Type::Int8Ty);
1348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy);
1358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
1368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        BasicBlock &Entry = F->getEntryBlock();
137b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen        Instruction *InsPt = &Entry.front();
1388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
1398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        AI = new AllocaInst(PtrTy, "StackGuardSlot", InsPt);
1408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, InsPt);
1418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
1428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        Value *Args[] = { LI, AI };
1438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        CallInst::
1448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen          Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_create),
1458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen                 &Args[0], array_endof(Args), "", InsPt);
1468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
147b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen        // Create the basic block to jump to when the guard check fails.
1488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        FailBB = CreateFailBB();
1498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen      }
1508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
151e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen      Function::iterator InsPt = BB; ++InsPt; // Insertion point for new BB.
1528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen      ++I; // Skip to the next block so that we don't resplit the return block.
1538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
1548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen      // Split the basic block before the return instruction.
1558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen      BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return");
156bfb1bf7e665a02b48026482bf33d05c83dfad73bt
1578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen      // Move the newly created basic block to the point right after the old basic
158facb9a509f7ae3621b7d2771319811985d9c46b7t      // block so that it's in the "fall through" position.
159facb9a509f7ae3621b7d2771319811985d9c46b7t      NewBB->removeFromParent();
160facb9a509f7ae3621b7d2771319811985d9c46b7t      F->getBasicBlockList().insert(InsPt, NewBB);
161facb9a509f7ae3621b7d2771319811985d9c46b7t
1628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen      // Generate the stack protector instructions in the old basic block.
1638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen      LoadInst *LI1 = new LoadInst(StackGuardVar, "", false, BB);
1648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen      CallInst *CI = CallInst::
1658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_check),
1668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen               AI, "", BB);
1678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen      ICmpInst *Cmp = new ICmpInst(CmpInst::ICMP_EQ, CI, LI1, "", BB);
1688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen      BranchInst::Create(NewBB, FailBB, Cmp, BB);
1698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    } else {
1708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen      ++I;
1718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    }
1728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  }
1738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
1748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  // Return if we didn't modify any basic blocks. I.e., there are no return
1758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  // statements in the function.
1768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  if (!FailBB) return false;
177facb9a509f7ae3621b7d2771319811985d9c46b7t
1788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  return true;
179facb9a509f7ae3621b7d2771319811985d9c46b7t}
180bfb1bf7e665a02b48026482bf33d05c83dfad73bt
1818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/// CreateFailBB - Create a basic block to jump to when the stack protector
1828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/// check fails.
1838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenBasicBlock *StackProtector::CreateFailBB() {
1848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  BasicBlock *FailBB = BasicBlock::Create("CallStackCheckFailBlk", F);
1858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  Constant *StackChkFail =
186b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen    M->getOrInsertFunction("__stack_chk_fail", Type::VoidTy, NULL);
1878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  CallInst::Create(StackChkFail, "", FailBB);
1888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  new UnreachableInst(FailBB);
189bfb1bf7e665a02b48026482bf33d05c83dfad73bt  return FailBB;
1908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
1918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
1927b0ab5c1c85787647428afafeff9491e9b6a60c7t/// RequiresStackProtector - Check whether or not this function needs a stack
1938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/// protector based upon the stack protector level. The heuristic we use is to
1948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/// add a guard variable to functions that call alloca, and functions with
1958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/// buffers larger than 8 bytes.
1968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenbool StackProtector::RequiresStackProtector() const {
1978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  switch (Level) {
1988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  default: return false;
1998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  case SSP::ALL: return true;
2008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  case SSP::SOME: {
2018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    const TargetData *TD = TLI->getTargetData();
2028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
2038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
2048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen      BasicBlock *BB = I;
2058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
2068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen      for (BasicBlock::iterator
2078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen             II = BB->begin(), IE = BB->end(); II != IE; ++II)
2088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        if (AllocaInst *AI = dyn_cast<AllocaInst>(II)) {
2098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen          if (AI->isArrayAllocation())
2108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen            // This is a call to alloca with a variable size. Emit stack
211b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen            // protectors.
2128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen            return true;
2138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
214bfb1bf7e665a02b48026482bf33d05c83dfad73bt          if (const ArrayType *AT = dyn_cast<ArrayType>(AI->getAllocatedType()))
2158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen            // If an array has more than 8 bytes of allocated space, then we
2168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen            // emit stack protectors.
2177b0ab5c1c85787647428afafeff9491e9b6a60c7t            if (SSPBufferSize <= TD->getABITypeSize(AT))
2188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen              return true;
2198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        }
2208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    }
2218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
2228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    return false;
2238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  }
2248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  }
2258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
2268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen