diff options
author | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-08-07 02:59:41 +0000 |
---|---|---|
committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-08-07 02:59:41 +0000 |
commit | 64a8cc7d0d63f5479b48c1e3e1adf85b1d0208c5 (patch) | |
tree | 50b9eb2943b33f2cf5629df92f18e36224c1e602 /llvm/lib/MC/MCWinEH.cpp | |
parent | bd3305b60f1b25727618b2f01e5c0a639e569eeb (diff) | |
download | bcm5719-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.cpp | 64 |
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 ""; +} +} +} + |