summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2008-11-13 01:02:14 +0000
committerBill Wendling <isanbard@gmail.com>2008-11-13 01:02:14 +0000
commite9e6bdf27fca46dc9eca2ebdf73e03747d1859ab (patch)
tree565577ce5e9de5d74dacdf007bb6657832a9aa9f
parent7fc610f07311ecbbbdf163e5bcb45c636b87c983 (diff)
downloadllvm-e9e6bdf27fca46dc9eca2ebdf73e03747d1859ab.tar.gz
llvm-e9e6bdf27fca46dc9eca2ebdf73e03747d1859ab.tar.bz2
llvm-e9e6bdf27fca46dc9eca2ebdf73e03747d1859ab.tar.xz
Implement stack protectors as function attributes: "ssp" and "sspreq".
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59202 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Attributes.h4
-rw-r--r--include/llvm/CodeGen/Passes.h13
-rw-r--r--lib/AsmParser/LLLexer.cpp2
-rw-r--r--lib/AsmParser/llvmAsmParser.y6
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp16
-rw-r--r--lib/CodeGen/StackProtector.cpp26
-rw-r--r--lib/VMCore/Attributes.cpp4
7 files changed, 27 insertions, 44 deletions
diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h
index b2117dd6be..57f4e17c47 100644
--- a/include/llvm/Attributes.h
+++ b/include/llvm/Attributes.h
@@ -47,6 +47,8 @@ const Attributes ReadOnly = 1<<10; ///< Function only reads from memory
const Attributes NoInline = 1<<11; // inline=never
const Attributes AlwaysInline = 1<<12; // inline=always
const Attributes OptimizeForSize = 1<<13; // opt_size
+const Attributes StackProtect = 1<<14; // Stack protection.
+const Attributes StackProtectReq = 1<<15; // Stack protection required.
const Attributes Alignment = 0xffff<<16; ///< Alignment of parameter (16 bits)
// 0 = unknown, else in clear (not log)
@@ -55,7 +57,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet;
/// @brief Attributes that only apply to function.
const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
- NoInline | AlwaysInline | OptimizeForSize;
+ NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq;
/// @brief Parameter attributes that do not apply to vararg call arguments.
const Attributes VarArgsIncompatible = StructRet;
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index a933309854..e9d26cf4c2 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -26,16 +26,6 @@ namespace llvm {
class TargetLowering;
class RegisterCoalescer;
- /// StackProtectorLevel - An enumeration for when to determin when to turn
- /// stack smashing protection (SSP) on.
- namespace SSP {
- enum StackProtectorLevel {
- OFF, // Stack protectors are off.
- SOME, // Stack protectors on only for functions that require them.
- ALL // Stack protectors on for all functions.
- };
- } // end SSP namespace
-
/// createUnreachableBlockEliminationPass - The LLVM code generator does not
/// work well with unreachable basic blocks (what live ranges make sense for a
/// block that cannot be reached?). As such, a code generator should either
@@ -204,8 +194,7 @@ namespace llvm {
FunctionPass *createStackSlotColoringPass();
/// createStackProtectorPass - This pass adds stack protectors to functions.
- FunctionPass *createStackProtectorPass(SSP::StackProtectorLevel lvl,
- const TargetLowering *tli);
+ FunctionPass *createStackProtectorPass(const TargetLowering *tli);
} // End llvm namespace
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 39d62bf71c..20b2b888b1 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -499,6 +499,8 @@ int LLLexer::LexIdentifier() {
KEYWORD("noinline", NOINLINE);
KEYWORD("alwaysinline", ALWAYSINLINE);
KEYWORD("optsize", OPTSIZE);
+ KEYWORD("ssp", SSP);
+ KEYWORD("sspreq", SSPREQ);
KEYWORD("type", TYPE);
KEYWORD("opaque", OPAQUE);
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index 36b827d6b7..af8e3afee3 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -1137,7 +1137,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
// Function Attributes
%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
-%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE
+%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE SSP SSPREQ
// Visibility Styles
%token DEFAULT HIDDEN PROTECTED
@@ -1305,7 +1305,9 @@ FuncAttr : NORETURN { $$ = Attribute::NoReturn; }
| READONLY { $$ = Attribute::ReadOnly; }
| NOINLINE { $$ = Attribute::NoInline; }
| ALWAYSINLINE { $$ = Attribute::AlwaysInline; }
- | OPTSIZE { $$ = Attribute::OptimizeForSize; }
+ | OPTSIZE { $$ = Attribute::OptimizeForSize; }
+ | SSP { $$ = Attribute::StackProtect; }
+ | SSPREQ { $$ = Attribute::StackProtectReq; }
;
OptFuncAttrs : /* empty */ { $$ = Attribute::None; }
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index fee70b0015..2397a160e9 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -60,19 +60,6 @@ static cl::opt<cl::boolOrDefault>
EnableFastISelOption("fast-isel", cl::Hidden,
cl::desc("Enable the experimental \"fast\" instruction selector"));
-// Enable stack protectors.
-static cl::opt<SSP::StackProtectorLevel>
-EnableStackProtector("enable-stack-protector",
- cl::desc("Stack canary protection level: (default: off)"),
- cl::init(SSP::OFF),
- cl::values(clEnumValN(SSP::ALL, "all",
- "All functions get stack protectors."),
- clEnumValN(SSP::SOME, "some",
- "Only functions requiring stack protectors get them."),
- clEnumValN(SSP::OFF, "off",
- "No functions get stack protectors."),
- clEnumValEnd));
-
FileModel::Model
LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
raw_ostream &Out,
@@ -178,8 +165,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, bool Fast) {
if (!Fast)
PM.add(createCodeGenPreparePass(getTargetLowering()));
- if (EnableStackProtector != SSP::OFF)
- PM.add(createStackProtectorPass(EnableStackProtector, getTargetLowering()));
+ PM.add(createStackProtectorPass(getTargetLowering()));
if (PrintISelInput)
PM.add(createPrintFunctionPass("\n\n"
diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp
index 746addeba4..d724bd71f8 100644
--- a/lib/CodeGen/StackProtector.cpp
+++ b/lib/CodeGen/StackProtector.cpp
@@ -16,6 +16,7 @@
#define DEBUG_TYPE "stack-protector"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/Attributes.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
@@ -37,9 +38,6 @@ SSPBufferSize("stack-protector-buffer-size", cl::init(8),
namespace {
class VISIBILITY_HIDDEN StackProtector : public FunctionPass {
- /// Level - The level of stack protection.
- SSP::StackProtectorLevel Level;
-
/// TLI - Keep a pointer of a TargetLowering to consult for determining
/// target type sizes.
const TargetLowering *TLI;
@@ -64,9 +62,9 @@ namespace {
bool RequiresStackProtector() const;
public:
static char ID; // Pass identification, replacement for typeid.
- StackProtector() : FunctionPass(&ID), Level(SSP::OFF), TLI(0) {}
- StackProtector(SSP::StackProtectorLevel lvl, const TargetLowering *tli)
- : FunctionPass(&ID), Level(lvl), TLI(tli) {}
+ StackProtector() : FunctionPass(&ID), TLI(0) {}
+ StackProtector(const TargetLowering *tli)
+ : FunctionPass(&ID), TLI(tli) {}
virtual bool runOnFunction(Function &Fn);
};
@@ -76,9 +74,8 @@ char StackProtector::ID = 0;
static RegisterPass<StackProtector>
X("stack-protector", "Insert stack protectors");
-FunctionPass *llvm::createStackProtectorPass(SSP::StackProtectorLevel lvl,
- const TargetLowering *tli) {
- return new StackProtector(lvl, tli);
+FunctionPass *llvm::createStackProtectorPass(const TargetLowering *tli) {
+ return new StackProtector(tli);
}
bool StackProtector::runOnFunction(Function &Fn) {
@@ -193,10 +190,10 @@ BasicBlock *StackProtector::CreateFailBB() {
/// add a guard variable to functions that call alloca, and functions with
/// buffers larger than 8 bytes.
bool StackProtector::RequiresStackProtector() const {
- switch (Level) {
- default: return false;
- case SSP::ALL: return true;
- case SSP::SOME: {
+ if (F->hasFnAttr(Attribute::StackProtectReq))
+ return true;
+
+ if (F->hasFnAttr(Attribute::StackProtect)) {
const TargetData *TD = TLI->getTargetData();
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
@@ -220,5 +217,6 @@ bool StackProtector::RequiresStackProtector() const {
return false;
}
- }
+
+ return false;
}
diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp
index 433b79d77c..92acc111be 100644
--- a/lib/VMCore/Attributes.cpp
+++ b/lib/VMCore/Attributes.cpp
@@ -53,6 +53,10 @@ std::string Attribute::getAsString(Attributes Attrs) {
Result += "noinline ";
if (Attrs & Attribute::AlwaysInline)
Result += "alwaysinline ";
+ if (Attrs & Attribute::StackProtect)
+ Result += "ssp ";
+ if (Attrs & Attribute::StackProtectReq)
+ Result += "sspreq ";
if (Attrs & Attribute::Alignment) {
Result += "align ";
Result += utostr((Attrs & Attribute::Alignment) >> 16);