[llvm] r238627 - [WinEH] Adjust the 32-bit SEH prologue to better match reality

Reid Kleckner reid at kleckner.net
Fri May 29 15:57:47 PDT 2015


Author: rnk
Date: Fri May 29 17:57:46 2015
New Revision: 238627

URL: http://llvm.org/viewvc/llvm-project?rev=238627&view=rev
Log:
[WinEH] Adjust the 32-bit SEH prologue to better match reality

It turns out that _except_handler3 and _except_handler4 really use the
same stack allocation layout, at least today. They just make different
choices about encoding the LSDA.

This is in preparation for lowering the llvm.eh.exceptioninfo().

Modified:
    llvm/trunk/lib/Target/X86/X86WinEHState.cpp
    llvm/trunk/test/CodeGen/X86/win32-eh.ll

Modified: llvm/trunk/lib/Target/X86/X86WinEHState.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86WinEHState.cpp?rev=238627&r1=238626&r2=238627&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86WinEHState.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86WinEHState.cpp Fri May 29 17:57:46 2015
@@ -74,17 +74,15 @@ private:
   int escapeRegNode(Function &F);
 
   // Module-level type getters.
-  Type *getEHRegistrationType();
-  Type *getSEH3RegistrationType();
-  Type *getSEH4RegistrationType();
-  Type *getCXXEH3RegistrationType();
+  Type *getEHLinkRegistrationType();
+  Type *getSEHRegistrationType();
+  Type *getCXXEHRegistrationType();
 
   // Per-module data.
   Module *TheModule = nullptr;
-  StructType *EHRegistrationTy = nullptr;
-  StructType *CXXEH3RegistrationTy = nullptr;
-  StructType *SEH3RegistrationTy = nullptr;
-  StructType *SEH4RegistrationTy = nullptr;
+  StructType *EHLinkRegistrationTy = nullptr;
+  StructType *CXXEHRegistrationTy = nullptr;
+  StructType *SEHRegistrationTy = nullptr;
 
   // Per-function state
   EHPersonality Personality = EHPersonality::Unknown;
