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 | |
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')
-rw-r--r-- | llvm/lib/MC/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/MC/MCWin64EH.cpp | 71 | ||||
-rw-r--r-- | llvm/lib/MC/MCWinEH.cpp | 64 |
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 ""; +} +} +} + |