[llvm] r274239 - [exceptions] Upgrade exception handlers when stack protector is used

Etienne Bergeron via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 30 08:36:59 PDT 2016


Author: etienneb
Date: Thu Jun 30 10:36:59 2016
New Revision: 274239

URL: http://llvm.org/viewvc/llvm-project?rev=274239&view=rev
Log:
[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

Added:
    llvm/trunk/test/CodeGen/WinEH/wineh-promote-eh.ll
Modified:
    llvm/trunk/lib/CodeGen/WinEHPrepare.cpp

Modified: llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/WinEHPrepare.cpp?rev=274239&r1=274238&r2=274239&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/WinEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/WinEHPrepare.cpp Thu Jun 30 10:36:59 2016
@@ -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
   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::verifyPreparedFunclet
 }
 
 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.

Added: llvm/trunk/test/CodeGen/WinEH/wineh-promote-eh.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/wineh-promote-eh.ll?rev=274239&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/wineh-promote-eh.ll (added)
+++ llvm/trunk/test/CodeGen/WinEH/wineh-promote-eh.ll Thu Jun 30 10:36:59 2016
@@ -0,0 +1,16 @@
+; RUN: opt -mtriple=i686-windows-msvc -S -winehprepare %s | FileCheck %s
+
+declare i32 @_except_handler3(...)
+
+define void @test1a() personality i32 (...)* @_except_handler3 {
+; CHECK: define void @test1a() personality i32 (...)* @_except_handler3
+entry:
+  ret void
+}
+
+define void @test1b() ssp personality i32 (...)* @_except_handler3 {
+; CHECK: define void @test1b() [[attr:.*]] personality i32 (...)* @_except_handler4
+entry:
+  ret void
+}
+




More information about the llvm-commits mailing list