diff options
author | David Bozier <seifsta@gmail.com> | 2017-02-09 15:08:40 +0000 |
---|---|---|
committer | David Bozier <seifsta@gmail.com> | 2017-02-09 15:08:40 +0000 |
commit | 6a44b7c2ebb30624e7901862abb0b118e11c2a04 (patch) | |
tree | d725432d185f563a19dab5ec85174d35d249505c /llvm/lib/CodeGen | |
parent | dc1c3011fd2dfb75f6a1f4f20fa73344956a54a4 (diff) | |
download | bcm5719-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.cpp | 42 |
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; +} |