[llvm] r215050 - MC: split Win64EHUnwindEmitter into a shared streamer

Saleem Abdulrasool compnerd at compnerd.org
Wed Aug 6 19:59:41 PDT 2014


Author: compnerd
Date: Wed Aug  6 21:59:41 2014
New Revision: 215050

URL: http://llvm.org/viewvc/llvm-project?rev=215050&view=rev
Log:
MC: split Win64EHUnwindEmitter into a shared streamer

This changes Win64EHEmitter into a utility WinEH UnwindEmitter that can be
shared across multiple architectures and a target specific bit which is
overridden (Win64::UnwindEmitter).  This enables sharing the section selection
code across X86 and the intended use in ARM for emitting unwind information for
Windows on ARM.

Added:
    llvm/trunk/lib/MC/MCWinEH.cpp
Modified:
    llvm/trunk/include/llvm/MC/MCWin64EH.h
    llvm/trunk/include/llvm/MC/MCWinEH.h
    llvm/trunk/lib/MC/CMakeLists.txt
    llvm/trunk/lib/MC/MCAsmStreamer.cpp
    llvm/trunk/lib/MC/MCWin64EH.cpp
    llvm/trunk/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp

Modified: llvm/trunk/include/llvm/MC/MCWin64EH.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCWin64EH.h?rev=215050&r1=215049&r2=215050&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCWin64EH.h (original)
+++ llvm/trunk/include/llvm/MC/MCWin64EH.h Wed Aug  6 21:59:41 2014
@@ -20,9 +20,8 @@
 #include <vector>
 
 namespace llvm {
-  class StringRef;
-  class MCStreamer;
-  class MCSymbol;
+class MCStreamer;
+class MCSymbol;
 
 namespace Win64EH {
 struct Instruction {
@@ -52,17 +51,13 @@ struct Instruction {
     return WinEH::Instruction(UOP_SetFPReg, L, Reg, Off);
   }
 };
-}
 
-  class MCWin64EHUnwindEmitter {
-  public:
-    static StringRef GetSectionSuffix(const MCSymbol *func);
-    //
-    // This emits the unwind info sections (.pdata and .xdata in PE/COFF).
-    //
-    static void Emit(MCStreamer &streamer);
-    static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info);
-  };
+class UnwindEmitter : public WinEH::UnwindEmitter {
+public:
+  void Emit(MCStreamer &Streamer) const override;
+  void EmitUnwindInfo(MCStreamer &Streamer, WinEH::FrameInfo *FI) const override;
+};
+}
 } // end namespace llvm
 
 #endif

