diff options
| -rw-r--r-- | llvm/include/llvm/Intrinsics.td | 7 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/StackProtector.cpp | 60 | 
3 files changed, 37 insertions, 42 deletions
diff --git a/llvm/include/llvm/Intrinsics.td b/llvm/include/llvm/Intrinsics.td index 690d4a6a47c..1c8b97e21d1 100644 --- a/llvm/include/llvm/Intrinsics.td +++ b/llvm/include/llvm/Intrinsics.td @@ -179,9 +179,10 @@ def int_readcyclecounter : Intrinsic<[llvm_i64_ty]>;  // Stack Protector Intrinsics - The stackprotector_create writes the stack guard  // to the correct place on the stack frame. The stackprotector_check reads back  // the stack guard that the stackprotector_create stored. -def int_stackprotector_create : Intrinsic<[llvm_void_ty, llvm_ptr_ty], -                                          [IntrWriteMem]>; -def int_stackprotector_check  : Intrinsic<[llvm_ptr_ty], [IntrReadMem]>; +def int_stackprotector_create : Intrinsic<[llvm_void_ty, llvm_ptr_ty, +                                           llvm_ptrptr_ty], [IntrWriteMem]>; +def int_stackprotector_check  : Intrinsic<[llvm_ptr_ty, llvm_ptrptr_ty], +                                          [IntrReadMem]>;  //===------------------- Standard C Library Intrinsics --------------------===//  // diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index a0c30ff6c75..3e19b71b3bb 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -3801,14 +3801,10 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {      MachineFrameInfo *MFI = MF.getFrameInfo();      MVT PtrTy = TLI.getPointerTy(); -    // Retrieve the stack protector guard's value. -    SDValue Src = getValue(I.getOperand(1)); - -    // Create a slot on the stack for the stack protector. It should go first -    // before local variables are allocated. -    unsigned Align = -      TLI.getTargetData()->getPrefTypeAlignment(PtrTy.getTypeForMVT()); -    int FI = MFI->CreateStackObject(PtrTy.getSizeInBits() / 8, Align); +    SDValue Src = getValue(I.getOperand(1));   // The guard's value. +    AllocaInst *Slot = cast<AllocaInst>(I.getOperand(2)); + +    int FI = FuncInfo.StaticAllocaMap[Slot];      MFI->setStackProtectorIndex(FI);      SDValue FIN = DAG.getFrameIndex(FI, PtrTy); diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp index 3f5e9802e72..19fd45cbac0 100644 --- a/llvm/lib/CodeGen/StackProtector.cpp +++ b/llvm/lib/CodeGen/StackProtector.cpp @@ -97,9 +97,6 @@ bool StackProtector::runOnFunction(Function &Fn) {  ///  - The epilogue checks the value stored in the prologue against the original  ///    value. It calls __stack_chk_fail if they differ.  bool StackProtector::InsertStackProtectors() { -  Constant *StackGuardVar = 0;  // The global variable for the stack guard. -  BasicBlock *FailBB = 0;       // The basic block to jump to if check fails. -    // Loop through the basic blocks that have return instructions. Convert this:    //    //   return: @@ -122,18 +119,34 @@ bool StackProtector::InsertStackProtectors() {    //     call void @__stack_chk_fail()    //     unreachable    // +  BasicBlock *FailBB = 0;       // The basic block to jump to if check fails. +  AllocaInst *AI = 0;           // Place on stack that stores the stack guard. +  Constant *StackGuardVar = 0;  // The stack guard variable. +    for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {      BasicBlock *BB = I;      if (isa<ReturnInst>(BB->getTerminator())) { -      // Create the basic block to jump to when the guard check fails. -      if (!FailBB) +      if (!FailBB) { +        // Create the basic block to jump to when the guard check fails.          FailBB = CreateFailBB(); -      if (!StackGuardVar) -        StackGuardVar = -          M->getOrInsertGlobal("__stack_chk_guard", -                               PointerType::getUnqual(Type::Int8Ty)); +        // Insert code into the entry block that stores the __stack_chk_guard +        // variable onto the stack. +        PointerType *PtrTy = PointerType::getUnqual(Type::Int8Ty); +        StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); + +        BasicBlock &Entry = F->getEntryBlock(); +        Instruction *InsPt = &Entry.front(); + +        AI = new AllocaInst(PtrTy, "StackGuardSlot", InsPt); +        LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, InsPt); + +        Value *Args[] = { LI, AI }; +        CallInst:: +          Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_create), +                 &Args[0], array_endof(Args), "", InsPt); +      }        ReturnInst *RI = cast<ReturnInst>(BB->getTerminator());        Function::iterator InsPt = BB; ++InsPt; // Insertion point for new BB. @@ -151,7 +164,7 @@ bool StackProtector::InsertStackProtectors() {        LoadInst *LI1 = new LoadInst(StackGuardVar, "", false, BB);        CallInst *CI = CallInst::          Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_check), -               "", BB); +               AI, "", BB);        ICmpInst *Cmp = new ICmpInst(CmpInst::ICMP_EQ, CI, LI1, "", BB);        BranchInst::Create(NewBB, FailBB, Cmp, BB);      } @@ -161,16 +174,6 @@ bool StackProtector::InsertStackProtectors() {    // statements in the function.    if (!FailBB) return false; -  // Insert code into the entry block that stores the __stack_chk_guard variable -  // onto the stack. -  BasicBlock &Entry = F->getEntryBlock(); -  Instruction *InsertPt = &Entry.front(); - -  LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, InsertPt); -  CallInst:: -    Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_create), -           LI, "", InsertPt); -    return true;  } @@ -202,21 +205,16 @@ bool StackProtector::RequiresStackProtector() const {        for (BasicBlock::iterator               II = BB->begin(), IE = BB->end(); II != IE; ++II)          if (AllocaInst *AI = dyn_cast<AllocaInst>(II)) { -          if (!AI->isArrayAllocation()) continue; // Only care about arrays. - -          if (ConstantInt *CI = dyn_cast<ConstantInt>(AI->getArraySize())) { -            const Type *Ty = AI->getAllocatedType(); -            uint64_t TySize = TD->getABITypeSize(Ty); +          if (AI->isArrayAllocation()) +            // This is a call to alloca with a variable size. Emit stack +            // protectors. +            return true; +          if (const ArrayType *AT = dyn_cast<ArrayType>(AI->getAllocatedType()))              // If an array has more than 8 bytes of allocated space, then we              // emit stack protectors. -            if (SSPBufferSize <= TySize * CI->getZExtValue()) +            if (SSPBufferSize <= TD->getABITypeSize(AT))                return true; -          } else { -            // This is a call to alloca with a variable size. Default to adding -            // stack protectors. -            return true; -          }          }      }  | 

