summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp23
-rw-r--r--llvm/lib/MC/MCAsmInfoCOFF.cpp11
-rw-r--r--llvm/lib/MC/MCStreamer.cpp21
3 files changed, 46 insertions, 9 deletions
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 03a1f6239f2..8518ee7def3 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -1060,7 +1060,7 @@ MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal(
Selection);
}
-static const char *getCOFFSectionNameForUniqueGlobal(SectionKind Kind) {
+static StringRef getCOFFSectionNameForUniqueGlobal(SectionKind Kind) {
if (Kind.isText())
return ".text";
if (Kind.isBSS())
@@ -1072,6 +1072,15 @@ static const char *getCOFFSectionNameForUniqueGlobal(SectionKind Kind) {
return ".data";
}
+void TargetLoweringObjectFileCOFF::appendComdatSymbolForMinGW(
+ SmallVectorImpl<char> &SecName, StringRef Symbol,
+ const DataLayout &DL) const {
+ if (getTargetTriple().isWindowsGNUEnvironment()) {
+ SecName.push_back('$');
+ getMangler().getNameWithPrefix(SecName, Symbol, DL);
+ }
+}
+
MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
// If we have -ffunction-sections then we should emit the global value to a
@@ -1083,7 +1092,8 @@ MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal(
EmitUniquedSection = TM.getDataSections();
if ((EmitUniquedSection && !Kind.isCommon()) || GO->hasComdat()) {
- const char *Name = getCOFFSectionNameForUniqueGlobal(Kind);
+ SmallString<256> Name = getCOFFSectionNameForUniqueGlobal(Kind);
+
unsigned Characteristics = getCOFFSectionFlags(Kind, TM);
Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
@@ -1103,6 +1113,8 @@ MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal(
if (!ComdatGV->hasPrivateLinkage()) {
MCSymbol *Sym = TM.getSymbol(ComdatGV);
StringRef COMDATSymName = Sym->getName();
+ appendComdatSymbolForMinGW(Name, COMDATSymName,
+ GO->getParent()->getDataLayout());
return getContext().getCOFFSection(Name, Characteristics, Kind,
COMDATSymName, Selection, UniqueID);
} else {
@@ -1160,13 +1172,14 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
StringRef COMDATSymName = Sym->getName();
SectionKind Kind = SectionKind::getReadOnly();
- const char *Name = getCOFFSectionNameForUniqueGlobal(Kind);
+ StringRef SecName = getCOFFSectionNameForUniqueGlobal(Kind);
unsigned Characteristics = getCOFFSectionFlags(Kind, TM);
Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
unsigned UniqueID = NextUniqueID++;
- return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName,
- COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
+ return getContext().getCOFFSection(
+ SecName, Characteristics, Kind, COMDATSymName,
+ COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
}
void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer,
diff --git a/llvm/lib/MC/MCAsmInfoCOFF.cpp b/llvm/lib/MC/MCAsmInfoCOFF.cpp
index 85104484fd4..8bb02c3f649 100644
--- a/llvm/lib/MC/MCAsmInfoCOFF.cpp
+++ b/llvm/lib/MC/MCAsmInfoCOFF.cpp
@@ -41,6 +41,10 @@ MCAsmInfoCOFF::MCAsmInfoCOFF() {
// At least MSVC inline-asm does AShr.
UseLogicalShr = false;
+
+ // If this is a COFF target, assume that it supports associative comdats. It's
+ // part of the spec.
+ HasCOFFAssociativeComdats = true;
}
void MCAsmInfoMicrosoft::anchor() {}
@@ -49,4 +53,9 @@ MCAsmInfoMicrosoft::MCAsmInfoMicrosoft() = default;
void MCAsmInfoGNUCOFF::anchor() {}
-MCAsmInfoGNUCOFF::MCAsmInfoGNUCOFF() = default;
+MCAsmInfoGNUCOFF::MCAsmInfoGNUCOFF() {
+ // If this is a GNU environment (mingw or cygwin), don't use associative
+ // comdats for jump tables, unwind information, and other data associated with
+ // a function.
+ HasCOFFAssociativeComdats = false;
+}
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 491fec3e9ab..953aa0528fb 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -673,16 +673,31 @@ static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
return MainCFISec;
const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
+ auto *MainCFISecCOFF = cast<MCSectionCOFF>(MainCFISec);
unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
// If this section is COMDAT, this unwind section should be COMDAT associative
// with its group.
const MCSymbol *KeySym = nullptr;
- if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)
+ if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
KeySym = TextSecCOFF->getCOMDATSymbol();
- return Context.getAssociativeCOFFSection(cast<MCSectionCOFF>(MainCFISec),
- KeySym, UniqueID);
+ // In a GNU environment, we can't use associative comdats. Instead, do what
+ // GCC does, which is to make plain comdat selectany section named like
+ // ".[px]data$_Z3foov".
+ if (!Context.getAsmInfo()->hasCOFFAssociativeComdats()) {
+ std::string SectionName =
+ (MainCFISecCOFF->getSectionName() + "$" +
+ TextSecCOFF->getSectionName().split('$').second)
+ .str();
+ return Context.getCOFFSection(
+ SectionName,
+ MainCFISecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT,
+ MainCFISecCOFF->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY);
+ }
+ }
+
+ return Context.getAssociativeCOFFSection(MainCFISecCOFF, KeySym, UniqueID);
}
MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
OpenPOWER on IntegriCloud