Modified: llvm/trunk/include/llvm/MC/MCWinEH.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCWinEH.h?rev=215050&r1=215049&r2=215050&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCWinEH.h (original)
+++ llvm/trunk/include/llvm/MC/MCWinEH.h Wed Aug  6 21:59:41 2014
@@ -13,7 +13,11 @@
 #include <vector>
 
 namespace llvm {
+class MCContext;
+class MCSection;
+class MCStreamer;
 class MCSymbol;
+class StringRef;
 
 namespace WinEH {
 struct Instruction {
@@ -58,6 +62,21 @@ struct FrameInfo {
       HandlesUnwind(false), HandlesExceptions(false), LastFrameInst(-1),
       ChainedParent(ChainedParent), Instructions() {}
 };
+
+class UnwindEmitter {
+public:
+  static StringRef GetSectionSuffix(const MCSymbol *Function);
+  static const MCSection *GetPDataSection(StringRef Suffix, MCContext &Context);
+  static const MCSection *GetXDataSection(StringRef Suffix, MCContext &Context);
+
+  virtual ~UnwindEmitter() { }
+
+  //
+  // This emits the unwind info sections (.pdata and .xdata in PE/COFF).
+  //
+  virtual void Emit(MCStreamer &Streamer) const = 0;
+  virtual void EmitUnwindInfo(MCStreamer &Streamer, FrameInfo *FI) const = 0;
+};
 }
 }
 

Modified: llvm/trunk/lib/MC/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/CMakeLists.txt?rev=215050&r1=215049&r2=215050&view=diff
==============================================================================
--- llvm/trunk/lib/MC/CMakeLists.txt (original)
+++ llvm/trunk/lib/MC/CMakeLists.txt Wed Aug  6 21:59:41 2014
@@ -39,6 +39,7 @@ add_llvm_library(LLVMMC
   MCTargetOptions.cpp
   MCValue.cpp
   MCWin64EH.cpp
+  MCWinEH.cpp
   MachObjectWriter.cpp
   StringTableBuilder.cpp
   SubtargetFeature.cpp

Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=215050&r1=215049&r2=215050&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Wed Aug  6 21:59:41 2014
@@ -1110,10 +1110,9 @@ void MCAsmStreamer::EmitWinEHHandlerData
   // We only do this so the section switch that terminates the handler
   // data block is visible.
   WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
-  StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
-  const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
-  if (xdataSect)
-    SwitchSectionNoChange(xdataSect);
+  StringRef Suffix = WinEH::UnwindEmitter::GetSectionSuffix(CurFrame->Function);
+  if (const MCSection *XData = getWin64EHTableSection(Suffix, getContext()))
+    SwitchSectionNoChange(XData);
 
   OS << "\t.seh_handlerdata";
   EmitEOL();

Modified: llvm/trunk/lib/MC/MCWin64EH.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCWin64EH.cpp?rev=215050&r1=215049&r2=215050&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCWin64EH.cpp (original)
+++ llvm/trunk/lib/MC/MCWin64EH.cpp Wed Aug  6 21:59:41 2014
@@ -218,65 +218,14 @@ static void EmitUnwindInfo(MCStreamer &s
   }
 }
 
-StringRef MCWin64EHUnwindEmitter::GetSectionSuffix(const MCSymbol *func) {
-  if (!func || !func->isInSection()) return "";
-  const MCSection *section = &func->getSection();
-  const MCSectionCOFF *COFFSection;
-  if ((COFFSection = dyn_cast<MCSectionCOFF>(section))) {
-    StringRef name = COFFSection->getSectionName();
-    size_t dollar = name.find('$');
-    size_t dot = name.find('.', 1);
-    if (dollar == StringRef::npos && dot == StringRef::npos)
-      return "";
-    if (dot == StringRef::npos)
-      return name.substr(dollar);
-    if (dollar == StringRef::npos || dot < dollar)
-      return name.substr(dot);
-    return name.substr(dollar);
-  }
-  return "";
-}
-
-static const MCSection *getWin64EHTableSection(StringRef suffix,
-                                               MCContext &context) {
-  if (suffix == "")
-    return context.getObjectFileInfo()->getXDataSection();
-
-  return context.getCOFFSection((".xdata"+suffix).str(),
-                                COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
-                                COFF::IMAGE_SCN_MEM_READ,
-                                SectionKind::getDataRel());
-}
-
-static const MCSection *getWin64EHFuncTableSection(StringRef suffix,
-                                                   MCContext &context) {
-  if (suffix == "")
-    return context.getObjectFileInfo()->getPDataSection();
-  return context.getCOFFSection((".pdata"+suffix).str(),
-                                COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
-                                COFF::IMAGE_SCN_MEM_READ,
-                                SectionKind::getDataRel());
-}
-
-void MCWin64EHUnwindEmitter::EmitUnwindInfo(MCStreamer &streamer,
-                                            WinEH::FrameInfo *info) {
-  // Switch sections (the static function above is meant to be called from
-  // here and from Emit().
-  MCContext &context = streamer.getContext();
-  const MCSection *xdataSect =
-    getWin64EHTableSection(GetSectionSuffix(info->Function), context);
-  streamer.SwitchSection(xdataSect);
-
-  llvm::EmitUnwindInfo(streamer, info);
-}
-
-void MCWin64EHUnwindEmitter::Emit(MCStreamer &Streamer) {
+namespace Win64EH {
+void UnwindEmitter::Emit(MCStreamer &Streamer) const {
   MCContext &Context = Streamer.getContext();
 
   // Emit the unwind info structs first.
   for (const auto &CFI : Streamer.getWinFrameInfos()) {
     const MCSection *XData =
-        getWin64EHTableSection(GetSectionSuffix(CFI->Function), Context);
+        GetXDataSection(GetSectionSuffix(CFI->Function), Context);
     Streamer.SwitchSection(XData);
     EmitUnwindInfo(Streamer, CFI);
   }
@@ -284,11 +233,23 @@ void MCWin64EHUnwindEmitter::Emit(MCStre
   // Now emit RUNTIME_FUNCTION entries.
   for (const auto &CFI : Streamer.getWinFrameInfos()) {
     const MCSection *PData =
-        getWin64EHFuncTableSection(GetSectionSuffix(CFI->Function), Context);
+        GetPDataSection(GetSectionSuffix(CFI->Function), Context);
     Streamer.SwitchSection(PData);
     EmitRuntimeFunction(Streamer, CFI);
   }
 }
 
+void UnwindEmitter::EmitUnwindInfo(MCStreamer &Streamer,
+                                   WinEH::FrameInfo *info) const {
+  // Switch sections (the static function above is meant to be called from
+  // here and from Emit().
+  MCContext &context = Streamer.getContext();
+  const MCSection *xdataSect =
+    GetXDataSection(GetSectionSuffix(info->Function), context);
+  Streamer.SwitchSection(xdataSect);
+
+  llvm::EmitUnwindInfo(Streamer, info);
+}
+}
 } // End of namespace llvm
 

Added: llvm/trunk/lib/MC/MCWinEH.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCWinEH.cpp?rev=215050&view=auto
==============================================================================
--- llvm/trunk/lib/MC/MCWinEH.cpp (added)
+++ llvm/trunk/lib/MC/MCWinEH.cpp Wed Aug  6 21:59:41 2014
@@ -0,0 +1,64 @@
+//===- lib/MC/MCWinEH.cpp - Windows EH implementation ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCSectionCOFF.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCWinEH.h"
+#include "llvm/Support/COFF.h"
+
+namespace llvm {
+namespace WinEH {
+const MCSection *UnwindEmitter::GetPDataSection(StringRef Suffix,
+                                                MCContext &Context) {
+  if (Suffix.empty())
+    return Context.getObjectFileInfo()->getPDataSection();
+  return Context.getCOFFSection((".pdata" + Suffix).str(),
+                                COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+                                COFF::IMAGE_SCN_MEM_READ,
+                                SectionKind::getDataRel());
+}
+
+const MCSection *UnwindEmitter::GetXDataSection(StringRef Suffix,
+                                                MCContext &Context) {
+  if (Suffix.empty())
+    return Context.getObjectFileInfo()->getXDataSection();
+  return Context.getCOFFSection((".xdata" + Suffix).str(),
+                                COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+                                COFF::IMAGE_SCN_MEM_READ,
+                                SectionKind::getDataRel());
+}
+
+StringRef UnwindEmitter::GetSectionSuffix(const MCSymbol *Function) {
+  if (!Function || !Function->isInSection())
+    return "";
+
+  const MCSection *FunctionSection = &Function->getSection();
+  if (const auto Section = dyn_cast<MCSectionCOFF>(FunctionSection)) {
+    StringRef Name = Section->getSectionName();
+    size_t Dollar = Name.find('$');
+    size_t Dot = Name.find('.', 1);
+
+    if (Dollar == StringRef::npos && Dot == StringRef::npos)
+      return "";
+    if (Dot == StringRef::npos)
+      return Name.substr(Dollar);
+    if (Dollar == StringRef::npos || Dot < Dollar)
+      return Name.substr(Dot);
+
+    return Name.substr(Dollar);
+  }
+
+  return "";
+}
+}
+}
+

Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp?rev=215050&r1=215049&r2=215050&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp Wed Aug  6 21:59:41 2014
@@ -8,12 +8,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "X86MCTargetDesc.h"
+#include "llvm/MC/MCWin64EH.h"
 #include "llvm/MC/MCWinCOFFStreamer.h"
 
 using namespace llvm;
 
 namespace {
 class X86WinCOFFStreamer : public MCWinCOFFStreamer {
+  Win64EH::UnwindEmitter EHStreamer;
 public:
   X86WinCOFFStreamer(MCContext &C, MCAsmBackend &AB, MCCodeEmitter *CE,
                      raw_ostream &OS)
@@ -29,13 +31,13 @@ void X86WinCOFFStreamer::EmitWinEHHandle
 
   // We have to emit the unwind info now, because this directive
   // actually switches to the .xdata section!
-  MCWin64EHUnwindEmitter::EmitUnwindInfo(*this, getCurrentWinFrameInfo());
+  EHStreamer.EmitUnwindInfo(*this, getCurrentWinFrameInfo());
 }
 
 void X86WinCOFFStreamer::EmitWindowsUnwindTables() {
   if (!getNumWinFrameInfos())
     return;
-  MCWin64EHUnwindEmitter::Emit(*this);
+  EHStreamer.Emit(*this);
 }
 
 void X86WinCOFFStreamer::FinishImpl() {





More information about the llvm-commits mailing list