summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/MCWinEH.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC/MCWinEH.cpp')
-rw-r--r--llvm/lib/MC/MCWinEH.cpp62
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);
+}
+
}
}
OpenPOWER on IntegriCloud