[PATCH][X86_64/MC] Emit personality function and Dwarf EH data for Win64 SEH

Kai Nacke kai.nacke at redstar.de
Sun Sep 15 11:27:01 PDT 2013


Hi!

Currently, the MC code emits a hard-coded name for the personality 
function. Obviously the function specified by the user should be emitted 
as language handler.
There is no special language data section for SEH. Instead the data is 
emitted after the unwind data and the reference to the handler function.
See also the specification for the struct UNWIND_INFO in the msdn:
http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx

This is the same as gcc 4.8.0 does. In case of SEH the handler function 
is called __gcc_personality_imp and the LSDA is stored in the handler data.

The attached patch changes the output to be conformant to the 
specification. As of now there is no code path which can trigger this 
code therefore no test case is included. My next patch enables proper EH 
handling on Win64 and will include test cases for this change, too.

Please review.

Regards
Kai
-------------- next part --------------
>From 80eb8a0f3c710a58b077249e2d1fddf363b65193 Mon Sep 17 00:00:00 2001
From: kai <kai at redstar.de>
Date: Wed, 29 May 2013 06:41:03 +0200
Subject: [PATCH 1/1] Emit personality function and Dwarf EH data for Win64
 SEH.

Obviously the personality function should be emitted as language handler
instead of the hard coded _GCC_specific_handler. The language specific
data must be placed after the unwind information therefore it must not
be emitted into a separate section.
---
 lib/CodeGen/AsmPrinter/Win64Exception.cpp | 12 +++---------
 lib/MC/MCObjectFileInfo.cpp               | 15 ++++++++++-----
 2 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/lib/CodeGen/AsmPrinter/Win64Exception.cpp b/lib/CodeGen/AsmPrinter/Win64Exception.cpp
index 1561012..99d53b9 100644
--- a/lib/CodeGen/AsmPrinter/Win64Exception.cpp
+++ b/lib/CodeGen/AsmPrinter/Win64Exception.cpp
@@ -78,9 +78,9 @@ void Win64Exception::BeginFunction(const MachineFunction *MF) {
   if (!shouldEmitPersonality)
     return;

-  MCSymbol *GCCHandlerSym =
-    Asm->GetExternalSymbolSymbol("_GCC_specific_handler");
-  Asm->OutStreamer.EmitWin64EHHandler(GCCHandlerSym, true, true);
+  const MCSymbol *PersHandlerSym = TLOF.getCFIPersonalitySymbol(Per, Asm->Mang,
+                                                                MMI);
+  Asm->OutStreamer.EmitWin64EHHandler(PersHandlerSym, true, true);

   Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
                                                 Asm->getFunctionNumber()));
@@ -99,14 +99,8 @@ void Win64Exception::EndFunction() {
   MMI->TidyLandingPads();

   if (shouldEmitPersonality) {
-    const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
-    const Function *Per = MMI->getPersonalities()[MMI->getPersonalityIndex()];
-    const MCSymbol *Sym = TLOF.getCFIPersonalitySymbol(Per, Asm->Mang, MMI);
-
     Asm->OutStreamer.PushSection();
     Asm->OutStreamer.EmitWin64EHHandlerData();
-    Asm->OutStreamer.EmitValue(MCSymbolRefExpr::Create(Sym, Asm->OutContext),
-                               4);
     EmitExceptionTable();
     Asm->OutStreamer.PopSection();
   }
diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp
index c620e8c..dd54fe5 100644
--- a/lib/MC/MCObjectFileInfo.cpp
+++ b/lib/MC/MCObjectFileInfo.cpp
@@ -568,11 +568,16 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
   // though it contains relocatable pointers.  In PIC mode, this is probably a
   // big runtime hit for C++ apps.  Either the contents of the LSDA need to be
   // adjusted or this should be a data section.
-  LSDASection =
-    Ctx->getCOFFSection(".gcc_except_table",
-                        COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
-                        COFF::IMAGE_SCN_MEM_READ,
-                        SectionKind::getReadOnly());
+  if (T.getOS() == Triple::Win32) {
+    // On Windows with SEH, the LSDA is emitted into the .xdata section
+    LSDASection = 0;
+  } else {
+    LSDASection =
+      Ctx->getCOFFSection(".gcc_except_table",
+                          COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+                          COFF::IMAGE_SCN_MEM_READ,
+                          SectionKind::getReadOnly());
+  }

   // Debug info.
   DwarfAbbrevSection =
--
1.8.0.msysgit.0



More information about the llvm-commits mailing list