[llvm] r295273 - Split WinCOFFObjectWriter::writeObject function.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 15 18:35:48 PST 2017


Author: ruiu
Date: Wed Feb 15 20:35:48 2017
New Revision: 295273

URL: http://llvm.org/viewvc/llvm-project?rev=295273&view=rev
Log:
Split WinCOFFObjectWriter::writeObject function.

Modified:
    llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp

Modified: llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp?rev=295273&r1=295272&r2=295273&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp Wed Feb 15 20:35:48 2017
@@ -179,6 +179,8 @@ public:
   void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S);
   void writeSectionHeader(const COFF::section &S);
   void WriteRelocation(const COFF::relocation &R);
+  void writeSection(MCAssembler &Asm, const MCAsmLayout &Layout,
+                    const COFFSection &Sec, const MCSection &MCSec);
 
   // MCObjectWriter interface implementation.
 
@@ -197,6 +199,10 @@ public:
                         MCValue Target, bool &IsPCRel,
                         uint64_t &FixedValue) override;
 
+  void createFileSymbols(MCAssembler &Asm);
+  void assignSectionNumbers();
+  void assignFileOffsets(MCAssembler &Asm, const MCAsmLayout &Layout);
+
   void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
 };
 
@@ -572,6 +578,78 @@ void WinCOFFObjectWriter::WriteRelocatio
   writeLE16(R.Type);
 }
 
