[lld] r228900 - PECOFF: make dumpbin tool happy.

Rui Ueyama ruiu at google.com
Wed Feb 11 18:50:05 PST 2015


Author: ruiu
Date: Wed Feb 11 20:50:05 2015
New Revision: 228900

URL: http://llvm.org/viewvc/llvm-project?rev=228900&view=rev
Log:
PECOFF: make dumpbin tool happy.

The dumpbin tool in the MSVC toolchain cannot handle an executable created
by LLD if the executable contains a long section name.

In PE/COFF, a section name is stored to a section table entry. Because the
section name field in the table is only 8 byte long, a name longer than
that is stored to the string table and the offset in the string table is
stored to the section table entry instead.

In order to look up a string from the string table, tools need to handle
the symbol table, because the string table is defined as it immediately
follows the symbol table.

And seems the dumpbin doesn't like zero-length symbol table.

This patch teaches LLD how to emit a dummy symbol table. The dummy table
has one dummy entry in it.

Modified:
    lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp

Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=228900&r1=228899&r2=228900&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Wed Feb 11 20:50:05 2015
@@ -148,6 +148,7 @@ public:
   }
 
   void setNumberOfSections(uint32_t num) { _coffHeader.NumberOfSections = num; }
+  void setNumberOfSymbols(uint32_t num) { _coffHeader.NumberOfSymbols = num; }
 
   void setAddressOfEntryPoint(uint32_t address) {
     _peHeader.AddressOfEntryPoint = address;
@@ -186,13 +187,20 @@ public:
   }
 
   uint32_t addSectionName(StringRef sectionName) {
-    if (_stringTable.empty())
-      _stringTable.insert(_stringTable.begin(), 4, 0);
+    if (_stringTable.empty()) {
+      // The string table immediately follows the symbol table.
+      // We don't really need a symbol table, but some tools (e.g. dumpbin)
+      // don't like zero-length symbol table.
+      // Make room for the empty symbol slot, which occupies 18 byte.
+      // We also need to reserve 4 bytes for the string table header.
+      int size = sizeof(llvm::object::coff_symbol16) + 4;
+      _stringTable.insert(_stringTable.begin(), size, 0);
+    }
     uint32_t offset = _stringTable.size();
     _stringTable.insert(_stringTable.end(), sectionName.begin(),
                         sectionName.end());
     _stringTable.push_back('\0');
-    return offset;
+    return offset - sizeof(llvm::object::coff_symbol16);
   }
 
   uint64_t size() const override { return _stringTable.size(); }
@@ -200,7 +208,8 @@ public:
   void write(uint8_t *buffer) override {
     if (_stringTable.empty())
       return;
-    *reinterpret_cast<ulittle32_t *>(_stringTable.data()) = _stringTable.size();
+    char *off = _stringTable.data() + sizeof(llvm::object::coff_symbol16);
+    *reinterpret_cast<ulittle32_t *>(off) = _stringTable.size();
     std::memcpy(buffer, _stringTable.data(), _stringTable.size());
   }
 
@@ -1158,11 +1167,11 @@ void PECOFFWriter::build(const File &lin
   }
 
   setImageSizeOnDisk();
-  // N.B. Currently released versions of dumpbin do not appropriately handle
-  // symbol tables which NumberOfSymbols set to zero but a non-zero
-  // PointerToSymbolTable.
-  if (stringTable->size())
+
+  if (stringTable->size()) {
     peHeader->setPointerToSymbolTable(stringTable->fileOffset());
+    peHeader->setNumberOfSymbols(1);
+  }
 
   for (std::unique_ptr<Chunk> &chunk : _chunks) {
     SectionChunk *section = dyn_cast<SectionChunk>(chunk.get());





More information about the llvm-commits mailing list