summaryrefslogtreecommitdiff
path: root/lib/MC/WinCOFFObjectWriter.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2014-06-06 19:26:12 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2014-06-06 19:26:12 +0000
commit013321a0f9e9f784ebb9a78ebf19e5f5099d5b16 (patch)
tree753bc6d742f12a5bb5f04d59afe902c14caba635 /lib/MC/WinCOFFObjectWriter.cpp
parent5448320a2061faeadedc800dff9a9adf14005a72 (diff)
downloadllvm-013321a0f9e9f784ebb9a78ebf19e5f5099d5b16.tar.gz
llvm-013321a0f9e9f784ebb9a78ebf19e5f5099d5b16.tar.bz2
llvm-013321a0f9e9f784ebb9a78ebf19e5f5099d5b16.tar.xz
Fix a few issues with comdat handling on COFF.
* Section association cannot use just the section name as many sections can have the same name. With this patch, the comdat symbol in an assoc section is interpreted to mean a symbol in the associated section and the mapping is discovered from it. * Comdat symbols were not being set correctly. Instead we were getting whatever was output first for that section. A consequence is that associative sections now must use .section to set the association. Using .linkonce would not work since it is not possible to change a sections comdat symbol (it is used to decide if we should create a new section or reuse an existing one). This includes r210298, which was reverted because it was asserting on an associated section having the same comdat as the associated section. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210367 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/WinCOFFObjectWriter.cpp')
-rw-r--r--lib/MC/WinCOFFObjectWriter.cpp30
1 files changed, 24 insertions, 6 deletions
diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp
index 961cbc6a8f..6f9c73b9cc 100644
--- a/lib/MC/WinCOFFObjectWriter.cpp
+++ b/lib/MC/WinCOFFObjectWriter.cpp
@@ -347,6 +347,14 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) {
COFFSection *coff_section = createSection(Sec.getSectionName());
COFFSymbol *coff_symbol = createSymbol(Sec.getSectionName());
+ if (Sec.getSelection() != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
+ if (const MCSymbol *S = Sec.getCOMDATSymbol()) {
+ COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S);
+ if (COMDATSymbol->Section)
+ report_fatal_error("two sections have the same comdat");
+ COMDATSymbol->Section = coff_section;
+ }
+ }
coff_section->Symbol = coff_symbol;
coff_symbol->Section = coff_section;
@@ -458,9 +466,15 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
} else {
const MCSymbolData &BaseData = Assembler.getSymbolData(*Base);
- if (BaseData.Fragment)
- coff_symbol->Section =
+ if (BaseData.Fragment) {
+ COFFSection *Sec =
SectionMap[&BaseData.Fragment->getParent()->getSection()];
+
+ if (coff_symbol->Section && coff_symbol->Section != Sec)
+ report_fatal_error("conflicting sections for symbol");
+
+ coff_symbol->Section = Sec;
+ }
}
coff_symbol->MCData = &ResSymData;
@@ -865,11 +879,15 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
const MCSectionCOFF &MCSec =
static_cast<const MCSectionCOFF &>(Section->MCData->getSection());
- COFFSection *Assoc = SectionMap.lookup(MCSec.getAssocSection());
+ const MCSymbol *COMDAT = MCSec.getCOMDATSymbol();
+ assert(COMDAT);
+ COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(COMDAT);
+ assert(COMDATSymbol);
+ COFFSection *Assoc = COMDATSymbol->Section;
if (!Assoc)
- report_fatal_error(Twine("Missing associated COMDAT section ") +
- MCSec.getAssocSection()->getSectionName() +
- " for section " + MCSec.getSectionName());
+ report_fatal_error(
+ Twine("Missing associated COMDAT section for section ") +
+ MCSec.getSectionName());
// Skip this section if the associated section is unused.
if (Assoc->Number == -1)