aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2009-06-28 07:36:13 +0000
committerBill Wendling <isanbard@gmail.com>2009-06-28 07:36:13 +0000
commit45483f7a1b3e57b4603b141bee80596b2d4dd443 (patch)
tree8fa4caaaa5f0ca371dd4be9d4b47f1c7808e8945
parent1bd1f6e85a011fe3129dc2898857e72741d36667 (diff)
Add stack protector support to clang. This generates the 'ssp' and 'sspreq'
function attributes. There are predefined macros that are defined when stack protectors are used: __SSP__=1 with -fstack-protector and __SSP_ALL__=2 with -fstack-protector-all. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74405 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/LangOptions.h6
-rw-r--r--include/clang/Driver/ArgList.h2
-rw-r--r--include/clang/Driver/Options.def5
-rw-r--r--lib/Basic/Targets.cpp9
-rw-r--r--lib/CodeGen/CGCall.cpp5
-rw-r--r--lib/Driver/ArgList.cpp29
-rw-r--r--lib/Driver/Tools.cpp12
-rw-r--r--lib/Frontend/InitPreprocessor.cpp7
-rw-r--r--test/CodeGen/stack-protector.c22
-rw-r--r--tools/clang-cc/clang-cc.cpp9
10 files changed, 99 insertions, 7 deletions
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index 543a0fff8e..9b308e1b32 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -84,6 +84,10 @@ public:
unsigned OpenCL : 1; // OpenCL C99 language extensions.
+ unsigned StackProtector : 2; // Whether stack protectors are on:
+ // 0 - None
+ // 1 - On
+ // 2 - All
private:
unsigned GC : 2; // Objective-C Garbage Collection modes. We declare
@@ -116,7 +120,7 @@ public:
Exceptions = NeXTRuntime = Freestanding = NoBuiltin = 0;
LaxVectorConversions = 1;
HeinousExtensions = 0;
- AltiVec = OpenCL = 0;
+ AltiVec = OpenCL = StackProtector = 0;
SymbolVisibility = (unsigned) Default;
diff --git a/include/clang/Driver/ArgList.h b/include/clang/Driver/ArgList.h
index 84e0329a37..a9c890b0b8 100644
--- a/include/clang/Driver/ArgList.h
+++ b/include/clang/Driver/ArgList.h
@@ -83,6 +83,8 @@ namespace driver {
/// \arg Claim Whether the argument should be claimed, if it exists.
Arg *getLastArg(options::ID Id, bool Claim=true) const;
Arg *getLastArg(options::ID Id0, options::ID Id1, bool Claim=true) const;
+ Arg *getLastArg(options::ID Id0, options::ID Id1, options::ID Id2,
+ bool Claim=true) const;
/// getArgString - Return the input argument string at \arg Index.
virtual const char *getArgString(unsigned Index) const = 0;
diff --git a/include/clang/Driver/Options.def b/include/clang/Driver/Options.def
index abd07a92b1..af108a85eb 100644
--- a/include/clang/Driver/Options.def
+++ b/include/clang/Driver/Options.def
@@ -420,7 +420,7 @@ OPTION("-fno-math-errno", fno_math_errno, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-pascal-strings", fno_pascal_strings, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-show-column", fno_show_column, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-show-source-location", fno_show_source_location, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-stack-protector", fno_stack_protector, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fno-stack-protector", fno_stack_protector, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-strict-aliasing", fno_strict_aliasing, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-unit-at-a-time", fno_unit_at_a_time, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-unwind-tables", fno_unwind_tables, Flag, f_Group, INVALID, "", 0, 0, 0)
@@ -450,7 +450,8 @@ OPTION("-framework", framework, Separate, INVALID, INVALID, "l", 0, 0, 0)
OPTION("-fshow-source-location", fshow_source_location, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fsigned-bitfields", fsigned_bitfields, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fsigned-char", fsigned_char, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fstack-protector", fstack_protector, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fstack-protector-all", fstack_protector_all, Flag, f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fstack-protector", fstack_protector, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fstrict-aliasing", fstrict_aliasing, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
OPTION("-fsyntax-only", fsyntax_only, Flag, INVALID, INVALID, "d", 0, 0, 0)
OPTION("-ftemplate-depth-", ftemplate_depth_, Joined, f_Group, INVALID, "", 0, 0, 0)
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 9910e28fcd..d1158a6c6f 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -235,11 +235,14 @@ static void GetDarwinLanguageOptions(LangOptions &Opts,
if (!getDarwinNumber(Triple, Maj, Min, Rev))
return;
- // Blocks default to on for 10.6 (darwin10) and beyond.
- // As does nonfragile-abi for 64bit mode
- if (Maj > 9)
+ // Blocks and stack protectors default to on for 10.6 (darwin10) and beyond.
+ if (Maj > 9) {
Opts.Blocks = 1;
+ Opts.StackProtector = 1;
+ }
+ // Non-fragile ABI (in 64-bit mode) default to on for 10.5 (darwin9) and
+ // beyond.
if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
Opts.ObjCNonFragileABI = 1;
}
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 30c5d28c22..61b6737be1 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -392,6 +392,11 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
if (CompileOpts.NoImplicitFloat)
FuncAttrs |= llvm::Attribute::NoImplicitFloat;
+ if (Features.StackProtector == 1)
+ FuncAttrs |= llvm::Attribute::StackProtect;
+ else if (Features.StackProtector == 2)
+ FuncAttrs |= llvm::Attribute::StackProtectReq;
+
QualType RetTy = FI.getReturnType();
unsigned Index = 1;
const ABIArgInfo &RetAI = FI.getReturnInfo();
diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp
index 593694cfbb..54dd4bb775 100644
--- a/lib/Driver/ArgList.cpp
+++ b/lib/Driver/ArgList.cpp
@@ -49,6 +49,35 @@ Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, bool Claim) const {
return Res;
}
+Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, options::ID Id2,
+ bool Claim) const {
+ Arg *Res = 0;
+ Arg *A0 = getLastArg(Id0, false);
+ Arg *A1 = getLastArg(Id1, false);
+ Arg *A2 = getLastArg(Id2, false);
+
+ int A0Idx = A0 ? A0->getIndex() : -1;
+ int A1Idx = A1 ? A1->getIndex() : -1;
+ int A2Idx = A2 ? A2->getIndex() : -1;
+
+ if (A0Idx > A1Idx) {
+ if (A0Idx > A2Idx)
+ Res = A0;
+ else if (A2Idx != -1)
+ Res = A2;
+ } else {
+ if (A1Idx > A2Idx)
+ Res = A1;
+ else if (A2Idx != -1)
+ Res = A2;
+ }
+
+ if (Claim && Res)
+ Res->claim();
+
+ return Res;
+}
+
bool ArgList::hasFlag(options::ID Pos, options::ID Neg, bool Default) const {
if (Arg *A = getLastArg(Pos, Neg))
return A->getOption().matches(Pos);
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index bfc247a015..ac07906c8f 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -498,6 +498,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fvisibility_EQ);
Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
+ // Forward stack protector flags.
+ if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
+ options::OPT_fstack_protector_all,
+ options::OPT_fstack_protector)) {
+ if (A->getOption().matches(options::OPT_fno_stack_protector))
+ CmdArgs.push_back("--stack-protector=0");
+ else if (A->getOption().matches(options::OPT_fstack_protector))
+ CmdArgs.push_back("--stack-protector=1");
+ else
+ CmdArgs.push_back("--stack-protector=2");
+ }
+
// Forward -f options with positive and negative forms; we translate
// these by hand.
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 730414e448..554868fd27 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -423,7 +423,12 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
sprintf(MacroBuf, "__DECIMAL_DIG__=%d",
PickFP(&TI.getLongDoubleFormat(), -1/*FIXME*/, 17, 21, 33, 36));
DefineBuiltinMacro(Buf, MacroBuf);
-
+
+ if (LangOpts.StackProtector == 1)
+ DefineBuiltinMacro(Buf, "__SSP__=1");
+ else if (LangOpts.StackProtector == 2)
+ DefineBuiltinMacro(Buf, "__SSP_ALL__=2");
+
// Get other target #defines.
TI.getTargetDefines(LangOpts, Buf);
}
diff --git a/test/CodeGen/stack-protector.c b/test/CodeGen/stack-protector.c
new file mode 100644
index 0000000000..bdac853aed
--- /dev/null
+++ b/test/CodeGen/stack-protector.c
@@ -0,0 +1,22 @@
+// RUN: clang-cc -triple i686-unknown-unknown -emit-llvm -o %t %s &&
+// RUN: not grep 'ssp' %t &&
+// RUN: clang-cc -triple i686-apple-darwin9 -emit-llvm -o %t %s &&
+// RUN: not grep 'ssp' %t &&
+// RUN: clang-cc -triple i686-apple-darwin10 -emit-llvm -o %t %s &&
+// RUN: grep 'ssp' %t &&
+// RUN: clang -fstack-protector-all -emit-llvm -S -o %t %s &&
+// RUN: grep 'sspreq' %t &&
+// RUN: clang -fstack-protector -emit-llvm -S -o %t %s &&
+// RUN: grep 'ssp' %t &&
+// RUN: clang -fno-stack-protector -emit-llvm -S -o %t %s &&
+// RUN: not grep 'ssp' %t &&
+// RUN: true
+
+#include <stdio.h>
+#include <string.h>
+
+void test1(const char *msg) {
+ char a[strlen(msg) + 1];
+ strcpy(a, msg);
+ printf("%s\n", a);
+}
diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp
index a3ffb48281..a1efe0101d 100644
--- a/tools/clang-cc/clang-cc.cpp
+++ b/tools/clang-cc/clang-cc.cpp
@@ -660,6 +660,11 @@ PICLevel("pic-level", llvm::cl::desc("Value for __PIC__"));
static llvm::cl::opt<bool>
StaticDefine("static-define", llvm::cl::desc("Should __STATIC__ be defined"));
+static llvm::cl::opt<int>
+StackProtector("stack-protector",
+ llvm::cl::desc("Enable stack protectors"),
+ llvm::cl::init(-1));
+
static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,
TargetInfo *Target,
const llvm::StringMap<bool> &Features) {
@@ -814,6 +819,10 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,
Options.Static = StaticDefine;
+ assert(StackProtector <= 2 && "Invalid value for -stack-protector");
+ if (StackProtector != -1)
+ Options.StackProtector = StackProtector;
+
if (MainFileName.getPosition())
Options.setMainFileName(MainFileName.c_str());
}