From 1299422ee1e7834a8a697b2c915a8bfdada77246 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 7 Aug 2012 20:59:05 +0000 Subject: For non-Darwin platforms, we want to generate stack protectors only for character arrays. This is in line with what GCC does. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161446 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/StackProtector.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'lib/CodeGen/StackProtector.cpp') diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp index 43a6ad8c97..1a12303e95 100644 --- a/lib/CodeGen/StackProtector.cpp +++ b/lib/CodeGen/StackProtector.cpp @@ -28,6 +28,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLowering.h" +#include "llvm/ADT/Triple.h" using namespace llvm; // SSPBufferSize - The lower bound for a buffer to be considered for stack @@ -111,6 +112,8 @@ bool StackProtector::RequiresStackProtector() const { 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; @@ -123,11 +126,17 @@ bool StackProtector::RequiresStackProtector() const { // protectors. return true; - if (ArrayType *AT = dyn_cast(AI->getAllocatedType())) + if (ArrayType *AT = dyn_cast(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; + } } } -- cgit v1.2.3-70-g09d2 From 6d86f3cdfc8d750d73f4a711ec74300fcb8644cb Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 13 Aug 2012 21:20:43 +0000 Subject: Whitespace cleanup. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161788 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/StackProtector.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/CodeGen/StackProtector.cpp') diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp index 1a12303e95..f1eab1f8e7 100644 --- a/lib/CodeGen/StackProtector.cpp +++ b/lib/CodeGen/StackProtector.cpp @@ -47,7 +47,7 @@ namespace { Function *F; Module *M; - DominatorTree* DT; + DominatorTree *DT; /// InsertStackProtectors - Insert code into the prologue and epilogue of /// the function. @@ -71,8 +71,8 @@ namespace { } StackProtector(const TargetLowering *tli) : FunctionPass(ID), TLI(tli) { - initializeStackProtectorPass(*PassRegistry::getPassRegistry()); - } + initializeStackProtectorPass(*PassRegistry::getPassRegistry()); + } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addPreserved(); @@ -96,7 +96,7 @@ bool StackProtector::runOnFunction(Function &Fn) { DT = getAnalysisIfAvailable(); if (!RequiresStackProtector()) return false; - + return InsertStackProtectors(); } @@ -168,17 +168,17 @@ bool StackProtector::InsertStackProtectors() { // StackGuardSlot = alloca i8* // StackGuard = load __stack_chk_guard // call void @llvm.stackprotect.create(StackGuard, StackGuardSlot) - // + // PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext()); unsigned AddressSpace, Offset; if (TLI->getStackCookieLocation(AddressSpace, Offset)) { Constant *OffsetVal = ConstantInt::get(Type::getInt32Ty(RI->getContext()), Offset); - + StackGuardVar = ConstantExpr::getIntToPtr(OffsetVal, PointerType::get(PtrTy, AddressSpace)); } else { - StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); + StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); } BasicBlock &Entry = F->getEntryBlock(); -- cgit v1.2.3-70-g09d2 From a67eda76c0224ec272e2cc7cf919f4e6e213e275 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 17 Aug 2012 20:59:56 +0000 Subject: Implement stack protectors for structures with character arrays in them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162131 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/StackProtector.cpp | 55 ++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 15 deletions(-) (limited to 'lib/CodeGen/StackProtector.cpp') diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp index f1eab1f8e7..b31db5f869 100644 --- a/lib/CodeGen/StackProtector.cpp +++ b/lib/CodeGen/StackProtector.cpp @@ -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(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(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(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; } } -- cgit v1.2.3-70-g09d2 From 35907e98626b33f6406dc498201fc59ced282c8a Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Tue, 21 Aug 2012 16:15:24 +0000 Subject: Add support for the --param ssp-buffer-size= driver option. PR9673 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162284 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetOptions.h | 4 ++++ lib/CodeGen/StackProtector.cpp | 12 +++--------- tools/llc/llc.cpp | 6 ++++++ tools/lto/LTOModule.cpp | 6 ++++++ 4 files changed, 19 insertions(+), 9 deletions(-) (limited to 'lib/CodeGen/StackProtector.cpp') diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index d1a07d1480..68ca567836 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -155,6 +155,10 @@ namespace llvm { /// automatically realigned, if needed. unsigned RealignStack : 1; + /// SSPBufferSize - The minimum size of buffers that will receive stack + /// smashing protection when -fstack-protection is used. + unsigned SSPBufferSize; + /// EnableFastISel - This flag enables fast-path instruction selection /// which trades away generated code quality in favor of reducing /// compile time. diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp index b31db5f869..a04ac3fbc1 100644 --- a/lib/CodeGen/StackProtector.cpp +++ b/lib/CodeGen/StackProtector.cpp @@ -28,16 +28,10 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLowering.h" +#include "llvm/Target/TargetOptions.h" #include "llvm/ADT/Triple.h" using namespace llvm; -// SSPBufferSize - The lower bound for a buffer to be considered for stack -// smashing protection. -static cl::opt -SSPBufferSize("stack-protector-buffer-size", cl::init(8), - cl::desc("Lower bound for a buffer to be considered for " - "stack protection")); - namespace { class StackProtector : public FunctionPass { /// TLI - Keep a pointer of a TargetLowering to consult for determining @@ -111,8 +105,8 @@ bool StackProtector::runOnFunction(Function &Fn) { bool StackProtector::ContainsProtectableArray(Type *Ty, bool InStruct) const { if (!Ty) return false; if (ArrayType *AT = dyn_cast(Ty)) { + const TargetMachine &TM = TLI->getTargetMachine(); 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 @@ -123,7 +117,7 @@ bool StackProtector::ContainsProtectableArray(Type *Ty, bool InStruct) const { // If an array has more than SSPBufferSize bytes of allocated space, then we // emit stack protectors. - if (SSPBufferSize <= TLI->getTargetData()->getTypeAllocSize(AT)) + if (TM.Options.SSPBufferSize <= TLI->getTargetData()->getTypeAllocSize(AT)) return true; } diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index 8951050c07..81f297f594 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -268,6 +268,11 @@ static cl::opt StartAfter("start-after", cl::value_desc("pass-name"), cl::init("")); +static cl::opt +SSPBufferSize("stack-protector-buffer-size", cl::init(8), + cl::desc("Lower bound for a buffer to be considered for " + "stack protection")); + // GetFileNameRoot - Helper function to get the basename of a filename. static inline std::string GetFileNameRoot(const std::string &InputFilename) { @@ -459,6 +464,7 @@ int main(int argc, char **argv) { Options.PositionIndependentExecutable = EnablePIE; Options.EnableSegmentedStacks = SegmentedStacks; Options.UseInitArray = UseInitArray; + Options.SSPBufferSize = SSPBufferSize; std::auto_ptr target(TheTarget->createTargetMachine(TheTriple.getTriple(), diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp index fa5f6b78db..d588f6a61b 100644 --- a/tools/lto/LTOModule.cpp +++ b/tools/lto/LTOModule.cpp @@ -150,6 +150,11 @@ UseInitArray("use-init-array", cl::desc("Use .init_array instead of .ctors."), cl::init(false)); +static cl::opt +SSPBufferSize("stack-protector-buffer-size", cl::init(8), + cl::desc("Lower bound for a buffer to be considered for " + "stack protection")); + LTOModule::LTOModule(llvm::Module *m, llvm::TargetMachine *t) : _module(m), _target(t), _context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(), NULL), @@ -252,6 +257,7 @@ void LTOModule::getTargetOptions(TargetOptions &Options) { Options.PositionIndependentExecutable = EnablePIE; Options.EnableSegmentedStacks = SegmentedStacks; Options.UseInitArray = UseInitArray; + Options.SSPBufferSize = SSPBufferSize; } LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer, -- cgit v1.2.3-70-g09d2