+void WinCOFFObjectWriter::writeSection(MCAssembler &Asm,
+                                       const MCAsmLayout &Layout,
+                                       const COFFSection &Sec,
+                                       const MCSection &MCSec) {
+  if (Sec.Number == -1)
+    return;
+
+  if (Sec.Header.PointerToRawData != 0) {
+    assert(getStream().tell() <= Sec.Header.PointerToRawData &&
+           "Section::PointerToRawData is insane!");
+
+    unsigned SectionDataPadding =
+        Sec.Header.PointerToRawData - getStream().tell();
+    assert(SectionDataPadding < 4 &&
+           "Should only need at most three bytes of padding!");
+
+    WriteZeros(SectionDataPadding);
+
+    // Save the contents of the section to a temporary buffer, we need this
+    // to CRC the data before we dump it into the object file.
+    SmallVector<char, 128> Buf;
+    raw_svector_ostream VecOS(Buf);
+    raw_pwrite_stream &OldStream = getStream();
+
+    // Redirect the output stream to our buffer.
+    setStream(VecOS);
+
+    // Fill our buffer with the section data.
+    Asm.writeSectionData(&MCSec, Layout);
+
+    // Reset the stream back to what it was before.
+    setStream(OldStream);
+
+    // Calculate our CRC with an initial value of '0', this is not how
+    // JamCRC is specified but it aligns with the expected output.
+    JamCRC JC(/*Init=*/0);
+    JC.update(Buf);
+
+    // Write the section contents to the object file.
+    getStream() << Buf;
+
+    // Update the section definition auxiliary symbol to record the CRC.
+    COFFSection *Sec = SectionMap[&MCSec];
+    COFFSymbol::AuxiliarySymbols &AuxSyms = Sec->Symbol->Aux;
+    assert(AuxSyms.size() == 1 && AuxSyms[0].AuxType == ATSectionDefinition);
+    AuxSymbol &SecDef = AuxSyms[0];
+    SecDef.Aux.SectionDefinition.CheckSum = JC.getCRC();
+  }
+
+  if (Sec.Relocations.empty()) {
+    assert(Sec.Header.PointerToRelocations == 0 &&
+           "Section::PointerToRelocations is insane!");
+    return;
+  }
+
+  assert(getStream().tell() == Sec.Header.PointerToRelocations &&
+         "Section::PointerToRelocations is insane!");
+
+  if (Sec.Relocations.size() >= 0xffff) {
+    // In case of overflow, write actual relocation count as first
+    // relocation. Including the synthetic reloc itself (+ 1).
+    COFF::relocation R;
+    R.VirtualAddress = Sec.Relocations.size() + 1;
+    R.SymbolTableIndex = 0;
+    R.Type = 0;
+    WriteRelocation(R);
+  }
+
+  for (const auto &Relocation : Sec.Relocations)
+    WriteRelocation(Relocation.Data);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // MCObjectWriter interface implementations
 
@@ -775,38 +853,21 @@ static std::time_t getTime() {
   return Now;
 }
 
-void WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
-                                      const MCAsmLayout &Layout) {
-  if (Sections.size() > INT32_MAX)
-    report_fatal_error(
-        "PE COFF object files can't have more than 2147483647 sections");
-
-  UseBigObj = Sections.size() > COFF::MaxNumberOfSections16;
-  Header.NumberOfSections = Sections.size();
-  Header.NumberOfSymbols = 0;
-
-  // Assign section numbers.
-  size_t Number = 1;
-  for (const auto &Section : Sections) {
-    Section->Number = Number;
-    Section->Symbol->Data.SectionNumber = Number;
-    Section->Symbol->Aux[0].Aux.SectionDefinition.Number = Number;
-    ++Number;
-  }
-
+// Create .file symbols.
+void WinCOFFObjectWriter::createFileSymbols(MCAssembler &Asm) {
   for (const std::string &Name : Asm.getFileNames()) {
     // round up to calculate the number of auxiliary symbols required
     unsigned SymbolSize = UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size;
     unsigned Count = (Name.size() + SymbolSize - 1) / SymbolSize;
 
-    COFFSymbol *file = createSymbol(".file");
-    file->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG;
-    file->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE;
-    file->Aux.resize(Count);
+    COFFSymbol *File = createSymbol(".file");
+    File->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG;
+    File->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE;
+    File->Aux.resize(Count);
 
     unsigned Offset = 0;
     unsigned Length = Name.size();
-    for (auto &Aux : file->Aux) {
+    for (auto &Aux : File->Aux) {
       Aux.AuxType = ATFile;
 
       if (Length > SymbolSize) {
@@ -821,6 +882,94 @@ void WinCOFFObjectWriter::writeObject(MC
       Offset += SymbolSize;
     }
   }
+}
+
+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;
+    ++I;
+  }
+}
+
+// Assign file offsets to COFF object file structures.
+void WinCOFFObjectWriter::assignFileOffsets(MCAssembler &Asm,
+                                            const MCAsmLayout &Layout) {
+  unsigned Offset = getInitialOffset();
+
+  Offset += UseBigObj ? COFF::Header32Size : COFF::Header16Size;
+  Offset += COFF::SectionSize * Header.NumberOfSections;
+
+  for (const auto &Section : Asm) {
+    COFFSection *Sec = SectionMap[&Section];
+
+    if (Sec->Number == -1)
+      continue;
+
+    Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section);
+
+    if (IsPhysicalSection(Sec)) {
+      // Align the section data to a four byte boundary.
+      Offset = alignTo(Offset, 4);
+      Sec->Header.PointerToRawData = Offset;
+
+      Offset += Sec->Header.SizeOfRawData;
+    }
+
+    if (!Sec->Relocations.empty()) {
+      bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff;
+
+      if (RelocationsOverflow) {
+        // Signal overflow by setting NumberOfRelocations to max value. Actual
+        // size is found in reloc #0. Microsoft tools understand this.
+        Sec->Header.NumberOfRelocations = 0xffff;
+      } else {
+        Sec->Header.NumberOfRelocations = Sec->Relocations.size();
+      }
+      Sec->Header.PointerToRelocations = Offset;
+
+      if (RelocationsOverflow) {
+        // Reloc #0 will contain actual count, so make room for it.
+        Offset += COFF::RelocationSize;
+      }
+
+      Offset += COFF::RelocationSize * Sec->Relocations.size();
+
+      for (auto &Relocation : Sec->Relocations) {
+        assert(Relocation.Symb->getIndex() != -1);
+        Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
+      }
+    }
+
+    assert(Sec->Symbol->Aux.size() == 1 &&
+           "Section's symbol must have one aux!");
+    AuxSymbol &Aux = Sec->Symbol->Aux[0];
+    assert(Aux.AuxType == ATSectionDefinition &&
+           "Section's symbol's aux symbol must be a Section Definition!");
+    Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData;
+    Aux.Aux.SectionDefinition.NumberOfRelocations =
+        Sec->Header.NumberOfRelocations;
+    Aux.Aux.SectionDefinition.NumberOfLinenumbers =
+        Sec->Header.NumberOfLineNumbers;
+  }
+
+  Header.PointerToSymbolTable = Offset;
+}
+
+void WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
+                                      const MCAsmLayout &Layout) {
+  if (Sections.size() > INT32_MAX)
+    report_fatal_error(
+        "PE COFF object files can't have more than 2147483647 sections");
+
+  UseBigObj = Sections.size() > COFF::MaxNumberOfSections16;
+  Header.NumberOfSections = Sections.size();
+  Header.NumberOfSymbols = 0;
+
+  assignSectionNumbers();
+  createFileSymbols(Asm);
 
   for (auto &Symbol : Symbols) {
     // Update section number & offset for symbols that have them.
@@ -883,70 +1032,7 @@ void WinCOFFObjectWriter::writeObject(MC
     Section->Symbol->Aux[0].Aux.SectionDefinition.Number = Assoc->Number;
   }
 
-  // Assign file offsets to COFF object file structures.
-
-  unsigned Offset = getInitialOffset();
-
-  if (UseBigObj)
-    Offset += COFF::Header32Size;
-  else
-    Offset += COFF::Header16Size;
-  Offset += COFF::SectionSize * Header.NumberOfSections;
-
-  for (const auto &Section : Asm) {
-    COFFSection *Sec = SectionMap[&Section];
-
-    if (Sec->Number == -1)
-      continue;
-
-    Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section);
-
-    if (IsPhysicalSection(Sec)) {
-      // Align the section data to a four byte boundary.
-      Offset = alignTo(Offset, 4);
-      Sec->Header.PointerToRawData = Offset;
-
-      Offset += Sec->Header.SizeOfRawData;
-    }
-
-    if (!Sec->Relocations.empty()) {
-      bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff;
-
-      if (RelocationsOverflow) {
-        // Signal overflow by setting NumberOfRelocations to max value. Actual
-        // size is found in reloc #0. Microsoft tools understand this.
-        Sec->Header.NumberOfRelocations = 0xffff;
-      } else {
-        Sec->Header.NumberOfRelocations = Sec->Relocations.size();
-      }
-      Sec->Header.PointerToRelocations = Offset;
-
-      if (RelocationsOverflow) {
-        // Reloc #0 will contain actual count, so make room for it.
-        Offset += COFF::RelocationSize;
-      }
-
-      Offset += COFF::RelocationSize * Sec->Relocations.size();
-
-      for (auto &Relocation : Sec->Relocations) {
-        assert(Relocation.Symb->getIndex() != -1);
-        Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
-      }
-    }
-
-    assert(Sec->Symbol->Aux.size() == 1 &&
-           "Section's symbol must have one aux!");
-    AuxSymbol &Aux = Sec->Symbol->Aux[0];
-    assert(Aux.AuxType == ATSectionDefinition &&
-           "Section's symbol's aux symbol must be a Section Definition!");
-    Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData;
-    Aux.Aux.SectionDefinition.NumberOfRelocations =
-        Sec->Header.NumberOfRelocations;
-    Aux.Aux.SectionDefinition.NumberOfLinenumbers =
-        Sec->Header.NumberOfLineNumbers;
-  }
-
-  Header.PointerToSymbolTable = Offset;
+  assignFileOffsets(Asm, Layout);
 
   // MS LINK expects to be able to use this timestamp to implement their
   // /INCREMENTAL feature.
@@ -968,86 +1054,23 @@ void WinCOFFObjectWriter::writeObject(MC
     }
   }
 
