[llvm] r295464 - MC/COFF: Do not emit forward associative section referenceds.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 17 09:32:55 PST 2017


Author: ruiu
Date: Fri Feb 17 11:32:54 2017
New Revision: 295464

URL: http://llvm.org/viewvc/llvm-project?rev=295464&view=rev
Log:
MC/COFF: Do not emit forward associative section referenceds.

MSVC link.exe cannot handle associative sections that refer later
sections in the section header. Technically, such COFF object doesn't
violate the Microsoft COFF spec, as the spec doesn't say anything
about that, but still we should avoid doing that to make it compatible
with MS tools.

This patch assigns smaller section numbers to non-associative sections
and larger numbers to associative sections. This should resolve the
compatibility issue.

Differential Revision: https://reviews.llvm.org/D30080

Modified:
    llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
    llvm/trunk/test/DebugInfo/COFF/globals.ll
    llvm/trunk/test/DebugInfo/COFF/types-data-members.ll
    llvm/trunk/test/MC/COFF/section-comdat.s

Modified: llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp?rev=295464&r1=295463&r2=295464&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp Fri Feb 17 11:32:54 2017
@@ -177,7 +177,7 @@ public:
   void WriteFileHeader(const COFF::header &Header);
   void WriteSymbol(const COFFSymbol &S);
   void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S);
-  void writeSectionHeader(const COFF::section &S);
+  void writeSectionHeaders();
   void WriteRelocation(const COFF::relocation &R);
   uint32_t writeSectionContents(MCAssembler &Asm, const MCAsmLayout &Layout,
                                 const MCSection &MCSec);
@@ -560,18 +560,37 @@ void WinCOFFObjectWriter::WriteAuxiliary
   }
 }
 
-void WinCOFFObjectWriter::writeSectionHeader(const COFF::section &S) {
-  writeBytes(StringRef(S.Name, COFF::NameSize));
+// Write the section header.
+void WinCOFFObjectWriter::writeSectionHeaders() {
+  // Section numbers must be monotonically increasing in the section
+  // header, but our Sections array is not sorted by section number,
+  // so make a copy of Sections and sort it.
+  std::vector<COFFSection *> Arr;
+  for (auto &Section : Sections)
+    Arr.push_back(Section.get());
+  std::sort(Arr.begin(), Arr.end(),
+            [](const COFFSection *A, const COFFSection *B) {
+              return A->Number < B->Number;
+            });
 
-  writeLE32(S.VirtualSize);
-  writeLE32(S.VirtualAddress);
-  writeLE32(S.SizeOfRawData);
-  writeLE32(S.PointerToRawData);
-  writeLE32(S.PointerToRelocations);
-  writeLE32(S.PointerToLineNumbers);
-  writeLE16(S.NumberOfRelocations);
-  writeLE16(S.NumberOfLineNumbers);
-  writeLE32(S.Characteristics);
+  for (auto &Section : Arr) {
+    if (Section->Number == -1)
+      continue;
+
+    COFF::section &S = Section->Header;
+    if (Section->Relocations.size() >= 0xffff)
+      S.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL;
+    writeBytes(StringRef(S.Name, COFF::NameSize));
+    writeLE32(S.VirtualSize);
+    writeLE32(S.VirtualAddress);
+    writeLE32(S.SizeOfRawData);
+    writeLE32(S.PointerToRawData);
+    writeLE32(S.PointerToRelocations);
+    writeLE32(S.PointerToLineNumbers);
+    writeLE16(S.NumberOfRelocations);
+    writeLE16(S.NumberOfLineNumbers);
+    writeLE32(S.Characteristics);
+  }
 }
 
 void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) {
@@ -895,14 +914,29 @@ void WinCOFFObjectWriter::createFileSymb
   }
 }
 
+static bool isAssociative(const COFFSection &Section) {
+  return Section.Symbol->Aux[0].Aux.SectionDefinition.Selection ==
+         COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE;
+}
+
 void WinCOFFObjectWriter::assignSectionNumbers() {
   size_t I = 1;
-  for (const auto &Section : Sections) {
-    Section->Number = I;
-    Section->Symbol->Data.SectionNumber = I;
-    Section->Symbol->Aux[0].Aux.SectionDefinition.Number = I;
+  auto Assign = [&](COFFSection &Section) {
+    Section.Number = I;
+    Section.Symbol->Data.SectionNumber = I;
+    Section.Symbol->Aux[0].Aux.SectionDefinition.Number = I;
     ++I;
-  }
+  };
+
+  // Although it is not explicitly requested by the Microsoft COFF spec,
+  // we should avoid emitting forward associative section references,
+  // because MSVC link.exe as of 2017 cannot handle that.
+  for (const std::unique_ptr<COFFSection> &Section : Sections)
+    if (!isAssociative(*Section))
+      Assign(*Section);
+  for (const std::unique_ptr<COFFSection> &Section : Sections)
+    if (isAssociative(*Section))
+      Assign(*Section);
 }
 
 // Assign file offsets to COFF object file structures.
