diff options
author | Pascal Stumpf <pascal@cvs.openbsd.org> | 2016-09-03 22:47:03 +0000 |
---|---|---|
committer | Pascal Stumpf <pascal@cvs.openbsd.org> | 2016-09-03 22:47:03 +0000 |
commit | c07c59953ad4d4f16e8c3a3e25692ad9657db3ea (patch) | |
tree | e5a516d9d25bf178ab50dad2aa60c32b8684d5ee /gnu/llvm/lib/MC/MCWinEH.cpp | |
parent | 62bc401a55deb1281a3a42cd4f08325a6839a171 (diff) |
Use the space freed up by sparc and zaurus to import LLVM.
ok hackroom@
Diffstat (limited to 'gnu/llvm/lib/MC/MCWinEH.cpp')
-rw-r--r-- | gnu/llvm/lib/MC/MCWinEH.cpp | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/gnu/llvm/lib/MC/MCWinEH.cpp b/gnu/llvm/lib/MC/MCWinEH.cpp new file mode 100644 index 00000000000..83af203c7ac --- /dev/null +++ b/gnu/llvm/lib/MC/MCWinEH.cpp @@ -0,0 +1,79 @@ +//===- 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/MCStreamer.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCWinEH.h" +#include "llvm/Support/COFF.h" + +namespace llvm { +namespace WinEH { + +/// We can't have one section for all .pdata or .xdata because the Microsoft +/// linker seems to want all code relocations to refer to the same object file +/// section. If the code described is comdat, create a new comdat section +/// associated with that comdat. If the code described is not in the main .text +/// section, make a new section for it. Otherwise use the main unwind info +/// section. +static MCSection *getUnwindInfoSection(StringRef SecName, + MCSectionCOFF *UnwindSec, + const MCSymbol *Function, + MCContext &Context) { + if (Function && Function->isInSection()) { + // If Function is in a COMDAT, get or create an unwind info section in that + // COMDAT group. + const MCSectionCOFF *FunctionSection = + cast<MCSectionCOFF>(&Function->getSection()); + if (FunctionSection->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) { + return Context.getAssociativeCOFFSection( + UnwindSec, FunctionSection->getCOMDATSymbol()); + } + + // If Function is in a section other than .text, create a new .pdata section. + // Otherwise use the plain .pdata section. + if (const auto *Section = dyn_cast<MCSectionCOFF>(FunctionSection)) { + StringRef CodeSecName = Section->getSectionName(); + if (CodeSecName == ".text") + return UnwindSec; + + if (CodeSecName.startswith(".text$")) + CodeSecName = CodeSecName.substr(6); + + return Context.getCOFFSection((SecName + Twine('$') + CodeSecName).str(), + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getData()); + } + } + + return UnwindSec; + +} + +MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function, + MCContext &Context) { + MCSectionCOFF *PData = + cast<MCSectionCOFF>(Context.getObjectFileInfo()->getPDataSection()); + return getUnwindInfoSection(".pdata", PData, Function, Context); +} + +MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function, + MCContext &Context) { + MCSectionCOFF *XData = + cast<MCSectionCOFF>(Context.getObjectFileInfo()->getXDataSection()); + return getUnwindInfoSection(".xdata", XData, Function, Context); +} + +} +} + |