diff options
Diffstat (limited to 'llvm/lib/MC/MCWinEH.cpp')
-rw-r--r-- | llvm/lib/MC/MCWinEH.cpp | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/llvm/lib/MC/MCWinEH.cpp b/llvm/lib/MC/MCWinEH.cpp index 8faf70737bf..f0c354feb61 100644 --- a/llvm/lib/MC/MCWinEH.cpp +++ b/llvm/lib/MC/MCWinEH.cpp @@ -17,27 +17,7 @@ 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) { +static StringRef getSectionSuffix(const MCSymbol *Function) { if (!Function || !Function->isInSection()) return ""; @@ -59,6 +39,46 @@ StringRef UnwindEmitter::GetSectionSuffix(const MCSymbol *Function) { 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<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. + 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<MCSectionCOFF>(Context.getObjectFileInfo()->getPDataSection()); + return getUnwindInfoSection(".pdata", PData, Function, Context); +} + +const MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function, + MCContext &Context) { + const MCSectionCOFF *XData = + cast<MCSectionCOFF>(Context.getObjectFileInfo()->getXDataSection()); + return getUnwindInfoSection(".xdata", XData, Function, Context); +} + } } |