Implement stack protectors for structures with character arrays in them.

<rdar://problem/10545247>

llvm-svn: 162131
This commit is contained in:
Bill Wendling 2012-08-17 20:59:56 +00:00
parent 7b1a2e8f02
commit bfb9b7598d
1 changed files with 40 additions and 15 deletions

View File

@ -61,6 +61,11 @@ namespace {
/// check fails.
BasicBlock *CreateFailBB();
/// ContainsProtectableArray - Check whether the type either is an array or
/// contains an array of sufficient size so that we need stack protectors
/// for it.
bool ContainsProtectableArray(Type *Ty, bool InStruct = false) const;
/// RequiresStackProtector - Check whether or not this function needs a
/// stack protector based upon the stack protector level.
bool RequiresStackProtector() const;
@ -100,6 +105,39 @@ bool StackProtector::runOnFunction(Function &Fn) {
return InsertStackProtectors();
}
/// ContainsProtectableArray - Check whether the type either is an array or
/// contains a char array of sufficient size so that we need stack protectors
/// for it.
bool StackProtector::ContainsProtectableArray(Type *Ty, bool InStruct) const {
if (!Ty) return false;
if (ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
if (!AT->getElementType()->isIntegerTy(8)) {
const TargetMachine &TM = TLI->getTargetMachine();
Triple Trip(TM.getTargetTriple());
// If we're on a non-Darwin platform or we're inside of a structure, don't
// add stack protectors unless the array is a character array.
if (InStruct || !Trip.isOSDarwin())
return false;
}
// If an array has more than SSPBufferSize bytes of allocated space, then we
// emit stack protectors.
if (SSPBufferSize <= TLI->getTargetData()->getTypeAllocSize(AT))
return true;
}
const StructType *ST = dyn_cast<StructType>(Ty);
if (!ST) return false;
for (StructType::element_iterator I = ST->element_begin(),
E = ST->element_end(); I != E; ++I)
if (ContainsProtectableArray(*I, true))
return true;
return false;
}
/// RequiresStackProtector - Check whether or not this function needs a stack
/// protector based upon the stack protector level. The heuristic we use is to
/// add a guard variable to functions that call alloca, and functions with
@ -111,10 +149,6 @@ bool StackProtector::RequiresStackProtector() const {
if (!F->hasFnAttr(Attribute::StackProtect))
return false;
const TargetData *TD = TLI->getTargetData();
const TargetMachine &TM = TLI->getTargetMachine();
Triple Trip(TM.getTargetTriple());
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
BasicBlock *BB = I;
@ -126,17 +160,8 @@ bool StackProtector::RequiresStackProtector() const {
// protectors.
return true;
if (ArrayType *AT = dyn_cast<ArrayType>(AI->getAllocatedType())) {
// If we're on a non-Darwin platform, don't add stack protectors
// unless the array is a character array.
if (!Trip.isOSDarwin() && !AT->getElementType()->isIntegerTy(8))
continue;
// If an array has more than SSPBufferSize bytes of allocated space,
// then we emit stack protectors.
if (SSPBufferSize <= TD->getTypeAllocSize(AT))
return true;
}
if (ContainsProtectableArray(AI->getAllocatedType()))
return true;
}
}