aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/WinEHPrepare.cpp
diff options
context:
space:
mode:
authorEtienne Bergeron <etienneb@google.com>2016-06-30 15:36:59 +0000
committerEtienne Bergeron <etienneb@google.com>2016-06-30 15:36:59 +0000
commit47cf4eabe6e2dac486a57bcd52437e84a772883a (patch)
tree67377266a2db445d28c48906b8c9576133b0fb87 /llvm/lib/CodeGen/WinEHPrepare.cpp
parent7521e1b880a14a9df799ef95db2a0084a51be8f1 (diff)
downloadllvm-47cf4eabe6e2dac486a57bcd52437e84a772883a.zip
llvm-47cf4eabe6e2dac486a57bcd52437e84a772883a.tar.gz
llvm-47cf4eabe6e2dac486a57bcd52437e84a772883a.tar.bz2
[exceptions] Upgrade exception handlers when stack protector is used
Summary: MSVC provide exception handlers with enhanced information to deal with security buffer feature (/GS). To be more secure, the security cookies (GS and SEH) are validated when unwinding the stack. The following code: ``` void f() {} void foo() { __try { f(); } __except(1) { f(); } } ``` Reviewers: majnemer, rnk Subscribers: thakis, llvm-commits, chrisha Differential Revision: http://reviews.llvm.org/D21101 llvm-svn: 274239
Diffstat (limited to 'llvm/lib/CodeGen/WinEHPrepare.cpp')
-rw-r--r--llvm/lib/CodeGen/WinEHPrepare.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp
index 041fb7b..e4cee0e 100644
--- a/llvm/lib/CodeGen/WinEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -20,6 +20,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -67,6 +68,7 @@ public:
}
private:
+ void promoteEHPersonality(Function &F);
void insertPHIStores(PHINode *OriginalPHI, AllocaInst *SpillSlot);
void
insertPHIStore(BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
@@ -464,6 +466,39 @@ static int addClrEHHandler(WinEHFuncInfo &FuncInfo, int HandlerParentState,
return FuncInfo.ClrEHUnwindMap.size() - 1;
}
+static Value *getStackGuardEHPersonality(Value *Pers) {
+ Function *F =
+ Pers ? dyn_cast<Function>(Pers->stripPointerCasts()) : nullptr;
+ if (!F)
+ return nullptr;
+
+ // TODO(etienneb): Upgrade exception handlers when they are working.
+ StringRef NewName = llvm::StringSwitch<StringRef>(F->getName())
+ .Case("_except_handler3", "_except_handler4")
+ .Default("");
+ if (NewName.empty())
+ return nullptr;
+
+ Module *M = F->getParent();
+ return M->getOrInsertFunction("_except_handler4", F->getFunctionType(),
+ F->getAttributes());
+}
+
+void WinEHPrepare::promoteEHPersonality(Function &F) {
+ // Promote the exception handler when stack protection is activated.
+ if (!F.hasFnAttribute(Attribute::StackProtect) &&
+ !F.hasFnAttribute(Attribute::StackProtectReq) &&
+ !F.hasFnAttribute(Attribute::StackProtectStrong))
+ return;
+
+ if (Value *PersonalityFn = F.getPersonalityFn()) {
+ if (Value *Personality = getStackGuardEHPersonality(PersonalityFn)) {
+ Function* PromotedFn = cast<Function>(Personality);
+ F.setPersonalityFn(PromotedFn);
+ }
+ }
+}
+
void llvm::calculateClrEHStateNumbers(const Function *Fn,
WinEHFuncInfo &FuncInfo) {
// Return if it's already been done.
@@ -1028,6 +1063,10 @@ void WinEHPrepare::verifyPreparedFunclets(Function &F) {
}
bool WinEHPrepare::prepareExplicitEH(Function &F) {
+ // When stack-protector is present, some exception handlers need to be
+ // promoted to a compatible handlers.
+ promoteEHPersonality(F);
+
// Remove unreachable blocks. It is not valuable to assign them a color and
// their existence can trick us into thinking values are alive when they are
// not.