summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/MCWinEH.cpp
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/MCWinEH.cpp
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/MCWinEH.cpp')
-rw-r--r--llvm/lib/MC/MCWinEH.cpp64
1 files changed, 64 insertions, 0 deletions
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