-  SmallVector<char, 128> Buf;
-
-  sections::iterator I, IE;
-  MCAssembler::iterator J, JE;
-  for (I = Sections.begin(), IE = Sections.end(), J = Asm.begin(),
-      JE = Asm.end();
-       I != IE && J != JE; ++I, ++J) {
-    COFFSection &Sec = *I->get();
-    MCSection &MCSec = *J;
-
-    if (Sec.Number == -1)
-      continue;
-
-    if (Sec.Header.PointerToRawData != 0) {
-      assert(getStream().tell() <= Sec.Header.PointerToRawData &&
-             "Section::PointerToRawData is insane!");
-
-      unsigned SectionDataPadding =
-          Sec.Header.PointerToRawData - getStream().tell();
-      assert(SectionDataPadding < 4 &&
-             "Should only need at most three bytes of padding!");
-
-      WriteZeros(SectionDataPadding);
-
-      // Save the contents of the section to a temporary buffer, we need this
-      // to CRC the data before we dump it into the object file.
-      Buf.clear();
-      raw_svector_ostream VecOS(Buf);
-      raw_pwrite_stream &OldStream = getStream();
-      // Redirect the output stream to our buffer.
-      setStream(VecOS);
-      // Fill our buffer with the section data.
-      Asm.writeSectionData(&MCSec, Layout);
-      // Reset the stream back to what it was before.
-      setStream(OldStream);
-
-      // Calculate our CRC with an initial value of '0', this is not how
-      // JamCRC is specified but it aligns with the expected output.
-      JamCRC JC(/*Init=*/0x00000000U);
-      JC.update(Buf);
-
-      // Write the section contents to the object file.
-      getStream() << Buf;
-
-      // Update the section definition auxiliary symbol to record the CRC.
-      COFFSection *Sec = SectionMap[&MCSec];
-      COFFSymbol::AuxiliarySymbols &AuxSyms = Sec->Symbol->Aux;
-      assert(AuxSyms.size() == 1 && AuxSyms[0].AuxType == ATSectionDefinition);
-      AuxSymbol &SecDef = AuxSyms[0];
-      SecDef.Aux.SectionDefinition.CheckSum = JC.getCRC();
-    }
-
-    if (!Sec.Relocations.empty()) {
-      assert(getStream().tell() == Sec.Header.PointerToRelocations &&
-             "Section::PointerToRelocations is insane!");
-
-      if (Sec.Relocations.size() >= 0xffff) {
-        // In case of overflow, write actual relocation count as first
-        // relocation. Including the synthetic reloc itself (+ 1).
-        COFF::relocation R;
-        R.VirtualAddress = Sec.Relocations.size() + 1;
-        R.SymbolTableIndex = 0;
-        R.Type = 0;
-        WriteRelocation(R);
-      }
-
-      for (const auto &Relocation : Sec.Relocations)
-        WriteRelocation(Relocation.Data);
-    } else
-      assert(Sec.Header.PointerToRelocations == 0 &&
-             "Section::PointerToRelocations is insane!");
-  }
+  // Write section contents.
+  sections::iterator I = Sections.begin();
+  sections::iterator IE = Sections.end();
+  MCAssembler::iterator J = Asm.begin();
+  MCAssembler::iterator JE = Asm.end();
+  for (; I != IE && J != JE; ++I, ++J)
+    writeSection(Asm, Layout, **I, *J);
 
   assert(getStream().tell() == Header.PointerToSymbolTable &&
          "Header::PointerToSymbolTable is insane!");
 
+  // Write a symbol table.
   for (auto &Symbol : Symbols)
     if (Symbol->getIndex() != -1)
       WriteSymbol(*Symbol);
 
+  // Write a string table, which completes the entire COFF file.
   Strings.write(getStream());
 }
 




More information about the llvm-commits mailing list