llvm.org GIT mirror llvm / 6e9bd6a
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274239 91177308-0d34-0410-b5e6-96231b3b80d8 Etienne Bergeron 4 years ago
2 changed file(s) with 55 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
1919 #include "llvm/ADT/DenseMap.h"
2020 #include "llvm/ADT/MapVector.h"
2121 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/ADT/StringSwitch.h"
2223 #include "llvm/Analysis/CFG.h"
2324 #include "llvm/Analysis/EHPersonalities.h"
2425 #include "llvm/CodeGen/MachineBasicBlock.h"
6667 }
6768
6869 private:
70 void promoteEHPersonality(Function &F);
6971 void insertPHIStores(PHINode *OriginalPHI, AllocaInst *SpillSlot);
7072 void
7173 insertPHIStore(BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
462464 FuncInfo.ClrEHUnwindMap.push_back(Entry);
463465 return FuncInfo.ClrEHUnwindMap.size() - 1;
464466 }
467
468 static Value *getStackGuardEHPersonality(Value *Pers) {
469 Function *F =
470 Pers ? dyn_cast(Pers->stripPointerCasts()) : nullptr;
471 if (!F)
472 return nullptr;
473
474 // TODO(etienneb): Upgrade exception handlers when they are working.
475 StringRef NewName = llvm::StringSwitch(F->getName())
476 .Case("_except_handler3", "_except_handler4")
477 .Default("");
478 if (NewName.empty())
479 return nullptr;
480
481 Module *M = F->getParent();
482 return M->getOrInsertFunction("_except_handler4", F->getFunctionType(),
483 F->getAttributes());
484 }
485
486 void WinEHPrepare::promoteEHPersonality(Function &F) {
487 // Promote the exception handler when stack protection is activated.
488 if (!F.hasFnAttribute(Attribute::StackProtect) &&
489 !F.hasFnAttribute(Attribute::StackProtectReq) &&
490 !F.hasFnAttribute(Attribute::StackProtectStrong))
491 return;
492
493 if (Value *PersonalityFn = F.getPersonalityFn()) {
494 if (Value *Personality = getStackGuardEHPersonality(PersonalityFn)) {
495 Function* PromotedFn = cast(Personality);
496 F.setPersonalityFn(PromotedFn);
497 }
498 }
499 }
465500
466501 void llvm::calculateClrEHStateNumbers(const Function *Fn,
467502 WinEHFuncInfo &FuncInfo) {
10271062 }
10281063
10291064 bool WinEHPrepare::prepareExplicitEH(Function &F) {
1065 // When stack-protector is present, some exception handlers need to be
1066 // promoted to a compatible handlers.
1067 promoteEHPersonality(F);
1068
10301069 // Remove unreachable blocks. It is not valuable to assign them a color and
10311070 // their existence can trick us into thinking values are alive when they are
10321071 // not.
0 ; RUN: opt -mtriple=i686-windows-msvc -S -winehprepare %s | FileCheck %s
1
2 declare i32 @_except_handler3(...)
3
4 define void @test1a() personality i32 (...)* @_except_handler3 {
5 ; CHECK: define void @test1a() personality i32 (...)* @_except_handler3
6 entry:
7 ret void
8 }
9
10 define void @test1b() ssp personality i32 (...)* @_except_handler3 {
11 ; CHECK: define void @test1b() [[attr:.*]] personality i32 (...)* @_except_handler4
12 entry:
13 ret void
14 }
15