//===- 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 { static StringRef getSectionSuffix(const MCSymbol *Function) { if (!Function || !Function->isInSection()) return ""; const MCSection *FunctionSection = &Function->getSection(); if (const auto Section = dyn_cast(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 ""; } static const MCSection *getUnwindInfoSection( StringRef SecName, const MCSectionCOFF *UnwindSec, const MCSymbol *Function, MCContext &Context) { // If Function is in a COMDAT, get or create an unwind info section in that // COMDAT group. if (Function && Function->isInSection()) { const MCSectionCOFF *FunctionSection = cast(&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. StringRef Suffix = getSectionSuffix(Function); if (Suffix.empty()) return UnwindSec; return Context.getCOFFSection((SecName + Suffix).str(), COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, SectionKind::getDataRel()); } const MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function, MCContext &Context) { const MCSectionCOFF *PData = cast(Context.getObjectFileInfo()->getPDataSection()); return getUnwindInfoSection(".pdata", PData, Function, Context); } const MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function, MCContext &Context) { const MCSectionCOFF *XData = cast(Context.getObjectFileInfo()->getXDataSection()); return getUnwindInfoSection(".xdata", XData, Function, Context); } } }