summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
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
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')
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp5
-rw-r--r--llvm/lib/MC/MCContext.cpp16
-rw-r--r--llvm/lib/MC/MCWin64EH.cpp6
-rw-r--r--llvm/lib/MC/MCWinEH.cpp62
4 files changed, 62 insertions, 27 deletions
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index fcf39b836fc..f60c7fc5041 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -1095,9 +1095,8 @@ void MCAsmStreamer::EmitWinEHHandlerData() {
// We only do this so the section switch that terminates the handler
// data block is visible.
WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
- StringRef Suffix = WinEH::UnwindEmitter::GetSectionSuffix(CurFrame->Function);
- if (const MCSection *XData =
- WinEH::UnwindEmitter::GetXDataSection(Suffix, getContext()))
+ if (const MCSection *XData = WinEH::UnwindEmitter::getXDataSection(
+ CurFrame->Function, getContext()))
SwitchSectionNoChange(XData);
OS << "\t.seh_handlerdata";
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 7702da3540c..4266759b1f0 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -317,6 +317,22 @@ const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
return Iter->second;
}
+const MCSectionCOFF *
+MCContext::getAssociativeCOFFSection(const MCSectionCOFF *Sec,
+ const MCSymbol *KeySym) {
+ // Return the normal section if we don't have to be associative.
+ if (!KeySym)
+ return Sec;
+
+ // Make an associative section with the same name and kind as the normal
+ // section.
+ unsigned Characteristics =
+ Sec->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT;
+ return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(),
+ KeySym->getName(),
+ COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);
+}
+
//===----------------------------------------------------------------------===//
// Dwarf Management
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/MC/MCWin64EH.cpp b/llvm/lib/MC/MCWin64EH.cpp
index 7394ba848bc..dfadb3cc42b 100644
--- a/llvm/lib/MC/MCWin64EH.cpp
+++ b/llvm/lib/MC/MCWin64EH.cpp
@@ -225,7 +225,7 @@ void UnwindEmitter::Emit(MCStreamer &Streamer) const {
// Emit the unwind info structs first.
for (const auto &CFI : Streamer.getWinFrameInfos()) {
const MCSection *XData =
- GetXDataSection(GetSectionSuffix(CFI->Function), Context);
+ getXDataSection(CFI->Function, Context);
Streamer.SwitchSection(XData);
EmitUnwindInfo(Streamer, CFI);
}
@@ -233,7 +233,7 @@ void UnwindEmitter::Emit(MCStreamer &Streamer) const {
// Now emit RUNTIME_FUNCTION entries.
for (const auto &CFI : Streamer.getWinFrameInfos()) {
const MCSection *PData =
- GetPDataSection(GetSectionSuffix(CFI->Function), Context);
+ getPDataSection(CFI->Function, Context);
Streamer.SwitchSection(PData);
EmitRuntimeFunction(Streamer, CFI);
}
@@ -245,7 +245,7 @@ void UnwindEmitter::EmitUnwindInfo(MCStreamer &Streamer,
// here and from Emit().
MCContext &context = Streamer.getContext();
const MCSection *xdataSect =
- GetXDataSection(GetSectionSuffix(info->Function), context);
+ getXDataSection(info->Function, context);
Streamer.SwitchSection(xdataSect);
llvm::EmitUnwindInfo(Streamer, info);
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