@@ -1056,14 +1090,7 @@ void WinCOFFObjectWriter::writeObject(MC
 
   // Write it all to disk...
   WriteFileHeader(Header);
-
-  for (auto &Section : Sections) {
-    if (Section->Number != -1) {
-      if (Section->Relocations.size() >= 0xffff)
-        Section->Header.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL;
-      writeSectionHeader(Section->Header);
-    }
-  }
+  writeSectionHeaders();
 
   // Write section contents.
   sections::iterator I = Sections.begin();

Modified: llvm/trunk/test/DebugInfo/COFF/globals.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/globals.ll?rev=295464&r1=295463&r2=295464&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/globals.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/globals.ll Fri Feb 17 11:32:54 2017
@@ -96,7 +96,7 @@
 ; OBJ:   ]
 ; OBJ: ]
 ; OBJ: CodeViewDebugInfo [
-; OBJ:   Section: .debug$S (7)
+; OBJ:   Section: .debug$S (8)
 ; OBJ:   Magic: 0x4
 ; OBJ:   Subsection [
 ; OBJ:     SubSectionType: Symbols (0xF1)

Modified: llvm/trunk/test/DebugInfo/COFF/types-data-members.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/types-data-members.ll?rev=295464&r1=295463&r2=295464&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/types-data-members.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/types-data-members.ll Fri Feb 17 11:32:54 2017
@@ -37,7 +37,7 @@
 ; $ clang t.cpp -S -emit-llvm -g -gcodeview -o t.ll
 
 ; CHECK: CodeViewTypes [
-; CHECK:   Section: .debug$T (10)
+; CHECK:   Section: .debug$T (8)
 ; CHECK:   Magic: 0x4
 ; CHECK:   ArgList (0x1000) {
 ; CHECK:     TypeLeafKind: LF_ARGLIST (0x1201)

Modified: llvm/trunk/test/MC/COFF/section-comdat.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/section-comdat.s?rev=295464&r1=295463&r2=295464&view=diff
==============================================================================
--- llvm/trunk/test/MC/COFF/section-comdat.s (original)
+++ llvm/trunk/test/MC/COFF/section-comdat.s Fri Feb 17 11:32:54 2017
@@ -161,7 +161,7 @@ Symbol8:
 // CHECK:   }
 // CHECK:   Symbol {
 // CHECK:     Name: SecName
-// CHECK:     Section: SecName (9)
+// CHECK:     Section: SecName (11)
 // CHECK:     AuxSectionDef {
 // CHECK:       Selection: Associative
 // CHECK:       AssocSection: assocSec (4)
@@ -169,25 +169,25 @@ Symbol8:
 // CHECK:   }
 // CHECK:   Symbol {
 // CHECK:     Name: SecName
-// CHECK:     Section: SecName (10)
+// CHECK:     Section: SecName (9)
 // CHECK:     AuxSectionDef {
 // CHECK:       Selection: Largest
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
 // CHECK:     Name: Symbol6
-// CHECK:     Section: SecName (10)
+// CHECK:     Section: SecName (9)
 // CHECK:   }
 // CHECK:   Symbol {
 // CHECK:     Name: SecName
-// CHECK:     Section: SecName (11)
+// CHECK:     Section: SecName (10)
 // CHECK:     AuxSectionDef {
 // CHECK:       Selection: Newest (0x7)
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
 // CHECK:     Name: Symbol7
-// CHECK:     Section: SecName (11)
+// CHECK:     Section: SecName (10)
 // CHECK:   }
 // CHECK:   Symbol {
 // CHECK:     Name: assocSec
@@ -199,7 +199,7 @@ Symbol8:
 // CHECK:   }
 // CHECK:   Symbol {
 // CHECK:     Name: Symbol5
-// CHECK:     Section: SecName (9)
+// CHECK:     Section: SecName (11)
 // CHECK:   }
 // CHECK:   Symbol {
 // CHECK:     Name: Symbol8




More information about the llvm-commits mailing list