- Modify the stack protector algorithm so that the stack slot is allocated in
authorBill Wendling <isanbard@gmail.com>
Fri, 7 Nov 2008 01:23:58 +0000 (01:23 +0000)
committerBill Wendling <isanbard@gmail.com>
Fri, 7 Nov 2008 01:23:58 +0000 (01:23 +0000)
  LLVM IR code and not in the selection DAG ISel. This is a cleaner solution.

- Fix the heuristic for determining if protectors are necessary. The previous
  one wasn't checking the proper type size.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58824 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Intrinsics.td
lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
lib/CodeGen/StackProtector.cpp

index 690d4a6a47c32a7391c44823e546fd7b9679573e..1c8b97e21d18382a3d727762701127fed4723d81 100644 (file)
@@ -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 --------------------===//
 //
index a0c30ff6c756fd517a3f7fa6b3b361eee4200991..3e19b71b3bbf108d4a129c78c922edb9354191fa 100644 (file)
@@ -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);
index 3f5e9802e724b6f2b73b555ea47d6348ff305562..19fd45cbac02bc22117840fe004b90b1f6dfc11d 100644 (file)
@@ -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;
-          }
         }
     }