aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2013-01-23 06:41:41 +0000
committerBill Wendling <isanbard@gmail.com>2013-01-23 06:41:41 +0000
commit114baee1fa017daefad2339c77b45b9ca3d79a41 (patch)
treea8a1320a7ad94ac750fcca331a8db207f2fea637 /lib
parent28d65722d6f283b327b5815914382077fe9c0ab4 (diff)
downloadexternal_llvm-114baee1fa017daefad2339c77b45b9ca3d79a41.zip
external_llvm-114baee1fa017daefad2339c77b45b9ca3d79a41.tar.gz
external_llvm-114baee1fa017daefad2339c77b45b9ca3d79a41.tar.bz2
Add the IR attribute 'sspstrong'.
SSPStrong applies a heuristic to insert stack protectors in these situations: * A Protector is required for functions which contain an array, regardless of type or length. * A Protector is required for functions which contain a structure/union which contains an array, regardless of type or length. Note, there is no limit to the depth of nesting. * A protector is required when the address of a local variable (i.e., stack based variable) is exposed. (E.g., such as through a local whose address is taken as part of the RHS of an assignment or a local whose address is taken as part of a function argument.) This patch implements the SSPString attribute to be equivalent to SSPRequired. This will change in a subsequent patch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173230 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AsmParser/LLLexer.cpp1
-rw-r--r--lib/AsmParser/LLParser.cpp11
-rw-r--r--lib/AsmParser/LLToken.h1
-rw-r--r--lib/CodeGen/StackProtector.cpp6
-rw-r--r--lib/IR/Attributes.cpp3
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp1
-rw-r--r--lib/Transforms/IPO/Inliner.cpp45
7 files changed, 53 insertions, 15 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 2efa1f0..85e7574 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -549,6 +549,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(optsize);
KEYWORD(ssp);
KEYWORD(sspreq);
+ KEYWORD(sspstrong);
KEYWORD(noredzone);
KEYWORD(noimplicitfloat);
KEYWORD(naked);
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index fea5ec8..0eb6023 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -956,6 +956,7 @@ bool LLParser::ParseOptionalFuncAttrs(AttrBuilder &B) {
case lltok::kw_returns_twice: B.addAttribute(Attribute::ReturnsTwice); break;
case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break;
case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break;
+ case lltok::kw_sspstrong: B.addAttribute(Attribute::StackProtectStrong); break;
case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break;
case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break;
@@ -1050,11 +1051,11 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
case lltok::kw_readonly: case lltok::kw_inlinehint:
case lltok::kw_alwaysinline: case lltok::kw_optsize:
case lltok::kw_ssp: case lltok::kw_sspreq:
- case lltok::kw_noredzone: case lltok::kw_noimplicitfloat:
- case lltok::kw_naked: case lltok::kw_nonlazybind:
- case lltok::kw_address_safety: case lltok::kw_minsize:
- case lltok::kw_alignstack: case lltok::kw_align:
- case lltok::kw_noduplicate:
+ case lltok::kw_sspstrong: case lltok::kw_noimplicitfloat:
+ case lltok::kw_noredzone: case lltok::kw_naked:
+ case lltok::kw_nonlazybind: case lltok::kw_address_safety:
+ case lltok::kw_minsize: case lltok::kw_alignstack:
+ case lltok::kw_align: case lltok::kw_noduplicate:
HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
break;
}
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index 5b4d415..fea5f75 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -110,6 +110,7 @@ namespace lltok {
kw_optsize,
kw_ssp,
kw_sspreq,
+ kw_sspstrong,
kw_noredzone,
kw_noimplicitfloat,
kw_naked,
diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp
index e242804..049efc1 100644
--- a/lib/CodeGen/StackProtector.cpp
+++ b/lib/CodeGen/StackProtector.cpp
@@ -141,6 +141,12 @@ bool StackProtector::RequiresStackProtector() const {
Attribute::StackProtectReq))
return true;
+ // FIXME: Dummy SSP-strong implementation. Default to required until
+ // strong heuristic is implemented.
+ if (F->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::StackProtectStrong))
+ return true;
+
if (!F->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
Attribute::StackProtect))
return false;
diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp
index 4bd2391..964a404 100644
--- a/lib/IR/Attributes.cpp
+++ b/lib/IR/Attributes.cpp
@@ -206,6 +206,8 @@ std::string Attribute::getAsString() const {
Result += "ssp ";
if (hasAttribute(Attribute::StackProtectReq))
Result += "sspreq ";
+ if (hasAttribute(Attribute::StackProtectStrong))
+ Result += "sspstrong ";
if (hasAttribute(Attribute::NoRedZone))
Result += "noredzone ";
if (hasAttribute(Attribute::NoImplicitFloat))
@@ -487,6 +489,7 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) {
case Attribute::AddressSafety: return 1ULL << 32;
case Attribute::MinSize: return 1ULL << 33;
case Attribute::NoDuplicate: return 1ULL << 34;
+ case Attribute::StackProtectStrong: return 1ULL << 35;
}
llvm_unreachable("Unsupported attribute type");
}
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index f468861..50bfef5 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -499,6 +499,7 @@ void CppWriter::printAttributes(const AttributeSet &PAL,
HANDLE_ATTR(OptimizeForSize);
HANDLE_ATTR(StackProtect);
HANDLE_ATTR(StackProtectReq);
+ HANDLE_ATTR(StackProtectStrong);
HANDLE_ATTR(NoCapture);
HANDLE_ATTR(NoRedZone);
HANDLE_ATTR(NoImplicitFloat);
diff --git a/lib/Transforms/IPO/Inliner.cpp b/lib/Transforms/IPO/Inliner.cpp
index 2187a2a..663ddb7 100644
--- a/lib/Transforms/IPO/Inliner.cpp
+++ b/lib/Transforms/IPO/Inliner.cpp
@@ -72,6 +72,40 @@ void Inliner::getAnalysisUsage(AnalysisUsage &AU) const {
typedef DenseMap<ArrayType*, std::vector<AllocaInst*> >
InlinedArrayAllocasTy;
+/// \brief If the inlined function had a higher stack protection level than the
+/// calling function, then bump up the caller's stack protection level.
+static void AdjustCallerSSPLevel(Function *Caller, Function *Callee) {
+ // If upgrading the SSP attribute, clear out the old SSP Attributes first.
+ // Having multiple SSP attributes doesn't actually hurt, but it adds useless
+ // clutter to the IR.
+ AttrBuilder B;
+ B.addAttribute(Attribute::StackProtect)
+ .addAttribute(Attribute::StackProtectStrong);
+ AttributeSet OldSSPAttr = AttributeSet::get(Caller->getContext(),
+ AttributeSet::FunctionIndex,
+ B);
+ AttributeSet CallerAttr = Caller->getAttributes(),
+ CalleeAttr = Callee->getAttributes();
+
+ if (CalleeAttr.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::StackProtectReq)) {
+ Caller->removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
+ Caller->addFnAttr(Attribute::StackProtectReq);
+ } else if (CalleeAttr.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::StackProtectStrong) &&
+ !CallerAttr.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::StackProtectReq)) {
+ Caller->removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
+ Caller->addFnAttr(Attribute::StackProtectStrong);
+ } else if (CalleeAttr.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::StackProtect) &&
+ !CallerAttr.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::StackProtectReq) &&
+ !CallerAttr.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::StackProtectStrong))
+ Caller->addFnAttr(Attribute::StackProtect);
+}
+
/// InlineCallIfPossible - If it is possible to inline the specified call site,
/// do so and update the CallGraph for this operation.
///
@@ -91,16 +125,7 @@ static bool InlineCallIfPossible(CallSite CS, InlineFunctionInfo &IFI,
if (!InlineFunction(CS, IFI, InsertLifetime))
return false;
- // If the inlined function had a higher stack protection level than the
- // calling function, then bump up the caller's stack protection level.
- if (Callee->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
- Attribute::StackProtectReq))
- Caller->addFnAttr(Attribute::StackProtectReq);
- else if (Callee->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
- Attribute::StackProtect) &&
- !Caller->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
- Attribute::StackProtectReq))
- Caller->addFnAttr(Attribute::StackProtect);
+ AdjustCallerSSPLevel(Caller, Callee);
// Look at all of the allocas that we inlined through this call site. If we
// have already inlined other allocas through other calls into this function,