summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorDavid Bozier <seifsta@gmail.com>2017-02-09 15:08:40 +0000
committerDavid Bozier <seifsta@gmail.com>2017-02-09 15:08:40 +0000
commit6a44b7c2ebb30624e7901862abb0b118e11c2a04 (patch)
treed725432d185f563a19dab5ec85174d35d249505c /llvm/lib/CodeGen
parentdc1c3011fd2dfb75f6a1f4f20fa73344956a54a4 (diff)
downloadbcm5719-llvm-6a44b7c2ebb30624e7901862abb0b118e11c2a04.tar.gz
bcm5719-llvm-6a44b7c2ebb30624e7901862abb0b118e11c2a04.zip
[Stack Protection] Add diagnostic information for why stack protection was applied to a function
Stack Smash Protection is not completely free, so in hot code, the overhead it causes can cause performance issues. By adding diagnostic information for which function have SSP and why, a user can quickly determine what they can do to stop SSP being applied to a specific hot function. This change adds an SSP-specific DiagnosticInfo class and uses of it to the Stack Protection code. A subsequent change to clang will cause the remarks to be emitted when enabled. Patch by: James Henderson Differential Revision: https://reviews.llvm.org/D29023 llvm-svn: 294590
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/StackProtector.cpp42
1 files changed, 41 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp
index c2c010a29d4..ac747a44567 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -26,6 +26,7 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
@@ -51,7 +52,7 @@ static cl::opt<bool> EnableSelectionDAGSP("enable-selectiondag-sp",
char StackProtector::ID = 0;
INITIALIZE_TM_PASS(StackProtector, "stack-protector", "Insert stack protectors",
- false, true)
+ false, true)
FunctionPass *llvm::createStackProtectorPass(const TargetMachine *TM) {
return new StackProtector(TM);
@@ -223,6 +224,8 @@ bool StackProtector::RequiresStackProtector() {
return false;
if (F->hasFnAttribute(Attribute::StackProtectReq)) {
+ F->getContext().diagnose(
+ DiagnosticInfoSSP(*F, DiagnosticInfoSSP::SSPReason::Attribute));
NeedsProtector = true;
Strong = true; // Use the same heuristic as strong to determine SSPLayout
} else if (F->hasFnAttribute(Attribute::StackProtectStrong))
@@ -241,15 +244,21 @@ bool StackProtector::RequiresStackProtector() {
// A call to alloca with size >= SSPBufferSize requires
// stack protectors.
Layout.insert(std::make_pair(AI, SSPLK_LargeArray));
+ F->getContext().diagnose(
+ DiagnosticInfoSSP(*F, DiagnosticInfoSSP::SSPReason::Alloca));
NeedsProtector = true;
} else if (Strong) {
// Require protectors for all alloca calls in strong mode.
Layout.insert(std::make_pair(AI, SSPLK_SmallArray));
+ F->getContext().diagnose(
+ DiagnosticInfoSSP(*F, DiagnosticInfoSSP::SSPReason::Alloca));
NeedsProtector = true;
}
} else {
// A call to alloca with a variable size requires protectors.
Layout.insert(std::make_pair(AI, SSPLK_LargeArray));
+ F->getContext().diagnose(
+ DiagnosticInfoSSP(*F, DiagnosticInfoSSP::SSPReason::Alloca));
NeedsProtector = true;
}
continue;
@@ -259,6 +268,8 @@ bool StackProtector::RequiresStackProtector() {
if (ContainsProtectableArray(AI->getAllocatedType(), IsLarge, Strong)) {
Layout.insert(std::make_pair(AI, IsLarge ? SSPLK_LargeArray
: SSPLK_SmallArray));
+ F->getContext().diagnose(DiagnosticInfoSSP(
+ *F, DiagnosticInfoSSP::SSPReason::BufferOrStruct));
NeedsProtector = true;
continue;
}
@@ -266,6 +277,8 @@ bool StackProtector::RequiresStackProtector() {
if (Strong && HasAddressTaken(AI)) {
++NumAddrTaken;
Layout.insert(std::make_pair(AI, SSPLK_AddrOf));
+ F->getContext().diagnose(DiagnosticInfoSSP(
+ *F, DiagnosticInfoSSP::SSPReason::AddressTaken));
NeedsProtector = true;
}
}
@@ -464,3 +477,30 @@ BasicBlock *StackProtector::CreateFailBB() {
bool StackProtector::shouldEmitSDCheck(const BasicBlock &BB) const {
return HasPrologue && !HasIRCheck && dyn_cast<ReturnInst>(BB.getTerminator());
}
+
+void DiagnosticInfoSSP::print(DiagnosticPrinter &DP) const {
+ std::string Str;
+ raw_string_ostream OS(Str);
+
+ StringRef ReasonStr;
+ switch (Reason())
+ {
+ case Alloca:
+ ReasonStr = "a call to alloca or use of a variable length array";
+ break;
+ case BufferOrStruct:
+ ReasonStr = "a stack allocated buffer or struct containing a buffer";
+ break;
+ case AddressTaken:
+ ReasonStr = "the address of a local variable being taken";
+ break;
+ case Attribute:
+ ReasonStr = "a function attribute or command-line switch";
+ break;
+ }
+
+ OS << getLocationStr() << ": SSP applied to function " << Func.getName()
+ << " due to " << ReasonStr << '\n';
+ OS.flush();
+ DP << Str;
+}
OpenPOWER on IntegriCloud