1 //===- lib/MC/MCWinEH.cpp - Windows EH implementation ---------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/StringRef.h"
11 #include "llvm/MC/MCContext.h"
12 #include "llvm/MC/MCObjectFileInfo.h"
13 #include "llvm/MC/MCSectionCOFF.h"
14 #include "llvm/MC/MCSymbol.h"
15 #include "llvm/MC/MCWinEH.h"
16 #include "llvm/Support/COFF.h"
20 static StringRef getSectionSuffix(const MCSymbol *Function) {
21 if (!Function || !Function->isInSection())
24 const MCSection *FunctionSection = &Function->getSection();
25 if (const auto Section = dyn_cast<MCSectionCOFF>(FunctionSection)) {
26 StringRef Name = Section->getSectionName();
27 size_t Dollar = Name.find('$');
28 size_t Dot = Name.find('.', 1);
30 if (Dollar == StringRef::npos && Dot == StringRef::npos)
32 if (Dot == StringRef::npos)
33 return Name.substr(Dollar);
34 if (Dollar == StringRef::npos || Dot < Dollar)
35 return Name.substr(Dot);
37 return Name.substr(Dollar);
43 static const MCSection *getUnwindInfoSection(
44 StringRef SecName, const MCSectionCOFF *UnwindSec, const MCSymbol *Function,
46 // If Function is in a COMDAT, get or create an unwind info section in that
48 if (Function && Function->isInSection()) {
49 const MCSectionCOFF *FunctionSection =
50 cast<MCSectionCOFF>(&Function->getSection());
51 if (FunctionSection->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
52 return Context.getAssociativeCOFFSection(
53 UnwindSec, FunctionSection->getCOMDATSymbol());
57 // If Function is in a section other than .text, create a new .pdata section.
58 // Otherwise use the plain .pdata section.
59 StringRef Suffix = getSectionSuffix(Function);
62 return Context.getCOFFSection((SecName + Suffix).str(),
63 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
64 COFF::IMAGE_SCN_MEM_READ,
65 SectionKind::getDataRel());
68 const MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function,
70 const MCSectionCOFF *PData =
71 cast<MCSectionCOFF>(Context.getObjectFileInfo()->getPDataSection());
72 return getUnwindInfoSection(".pdata", PData, Function, Context);
75 const MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function,
77 const MCSectionCOFF *XData =
78 cast<MCSectionCOFF>(Context.getObjectFileInfo()->getXDataSection());
79 return getUnwindInfoSection(".xdata", XData, Function, Context);