[llvm] r306233 - [pdb] Fix reading of llvm-generated PDBs by cvdump.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 24 20:51:42 PDT 2017


Author: zturner
Date: Sat Jun 24 20:51:42 2017
New Revision: 306233

URL: http://llvm.org/viewvc/llvm-project?rev=306233&view=rev
Log:
[pdb] Fix reading of llvm-generated PDBs by cvdump.

If you dump a pdb to yaml, and then round-trip it back to a pdb,
and run cvdump -l <file> on the new pdb, cvdump will generate
output such as this.

*** LINES

** Module: "d:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj"

Error: Line number corrupted: invalid file id 0
  <Unknown> (MD5), 0001:00000010-0000001A, line/addr pairs = 3

        5 00000010      6 00000013      7 00000018

Note the error message about the corrupted line number.

It turns out that the problem is that cvdump cannot find the
/names stream (e.g. the global string table), and the reason it
can't find the /names stream is because it doesn't understand
the NameMap that we serialize which tells pdb consumers which
stream has the string table.

Some experimentation shows that if we add items to the hash
table in a specific order before serializing it, cvdump can read
it. This suggests that either we're using the wrong hash function,
or we're serializing something incorrectly, but it will take some
deeper investigation to figure out how / why.  For now, this at
least allows cvdump to read our line information (and incidentally,
produces an identical byte sequence to what Microsoft tools
produce when writing the named stream map).

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

Modified:
    llvm/trunk/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp?rev=306233&r1=306232&r2=306233&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp Sat Jun 24 20:51:42 2017
@@ -23,6 +23,14 @@
 using namespace llvm;
 using namespace llvm::pdb;
 
+// FIXME: This shouldn't be necessary, but if we insert the strings in any
+// other order, cvdump cannot read the generated name map.  This suggests that
+// we may be using the wrong hash function.  A closer inspection of the cvdump
+// source code may reveal something, but for now this at least makes us work,
+// even if only by accident.
+static constexpr const char *OrderedStreamNames[] = {"/LinkInfo", "/names",
+                                                     "/src/headerblock"};
+
 NamedStreamMap::NamedStreamMap() = default;
 
 Error NamedStreamMap::load(BinaryStreamReader &Stream) {
@@ -73,9 +81,10 @@ Error NamedStreamMap::commit(BinaryStrea
   if (auto EC = Writer.writeInteger(FinalizedInfo->StringDataBytes))
     return EC;
 
-  // Now all of the string data itself.
-  for (const auto &Item : Mapping) {
-    if (auto EC = Writer.writeCString(Item.getKey()))
+  for (const auto &Name : OrderedStreamNames) {
+    auto Item = Mapping.find(Name);
+    assert(Item != Mapping.end());
+    if (auto EC = Writer.writeCString(Item->getKey()))
       return EC;
   }
 
@@ -93,9 +102,12 @@ uint32_t NamedStreamMap::finalize() {
   // Build the finalized hash table.
   FinalizedHashTable.clear();
   FinalizedInfo.emplace();
-  for (const auto &Item : Mapping) {
-    FinalizedHashTable.set(FinalizedInfo->StringDataBytes, Item.getValue());
-    FinalizedInfo->StringDataBytes += Item.getKeyLength() + 1;
+
+  for (const auto &Name : OrderedStreamNames) {
+    auto Item = Mapping.find(Name);
+    assert(Item != Mapping.end());
+    FinalizedHashTable.set(FinalizedInfo->StringDataBytes, Item->getValue());
+    FinalizedInfo->StringDataBytes += Item->getKeyLength() + 1;
   }
 
   // Number of bytes of string data.




More information about the llvm-commits mailing list