diff options
| author | Reid Kleckner <reid@kleckner.net> | 2014-09-04 17:42:03 +0000 |
|---|---|---|
| committer | Reid Kleckner <reid@kleckner.net> | 2014-09-04 17:42:03 +0000 |
| commit | 7c4059eb8929eb2819ff81137033e190b1b550dd (patch) | |
| tree | ba73a0bc6df98b5579e89a72bc14bac4f88e47c5 /llvm/lib/MC/MCWinEH.cpp | |
| parent | 84897b8b7d01f5ccf7cb51e153f29c8bbb4f9191 (diff) | |
| download | bcm5719-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.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); +} + } } |

