Correctly set the comdat symbol on COFF.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 5 Jun 2014 23:09:25 +0000 (23:09 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 5 Jun 2014 23:09:25 +0000 (23:09 +0000)
We extended the .section syntax to allow multiple sections with the
same name but different comdats, but currently we don't make sure that
the output section has that comdat symbol.

That happens to work with the code llc produces currently because it looks like

.section secName, "dr", one_only, "COMDATSym"
.globl COMDATSym
COMDATSym:
....

but that is not very friendly to anyone coding in assembly or even to
llc once we get comdat support in the IR.

This patch changes the coff object writer to make sure the comdat symbol is
output just after the section symbol, as required by the coff spec.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210298 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCSectionCOFF.h
lib/MC/WinCOFFObjectWriter.cpp
test/MC/COFF/section-comdat-conflict.s [new file with mode: 0644]
test/MC/COFF/section-comdat.s

index a428f9efb2b58d9ba00e7458b0167ac7aa184060..33ba45c278352ed1445f14cd2674c7a349717a15 100644 (file)
@@ -76,6 +76,7 @@ class MCSymbol;
       return SectionName.str() + "_end";
     }
     unsigned getCharacteristics() const { return Characteristics; }
+    const MCSymbol *getCOMDATSymbol() const { return COMDATSymbol; }
     int getSelection() const { return Selection; }
     const MCSectionCOFF *getAssocSection() const { return Assoc; }
 
index 961cbc6a8f7d67966dcec72febb00c389553555c..c3fc61b2904d11a85673f554038e17cadca366ab 100644 (file)
@@ -347,6 +347,11 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) {
 
   COFFSection *coff_section = createSection(Sec.getSectionName());
   COFFSymbol  *coff_symbol = createSymbol(Sec.getSectionName());
+  if (const MCSymbol *S = Sec.getCOMDATSymbol()) {
+    COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S);
+    assert(!COMDATSymbol->Section);
+    COMDATSymbol->Section = coff_section;
+  }
 
   coff_section->Symbol = coff_symbol;
   coff_symbol->Section = coff_section;
@@ -458,9 +463,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;
diff --git a/test/MC/COFF/section-comdat-conflict.s b/test/MC/COFF/section-comdat-conflict.s
new file mode 100644 (file)
index 0000000..7ed452a
--- /dev/null
@@ -0,0 +1,13 @@
+// RUN: not llvm-mc -triple i386-pc-win32 -filetype=obj < %s 2>&1 |  FileCheck %s
+
+// CHECK: conflicting sections for symbol
+
+        .section .xyz
+        .global bar
+bar:
+        .long 42
+
+        .section        .abcd,"xr",discard,bar
+        .global foo
+foo:
+        .long 42
index dd5be871b05014e5854b8f5312449d8affe457e2..e166a508bc1bdc14bf30645a55e8b1fd97a6af94 100644 (file)
@@ -40,6 +40,11 @@ Symbol6:
 Symbol7:
 .long 1
 
+.section SecName, "dr", newest, "Symbol8"
+.globl AnotherSymbol
+AnotherSymbol:
+.long 1
+
 // CHECK: Sections [
 // CHECK:   Section {
 // CHECK:     Number: 1
@@ -114,6 +119,10 @@ Symbol7:
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
+// CHECK:     Name: Symbol1
+// CHECK:     Section: secName (2)
+// CHECK:   }
+// CHECK:   Symbol {
 // CHECK:     Name: secName
 // CHECK:     Section: secName (3)
 // CHECK:     AuxSectionDef {
@@ -121,6 +130,10 @@ Symbol7:
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
+// CHECK:     Name: Symbol2
+// CHECK:     Section: secName (3)
+// CHECK:   }
+// CHECK:   Symbol {
 // CHECK:     Name: SecName
 // CHECK:     Section: SecName (4)
 // CHECK:     AuxSectionDef {
@@ -128,6 +141,10 @@ Symbol7:
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
+// CHECK:     Name: Symbol3
+// CHECK:     Section: SecName (4)
+// CHECK:   }
+// CHECK:   Symbol {
 // CHECK:     Name: SecName
 // CHECK:     Section: SecName (5)
 // CHECK:     AuxSymbolCount: 1
@@ -136,6 +153,10 @@ Symbol7:
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
+// CHECK:     Name: Symbol4
+// CHECK:     Section: SecName (5)
+// CHECK:   }
+// CHECK:   Symbol {
 // CHECK:     Name: SecName
 // CHECK:     Section: SecName (6)
 // CHECK:     AuxSectionDef {
@@ -144,6 +165,10 @@ Symbol7:
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
+// CHECK:     Name: Symbol5
+// CHECK:     Section: SecName (6)
+// CHECK:   }
+// CHECK:   Symbol {
 // CHECK:     Name: SecName
 // CHECK:     Section: SecName (7)
 // CHECK:     AuxSectionDef {
@@ -151,6 +176,10 @@ Symbol7:
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
+// CHECK:     Name: Symbol6
+// CHECK:     Section: SecName (7)
+// CHECK:   }
+// CHECK:   Symbol {
 // CHECK:     Name: SecName
 // CHECK:     Section: SecName (8)
 // CHECK:     AuxSectionDef {
@@ -158,31 +187,22 @@ Symbol7:
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
-// CHECK:     Name: Symbol1
-// CHECK:     Section: secName (2)
-// CHECK:   }
-// CHECK:   Symbol {
-// CHECK:     Name: Symbol2
-// CHECK:     Section: secName (3)
-// CHECK:   }
-// CHECK:   Symbol {
-// CHECK:     Name: Symbol3
-// CHECK:     Section: SecName (4)
-// CHECK:   }
-// CHECK:   Symbol {
-// CHECK:     Name: Symbol4
-// CHECK:     Section: SecName (5)
+// CHECK:     Name: Symbol7
+// CHECK:     Section: SecName (8)
 // CHECK:   }
 // CHECK:   Symbol {
-// CHECK:     Name: Symbol5
-// CHECK:     Section: SecName (6)
+// CHECK:     Name: SecName
+// CHECK:     Section: SecName (9)
+// CHECK:     AuxSectionDef {
+// CHECK:       Selection: Newest (0x7)
+// CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
-// CHECK:     Name: Symbol6
-// CHECK:     Section: SecName (7)
+// CHECK:     Name: Symbol8
+// CHECK:     Section: SecName (9)
 // CHECK:   }
 // CHECK:   Symbol {
-// CHECK:     Name: Symbol7
-// CHECK:     Section: SecName (8)
+// CHECK:     Name: AnotherSymbol
+// CHECK:     Section: SecName (9)
 // CHECK:   }
 // CHECK: ]