[lld] r186066 - [PECOFF][Writer] Fixed a bug that an empty section is emit to the section header.

Rui Ueyama ruiu at google.com
Wed Jul 10 22:43:38 PDT 2013


Author: ruiu
Date: Thu Jul 11 00:43:38 2013
New Revision: 186066

URL: http://llvm.org/viewvc/llvm-project?rev=186066&view=rev
Log:
[PECOFF][Writer] Fixed a bug that an empty section is emit to the section header.

Modified:
    lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
    lld/trunk/test/pecoff/trivial.test

Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=186066&r1=186065&r2=186066&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Thu Jul 11 00:43:38 2013
@@ -400,15 +400,11 @@ public:
   static bool classof(const Chunk *c) { return c->getKind() == kindSection; }
 
 protected:
-  SectionChunk(SectionHeaderTableChunk *table, StringRef sectionName,
-               uint32_t characteristics)
+  SectionChunk(StringRef sectionName, uint32_t characteristics)
       : AtomChunk(kindSection),
         _sectionHeader(createSectionHeader(sectionName, characteristics)) {
     // The section should be aligned to disk sector.
     _align = SECTOR_SIZE;
-
-    // Add this section to the file header.
-    table->addSection(this);
   }
 
   void buildContents(const File &linkedFile,
@@ -478,11 +474,6 @@ void SectionHeaderTableChunk::write(uint
   uint64_t offset = 0;
   fileBuffer += fileOffset();
   for (const auto &chunk : _sections) {
-    // Skip the empty section. Windows loader does not like a section
-    // of size zero and rejects such executable.
-    if (chunk->size() == 0)
-      continue;
-
     const llvm::object::coff_section &header = chunk->getSectionHeader();
     std::memcpy(fileBuffer + offset, &header, sizeof(header));
     offset += sizeof(header);
@@ -492,8 +483,8 @@ void SectionHeaderTableChunk::write(uint
 // \brief A TextSectionChunk represents a .text section.
 class TextSectionChunk : public SectionChunk {
 public:
-  TextSectionChunk(const File &linkedFile, SectionHeaderTableChunk *table)
-      : SectionChunk(table, ".text", characteristics) {
+  TextSectionChunk(const File &linkedFile)
+      : SectionChunk(".text", characteristics) {
     buildContents(linkedFile, [](const DefinedAtom *atom) {
       return atom->contentType() == DefinedAtom::typeCode;
     });
@@ -509,8 +500,8 @@ private:
 // \brief A RDataSectionChunk represents a .rdata section.
 class RDataSectionChunk : public SectionChunk {
 public:
-  RDataSectionChunk(const File &linkedFile, SectionHeaderTableChunk *table)
-      : SectionChunk(table, ".rdata", characteristics) {
+  RDataSectionChunk(const File &linkedFile)
+      : SectionChunk(".rdata", characteristics) {
     buildContents(linkedFile, [](const DefinedAtom *atom) {
       return (atom->contentType() == DefinedAtom::typeData &&
               atom->permissions() == DefinedAtom::permR__);
@@ -527,8 +518,8 @@ private:
 // \brief A DataSectionChunk represents a .data section.
 class DataSectionChunk : public SectionChunk {
 public:
-  DataSectionChunk(const File &linkedFile, SectionHeaderTableChunk *table)
-      : SectionChunk(table, ".data", characteristics) {
+  DataSectionChunk(const File &linkedFile)
+      : SectionChunk(".data", characteristics) {
     buildContents(linkedFile, [](const DefinedAtom *atom) {
       return (atom->contentType() == DefinedAtom::typeData &&
               atom->permissions() == DefinedAtom::permRW_);
@@ -569,19 +560,20 @@ private:
                                                 chunk->align());
     chunk->setFileOffset(_imageSizeOnDisk);
     _imageSizeOnDisk += chunk->size();
+  }
 
-    // Compute and set the starting address of sections when loaded in
-    // memory. They are different from positions on disk because sections need
-    // to be sector-aligned on disk but page-aligned in memory.
-    if (SectionChunk *sectionChunk = dyn_cast<SectionChunk>(chunk)) {
-      sectionChunk->setVirtualAddress(_imageSizeInMemory);
-      // Skip the empty section.
-      if (chunk->size() == 0)
-        return;
-      _numSections++;
-      _imageSizeInMemory = llvm::RoundUpToAlignment(
+  void maybeAddSectionChunk(SectionChunk *chunk,
+                            SectionHeaderTableChunk *table) {
+    // Skip the empty section. Windows loader does not like a section of size
+    // zero and rejects such executable.
+    if (chunk->size() == 0)
+      return;
+    addChunk(chunk);
+    table->addSection(chunk);
+    _numSections++;
+    chunk->setVirtualAddress(_imageSizeInMemory);
+    _imageSizeInMemory = llvm::RoundUpToAlignment(
         _imageSizeInMemory + chunk->size(), PAGE_SIZE);
-    }
   }
 
 public:
@@ -596,23 +588,29 @@ public:
     auto *peHeader = new PEHeaderChunk(_PECOFFTargetInfo);
     auto *dataDirectory = new DataDirectoryChunk();
     auto *sectionTable = new SectionHeaderTableChunk();
-    auto *text = new TextSectionChunk(linkedFile, sectionTable);
-    auto *rdata = new RDataSectionChunk(linkedFile, sectionTable);
-    auto *data = new DataSectionChunk(linkedFile, sectionTable);
+    auto *text = new TextSectionChunk(linkedFile);
+    auto *rdata = new RDataSectionChunk(linkedFile);
+    auto *data = new DataSectionChunk(linkedFile);
 
     addChunk(dosStub);
     addChunk(peHeader);
     addChunk(dataDirectory);
     addChunk(sectionTable);
-    addChunk(text);
-    addChunk(rdata);
-    addChunk(data);
+    maybeAddSectionChunk(text, sectionTable);
+    maybeAddSectionChunk(rdata, sectionTable);
+    maybeAddSectionChunk(data, sectionTable);
 
     // Now that we know the size and file offset of sections. Set the file
     // header accordingly.
     peHeader->setSizeOfCode(text->size());
-    peHeader->setBaseOfCode(text->getVirtualAddress());
-    peHeader->setBaseOfData(rdata->getVirtualAddress());
+    if (text->size() > 0) {
+      peHeader->setBaseOfCode(text->getVirtualAddress());
+    }
+    if (rdata->size() > 0) {
+      peHeader->setBaseOfData(rdata->getVirtualAddress());
+    } else if (data->size() > 0) {
+      peHeader->setBaseOfData(data->getVirtualAddress());
+    }
     peHeader->setSizeOfInitializedData(rdata->size() + data->size());
     peHeader->setNumberOfSections(_numSections);
     peHeader->setSizeOfImage(_imageSizeInMemory);

Modified: lld/trunk/test/pecoff/trivial.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/trivial.test?rev=186066&r1=186065&r2=186066&view=diff
==============================================================================
--- lld/trunk/test/pecoff/trivial.test (original)
+++ lld/trunk/test/pecoff/trivial.test Thu Jul 11 00:43:38 2013
@@ -34,7 +34,7 @@ FILE:   SizeOfInitializedData: 0
 FILE:   SizeOfUninitializedData: 0
 FILE:   AddressOfEntryPoint: 0x1000
 FILE:   BaseOfCode: 0x1000
-FILE:   BaseOfData: 0x2000
+FILE:   BaseOfData: 0
 FILE:   ImageBase: 0x400000
 FILE:   SectionAlignment: 4096
 FILE:   FileAlignment: 512





More information about the llvm-commits mailing list