@@ -117,10 +115,9 @@ bool WinEHStatePass::doInitialization(Mo
 bool WinEHStatePass::doFinalization(Module &M) {
   assert(TheModule == &M);
   TheModule = nullptr;
-  EHRegistrationTy = nullptr;
-  CXXEH3RegistrationTy = nullptr;
-  SEH3RegistrationTy = nullptr;
-  SEH4RegistrationTy = nullptr;
+  EHLinkRegistrationTy = nullptr;
+  CXXEHRegistrationTy = nullptr;
+  SEHRegistrationTy = nullptr;
   return false;
 }
 
@@ -182,17 +179,17 @@ bool WinEHStatePass::runOnFunction(Funct
 ///     EHRegistrationNode *Next;
 ///     PEXCEPTION_ROUTINE Handler;
 ///   };
-Type *WinEHStatePass::getEHRegistrationType() {
-  if (EHRegistrationTy)
-    return EHRegistrationTy;
+Type *WinEHStatePass::getEHLinkRegistrationType() {
+  if (EHLinkRegistrationTy)
+    return EHLinkRegistrationTy;
   LLVMContext &Context = TheModule->getContext();
-  EHRegistrationTy = StructType::create(Context, "EHRegistrationNode");
+  EHLinkRegistrationTy = StructType::create(Context, "EHRegistrationNode");
   Type *FieldTys[] = {
-      EHRegistrationTy->getPointerTo(0), // EHRegistrationNode *Next
+      EHLinkRegistrationTy->getPointerTo(0), // EHRegistrationNode *Next
       Type::getInt8PtrTy(Context) // EXCEPTION_DISPOSITION (*Handler)(...)
   };
-  EHRegistrationTy->setBody(FieldTys, false);
-  return EHRegistrationTy;
+  EHLinkRegistrationTy->setBody(FieldTys, false);
+  return EHLinkRegistrationTy;
 }
 
 /// The __CxxFrameHandler3 registration node:
@@ -201,40 +198,21 @@ Type *WinEHStatePass::getEHRegistrationT
 ///     EHRegistrationNode SubRecord;
 ///     int32_t TryLevel;
 ///   };
-Type *WinEHStatePass::getCXXEH3RegistrationType() {
-  if (CXXEH3RegistrationTy)
-    return CXXEH3RegistrationTy;
+Type *WinEHStatePass::getCXXEHRegistrationType() {
+  if (CXXEHRegistrationTy)
+    return CXXEHRegistrationTy;
   LLVMContext &Context = TheModule->getContext();
   Type *FieldTys[] = {
       Type::getInt8PtrTy(Context), // void *SavedESP
-      getEHRegistrationType(),     // EHRegistrationNode SubRecord
+      getEHLinkRegistrationType(), // EHRegistrationNode SubRecord
       Type::getInt32Ty(Context)    // int32_t TryLevel
   };
-  CXXEH3RegistrationTy =
+  CXXEHRegistrationTy =
       StructType::create(FieldTys, "CXXExceptionRegistration");
-  return CXXEH3RegistrationTy;
+  return CXXEHRegistrationTy;
 }
 
-/// The _except_handler3 registration node:
-///   struct EH3ExceptionRegistration {
-///     EHRegistrationNode SubRecord;
-///     void *ScopeTable;
-///     int32_t TryLevel;
-///   };
-Type *WinEHStatePass::getSEH3RegistrationType() {
-  if (SEH3RegistrationTy)
-    return SEH3RegistrationTy;
-  LLVMContext &Context = TheModule->getContext();
-  Type *FieldTys[] = {
-      getEHRegistrationType(),     // EHRegistrationNode SubRecord
-      Type::getInt8PtrTy(Context), // void *ScopeTable
-      Type::getInt32Ty(Context)    // int32_t TryLevel
-  };
-  SEH3RegistrationTy = StructType::create(FieldTys, "EH3ExceptionRegistration");
-  return SEH3RegistrationTy;
-}
-
-/// The _except_handler4 registration node:
+/// The _except_handler3/4 registration node:
 ///   struct EH4ExceptionRegistration {
 ///     void *SavedESP;
 ///     _EXCEPTION_POINTERS *ExceptionPointers;
@@ -242,19 +220,19 @@ Type *WinEHStatePass::getSEH3Registratio
 ///     int32_t EncodedScopeTable;
 ///     int32_t TryLevel;
 ///   };
-Type *WinEHStatePass::getSEH4RegistrationType() {
-  if (SEH4RegistrationTy)
-    return SEH4RegistrationTy;
+Type *WinEHStatePass::getSEHRegistrationType() {
+  if (SEHRegistrationTy)
+    return SEHRegistrationTy;
   LLVMContext &Context = TheModule->getContext();
   Type *FieldTys[] = {
       Type::getInt8PtrTy(Context), // void *SavedESP
       Type::getInt8PtrTy(Context), // void *ExceptionPointers
-      getEHRegistrationType(),     // EHRegistrationNode SubRecord
+      getEHLinkRegistrationType(), // EHRegistrationNode SubRecord
       Type::getInt32Ty(Context),   // int32_t EncodedScopeTable
       Type::getInt32Ty(Context)    // int32_t TryLevel
   };
-  SEH4RegistrationTy = StructType::create(FieldTys, "EH4ExceptionRegistration");
-  return SEH4RegistrationTy;
+  SEHRegistrationTy = StructType::create(FieldTys, "SEHExceptionRegistration");
+  return SEHRegistrationTy;
 }
 
 // Emit an exception registration record. These are stack allocations with the
@@ -268,8 +246,8 @@ void WinEHStatePass::emitExceptionRegist
   StringRef PersonalityName = PersonalityFn->getName();
   IRBuilder<> Builder(&F->getEntryBlock(), F->getEntryBlock().begin());
   Type *Int8PtrType = Builder.getInt8PtrTy();
-  if (PersonalityName == "__CxxFrameHandler3") {
-    RegNodeTy = getCXXEH3RegistrationType();
+  if (Personality == EHPersonality::MSVC_CXX) {
+    RegNodeTy = getCXXEHRegistrationType();
     RegNode = Builder.CreateAlloca(RegNodeTy);
     // FIXME: We can skip this in -GS- mode, when we figure that out.
     // SavedESP = llvm.stacksave()
@@ -283,33 +261,35 @@ void WinEHStatePass::emitExceptionRegist
     Function *Trampoline = generateLSDAInEAXThunk(F);
     Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 1);
     linkExceptionRegistration(Builder, Trampoline);
-  } else if (PersonalityName == "_except_handler3") {
-    RegNodeTy = getSEH3RegistrationType();
-    RegNode = Builder.CreateAlloca(RegNodeTy);
-    // TryLevel = -1
-    StateFieldIndex = 2;
-    insertStateNumberStore(RegNode, Builder.GetInsertPoint(), -1);
-    // ScopeTable = llvm.x86.seh.lsda(F)
-    Value *LSDA = emitEHLSDA(Builder, F);
-    Builder.CreateStore(LSDA, Builder.CreateStructGEP(RegNodeTy, RegNode, 1));
-    Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 0);
-    linkExceptionRegistration(Builder, PersonalityFn);
-  } else if (PersonalityName == "_except_handler4") {
-    RegNodeTy = getSEH4RegistrationType();
+  } else if (Personality == EHPersonality::MSVC_X86SEH) {
+    // If _except_handler4 is in use, some additional guard checks and prologue
+    // stuff is required.
+    bool UseStackGuard = (PersonalityName == "_except_handler4");
+    RegNodeTy = getSEHRegistrationType();
     RegNode = Builder.CreateAlloca(RegNodeTy);
     // SavedESP = llvm.stacksave()
     Value *SP = Builder.CreateCall(
         Intrinsic::getDeclaration(TheModule, Intrinsic::stacksave), {});
     Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
-    // TryLevel = -1
+    // TryLevel = -2 / -1
     StateFieldIndex = 4;
-    insertStateNumberStore(RegNode, Builder.GetInsertPoint(), -1);
-    // FIXME: XOR the LSDA with __security_cookie.
+    insertStateNumberStore(RegNode, Builder.GetInsertPoint(),
+                           UseStackGuard ? -2 : -1);
     // ScopeTable = llvm.x86.seh.lsda(F)
     Value *FI8 = Builder.CreateBitCast(F, Int8PtrType);
     Value *LSDA = Builder.CreateCall(
         Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_lsda), FI8);
-    Builder.CreateStore(LSDA, Builder.CreateStructGEP(RegNodeTy, RegNode, 1));
+    Type *Int32Ty = Type::getInt32Ty(TheModule->getContext());
+    LSDA = Builder.CreatePtrToInt(LSDA, Int32Ty);
+    // If using _except_handler4, xor the address of the table with
+    // __security_cookie.
+    if (UseStackGuard) {
+      Value *Cookie =
+          TheModule->getOrInsertGlobal("__security_cookie", Int32Ty);
+      Value *Val = Builder.CreateLoad(Int32Ty, Cookie);
+      LSDA = Builder.CreateXor(LSDA, Val);
+    }
+    Builder.CreateStore(LSDA, Builder.CreateStructGEP(RegNodeTy, RegNode, 3));
     Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 2);
     linkExceptionRegistration(Builder, PersonalityFn);
   } else {
@@ -372,7 +352,7 @@ Function *WinEHStatePass::generateLSDAIn
 
 void WinEHStatePass::linkExceptionRegistration(IRBuilder<> &Builder,
                                                Value *Handler) {
-  Type *LinkTy = getEHRegistrationType();
+  Type *LinkTy = getEHLinkRegistrationType();
   // Handler = Handler
   Handler = Builder.CreateBitCast(Handler, Builder.getInt8PtrTy());
   Builder.CreateStore(Handler, Builder.CreateStructGEP(LinkTy, Link, 1));
@@ -392,7 +372,7 @@ void WinEHStatePass::unlinkExceptionRegi
     Builder.Insert(GEP);
     Link = GEP;
   }
-  Type *LinkTy = getEHRegistrationType();
+  Type *LinkTy = getEHLinkRegistrationType();
   // [fs:00] = Link->Next
   Value *Next =
       Builder.CreateLoad(Builder.CreateStructGEP(LinkTy, Link, 0));

Modified: llvm/trunk/test/CodeGen/X86/win32-eh.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win32-eh.ll?rev=238627&r1=238626&r2=238627&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win32-eh.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win32-eh.ll Fri May 29 17:57:46 2015
@@ -24,10 +24,10 @@ catchall:
 ; CHECK: subl ${{[0-9]+}}, %esp
 ; CHECK: movl $-1, -4(%ebp)
 ; CHECK: movl $L__ehtable$use_except_handler3, -8(%ebp)
+; CHECK: leal -16(%ebp), %[[node:[^ ,]*]]
 ; CHECK: movl $__except_handler3, -12(%ebp)
 ; CHECK: movl %fs:0, %[[next:[^ ,]*]]
 ; CHECK: movl %[[next]], -16(%ebp)
-; CHECK: leal -16(%ebp), %[[node:[^ ,]*]]
 ; CHECK: movl %[[node]], %fs:0
 ; CHECK: calll _may_throw_or_crash
 ; CHECK: movl -16(%ebp), %[[next:[^ ,]*]]
@@ -50,8 +50,10 @@ catchall:
 ; CHECK: movl %esp, %ebp
 ; CHECK: subl ${{[0-9]+}}, %esp
 ; CHECK: movl %esp, -24(%ebp)
-; CHECK: movl $-1, -4(%ebp)
-; CHECK: movl $L__ehtable$use_except_handler4, -20(%ebp)
+; CHECK: movl $-2, -4(%ebp)
+; CHECK: movl $L__ehtable$use_except_handler4, %[[lsda:[^ ,]*]]
+; CHECK: xorl ___security_cookie, %[[lsda]]
+; CHECK: movl %[[lsda]], -8(%ebp)
 ; CHECK: leal -16(%ebp), %[[node:[^ ,]*]]
 ; CHECK: movl $__except_handler4, -12(%ebp)
 ; CHECK: movl %fs:0, %[[next:[^ ,]*]]





More information about the llvm-commits mailing list