summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2014-08-07 02:59:41 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2014-08-07 02:59:41 +0000
commit64a8cc7d0d63f5479b48c1e3e1adf85b1d0208c5 (patch)
tree50b9eb2943b33f2cf5629df92f18e36224c1e602 /llvm/lib/MC
parentbd3305b60f1b25727618b2f01e5c0a639e569eeb (diff)
downloadbcm5719-llvm-64a8cc7d0d63f5479b48c1e3e1adf85b1d0208c5.tar.gz
bcm5719-llvm-64a8cc7d0d63f5479b48c1e3e1adf85b1d0208c5.zip
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. llvm-svn: 215050
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/CMakeLists.txt1
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp7
-rw-r--r--llvm/lib/MC/MCWin64EH.cpp71
-rw-r--r--llvm/lib/MC/MCWinEH.cpp64
4 files changed, 84 insertions, 59 deletions
diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt
index 9e78d45d776..855dcde6a97 100644
--- a/llvm/lib/MC/CMakeLists.txt
+++ b/llvm/lib/MC/CMakeLists.txt
@@ -39,6 +39,7 @@ add_llvm_library(LLVMMC
MCTargetOptions.cpp
MCValue.cpp
MCWin64EH.cpp
+ MCWinEH.cpp
MachObjectWriter.cpp
StringTableBuilder.cpp
SubtargetFeature.cpp
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 11d6de846fb..27cbd4962f1 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -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();
diff --git a/llvm/lib/MC/MCWin64EH.cpp b/llvm/lib/MC/MCWin64EH.cpp
index e59854c1c79..ecb9ae10691 100644
--- a/llvm/lib/MC/MCWin64EH.cpp
+++ b/llvm/lib/MC/MCWin64EH.cpp
@@ -218,65 +218,14 @@ static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) {
}
}
-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(MCStreamer &Streamer) {
// 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
diff --git a/llvm/lib/MC/MCWinEH.cpp b/llvm/lib/MC/MCWinEH.cpp
new file mode 100644
index 00000000000..8faf70737bf
--- /dev/null
+++ b/llvm/lib/MC/MCWinEH.cpp
@@ -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 "";
+}
+}
+}
+
OpenPOWER on IntegriCloud