summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/MCWinEH.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2014-09-04 17:42:03 +0000
committerReid Kleckner <reid@kleckner.net>2014-09-04 17:42:03 +0000
commit7c4059eb8929eb2819ff81137033e190b1b550dd (patch)
treeba73a0bc6df98b5579e89a72bc14bac4f88e47c5 /llvm/lib/MC/MCWinEH.cpp
parent84897b8b7d01f5ccf7cb51e153f29c8bbb4f9191 (diff)
downloadbcm5719-llvm-7c4059eb8929eb2819ff81137033e190b1b550dd.tar.gz
bcm5719-llvm-7c4059eb8929eb2819ff81137033e190b1b550dd.zip
MC Win64: Put unwind info for COMDAT code into the same COMDAT group
Summary: This fixes a long standing issue where we would emit many little .text sections and only one .pdata and .xdata section. Now we generate one .pdata / .xdata pair per .text section and associate them correctly. Fixes PR19667. Reviewers: majnemer Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D5181 llvm-svn: 217176
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