summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/MC/WinCOFFObjectWriter.cpp79
-rw-r--r--llvm/test/DebugInfo/COFF/globals.ll2
-rw-r--r--llvm/test/DebugInfo/COFF/types-data-members.ll2
-rw-r--r--llvm/test/MC/COFF/section-comdat.s12
4 files changed, 61 insertions, 34 deletions
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index ce8b2005e86..e1fde90af7d 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -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::WriteAuxiliarySymbols(
}
}
-void WinCOFFObjectWriter::writeSectionHeader(const COFF::section &S) {
- 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);
+// 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;
+ });
+
+ 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::createFileSymbols(MCAssembler &Asm) {
}
}
+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(MCAssembler &Asm,
// 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();
diff --git a/llvm/test/DebugInfo/COFF/globals.ll b/llvm/test/DebugInfo/COFF/globals.ll
index e560e4f9806..aadf6ab557f 100644
--- a/llvm/test/DebugInfo/COFF/globals.ll
+++ b/llvm/test/DebugInfo/COFF/globals.ll
@@ -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)
diff --git a/llvm/test/DebugInfo/COFF/types-data-members.ll b/llvm/test/DebugInfo/COFF/types-data-members.ll
index 9276b962ac8..275af969a48 100644
--- a/llvm/test/DebugInfo/COFF/types-data-members.ll
+++ b/llvm/test/DebugInfo/COFF/types-data-members.ll
@@ -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)
diff --git a/llvm/test/MC/COFF/section-comdat.s b/llvm/test/MC/COFF/section-comdat.s
index e7052d8f5ae..7669ffbadc3 100644
--- a/llvm/test/MC/COFF/section-comdat.s
+++ b/llvm/test/MC/COFF/section-comdat.s
@@ -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
OpenPOWER on IntegriCloud