зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
1bd1f6e85a
Коммит
45483f7a1b
|
@ -84,6 +84,10 @@ public:
|
||||||
|
|
||||||
unsigned OpenCL : 1; // OpenCL C99 language extensions.
|
unsigned OpenCL : 1; // OpenCL C99 language extensions.
|
||||||
|
|
||||||
|
unsigned StackProtector : 2; // Whether stack protectors are on:
|
||||||
|
// 0 - None
|
||||||
|
// 1 - On
|
||||||
|
// 2 - All
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned GC : 2; // Objective-C Garbage Collection modes. We declare
|
unsigned GC : 2; // Objective-C Garbage Collection modes. We declare
|
||||||
|
@ -116,7 +120,7 @@ public:
|
||||||
Exceptions = NeXTRuntime = Freestanding = NoBuiltin = 0;
|
Exceptions = NeXTRuntime = Freestanding = NoBuiltin = 0;
|
||||||
LaxVectorConversions = 1;
|
LaxVectorConversions = 1;
|
||||||
HeinousExtensions = 0;
|
HeinousExtensions = 0;
|
||||||
AltiVec = OpenCL = 0;
|
AltiVec = OpenCL = StackProtector = 0;
|
||||||
|
|
||||||
SymbolVisibility = (unsigned) Default;
|
SymbolVisibility = (unsigned) Default;
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,8 @@ namespace driver {
|
||||||
/// \arg Claim Whether the argument should be claimed, if it exists.
|
/// \arg Claim Whether the argument should be claimed, if it exists.
|
||||||
Arg *getLastArg(options::ID Id, bool Claim=true) const;
|
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, 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.
|
/// getArgString - Return the input argument string at \arg Index.
|
||||||
virtual const char *getArgString(unsigned Index) const = 0;
|
virtual const char *getArgString(unsigned Index) const = 0;
|
||||||
|
|
|
@ -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-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-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-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-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-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)
|
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("-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-bitfields", fsigned_bitfields, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||||
OPTION("-fsigned-char", fsigned_char, 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("-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("-fsyntax-only", fsyntax_only, Flag, INVALID, INVALID, "d", 0, 0, 0)
|
||||||
OPTION("-ftemplate-depth-", ftemplate_depth_, Joined, f_Group, INVALID, "", 0, 0, 0)
|
OPTION("-ftemplate-depth-", ftemplate_depth_, Joined, f_Group, INVALID, "", 0, 0, 0)
|
||||||
|
|
|
@ -235,11 +235,14 @@ static void GetDarwinLanguageOptions(LangOptions &Opts,
|
||||||
if (!getDarwinNumber(Triple, Maj, Min, Rev))
|
if (!getDarwinNumber(Triple, Maj, Min, Rev))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Blocks default to on for 10.6 (darwin10) and beyond.
|
// Blocks and stack protectors default to on for 10.6 (darwin10) and beyond.
|
||||||
// As does nonfragile-abi for 64bit mode
|
if (Maj > 9) {
|
||||||
if (Maj > 9)
|
|
||||||
Opts.Blocks = 1;
|
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))
|
if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
|
||||||
Opts.ObjCNonFragileABI = 1;
|
Opts.ObjCNonFragileABI = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -392,6 +392,11 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
|
||||||
if (CompileOpts.NoImplicitFloat)
|
if (CompileOpts.NoImplicitFloat)
|
||||||
FuncAttrs |= llvm::Attribute::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();
|
QualType RetTy = FI.getReturnType();
|
||||||
unsigned Index = 1;
|
unsigned Index = 1;
|
||||||
const ABIArgInfo &RetAI = FI.getReturnInfo();
|
const ABIArgInfo &RetAI = FI.getReturnInfo();
|
||||||
|
|
|
@ -49,6 +49,35 @@ Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, bool Claim) const {
|
||||||
return Res;
|
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 {
|
bool ArgList::hasFlag(options::ID Pos, options::ID Neg, bool Default) const {
|
||||||
if (Arg *A = getLastArg(Pos, Neg))
|
if (Arg *A = getLastArg(Pos, Neg))
|
||||||
return A->getOption().matches(Pos);
|
return A->getOption().matches(Pos);
|
||||||
|
|
|
@ -498,6 +498,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||||
Args.AddLastArg(CmdArgs, options::OPT_fvisibility_EQ);
|
Args.AddLastArg(CmdArgs, options::OPT_fvisibility_EQ);
|
||||||
Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
|
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
|
// Forward -f options with positive and negative forms; we translate
|
||||||
// these by hand.
|
// these by hand.
|
||||||
|
|
||||||
|
|
|
@ -423,7 +423,12 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
|
||||||
sprintf(MacroBuf, "__DECIMAL_DIG__=%d",
|
sprintf(MacroBuf, "__DECIMAL_DIG__=%d",
|
||||||
PickFP(&TI.getLongDoubleFormat(), -1/*FIXME*/, 17, 21, 33, 36));
|
PickFP(&TI.getLongDoubleFormat(), -1/*FIXME*/, 17, 21, 33, 36));
|
||||||
DefineBuiltinMacro(Buf, MacroBuf);
|
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.
|
// Get other target #defines.
|
||||||
TI.getTargetDefines(LangOpts, Buf);
|
TI.getTargetDefines(LangOpts, Buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -660,6 +660,11 @@ PICLevel("pic-level", llvm::cl::desc("Value for __PIC__"));
|
||||||
static llvm::cl::opt<bool>
|
static llvm::cl::opt<bool>
|
||||||
StaticDefine("static-define", llvm::cl::desc("Should __STATIC__ be defined"));
|
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,
|
static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,
|
||||||
TargetInfo *Target,
|
TargetInfo *Target,
|
||||||
const llvm::StringMap<bool> &Features) {
|
const llvm::StringMap<bool> &Features) {
|
||||||
|
@ -814,6 +819,10 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,
|
||||||
|
|
||||||
Options.Static = StaticDefine;
|
Options.Static = StaticDefine;
|
||||||
|
|
||||||
|
assert(StackProtector <= 2 && "Invalid value for -stack-protector");
|
||||||
|
if (StackProtector != -1)
|
||||||
|
Options.StackProtector = StackProtector;
|
||||||
|
|
||||||
if (MainFileName.getPosition())
|
if (MainFileName.getPosition())
|
||||||
Options.setMainFileName(MainFileName.c_str());
|
Options.setMainFileName(MainFileName.c_str());
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче