[llvm] r276426 - [pdb] Round-trip module & file info to/from YAML.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 22 08:46:38 PDT 2016


Author: zturner
Date: Fri Jul 22 10:46:37 2016
New Revision: 276426

URL: http://llvm.org/viewvc/llvm-project?rev=276426&view=rev
Log:
[pdb] Round-trip module & file info to/from YAML.

This implements support for writing compiland and compiland source
file info to a binary PDB.  This is tested by adding support for
dumping these fields from an existing PDB to yaml, reading them
back in, and dumping them again and verifying the values are as
expected.

Modified:
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawError.h
    llvm/trunk/lib/DebugInfo/CodeView/StreamWriter.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/RawError.cpp
    llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp
    llvm/trunk/tools/llvm-pdbdump/PdbYaml.h
    llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h?rev=276426&r1=276425&r2=276426&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h Fri Jul 22 10:46:37 2016
@@ -106,6 +106,7 @@ public:
   Error commit();
 
 private:
+  Error initializeModInfoArray();
   Error initializeSectionContributionData();
   Error initializeSectionHeadersData();
   Error initializeSectionMapData();

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h?rev=276426&r1=276425&r2=276426&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h Fri Jul 22 10:46:37 2016
@@ -11,8 +11,10 @@
 #define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAMBUILDER_H
 
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Error.h"
 
+#include "llvm/DebugInfo/CodeView/ByteStream.h"
 #include "llvm/DebugInfo/PDB/PDBTypes.h"
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
 #include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
@@ -24,7 +26,7 @@ class PDBFile;
 
 class DbiStreamBuilder {
 public:
-  DbiStreamBuilder();
+  DbiStreamBuilder(BumpPtrAllocator &Allocator);
 
   DbiStreamBuilder(const DbiStreamBuilder &) = delete;
   DbiStreamBuilder &operator=(const DbiStreamBuilder &) = delete;
@@ -39,9 +41,27 @@ public:
 
   uint32_t calculateSerializedLength() const;
 
+  Error addModuleInfo(StringRef ObjFile, StringRef Module);
+  Error addModuleSourceFile(StringRef Module, StringRef File);
+
   Expected<std::unique_ptr<DbiStream>> build(PDBFile &File);
 
 private:
+  uint32_t calculateModiSubstreamSize() const;
+  uint32_t calculateFileInfoSubstreamSize() const;
+  uint32_t calculateNamesBufferSize() const;
+
+  Error generateModiSubstream();
+  Error generateFileInfoSubstream();
+
+  struct ModuleInfo {
+    std::vector<StringRef> SourceFiles;
+    StringRef Obj;
+    StringRef Mod;
+  };
+
+  BumpPtrAllocator &Allocator;
+
   Optional<PdbRaw_DbiVer> VerHeader;
   uint32_t Age;
   uint16_t BuildNumber;
@@ -49,6 +69,15 @@ private:
   uint16_t PdbDllRbld;
   uint16_t Flags;
   PDB_Machine MachineType;
+
+  StringMap<std::unique_ptr<ModuleInfo>> ModuleInfos;
+  std::vector<ModuleInfo *> ModuleInfoList;
+
+  StringMap<uint32_t> SourceFileNames;
+
+  codeview::StreamRef NamesBuffer;
+  codeview::ByteStream<true> ModInfoBuffer;
+  codeview::ByteStream<true> FileInfoBuffer;
 };
 }
 }

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h?rev=276426&r1=276425&r2=276426&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h Fri Jul 22 10:46:37 2016
@@ -13,6 +13,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/DebugInfo/CodeView/StreamArray.h"
 #include "llvm/DebugInfo/CodeView/StreamRef.h"
+#include "llvm/Support/Endian.h"
 #include <cstdint>
 #include <vector>
 
@@ -20,8 +21,59 @@ namespace llvm {
 namespace pdb {
 
 class ModInfo {
+  friend class DbiStreamBuilder;
+
 private:
-  struct FileLayout;
+  typedef support::ulittle16_t ulittle16_t;
+  typedef support::ulittle32_t ulittle32_t;
+  typedef support::little32_t little32_t;
+
+  struct SCBytes {
+    ulittle16_t Section;
+    char Padding1[2];
+    little32_t Offset;
+    little32_t Size;
+    ulittle32_t Characteristics;
+    ulittle16_t ModuleIndex;
+    char Padding2[2];
+    ulittle32_t DataCrc;
+    ulittle32_t RelocCrc;
+  };
+
+  // struct Flags {
+  //  uint16_t fWritten : 1;   // True if ModInfo is dirty
+  //  uint16_t fECEnabled : 1; // Is EC symbolic info present?  (What is EC?)
+  //  uint16_t unused : 6;     // Reserved
+  //  uint16_t iTSM : 8;       // Type Server Index for this module
+  //};
+  const uint16_t HasECFlagMask = 0x2;
+
+  const uint16_t TypeServerIndexMask = 0xFF00;
+  const uint16_t TypeServerIndexShift = 8;
+
+  struct FileLayout {
+    ulittle32_t Mod;          // Currently opened module.  This field is a
+                              // pointer in the reference implementation, but
+                              // that won't work on 64-bit systems, and anyway
+                              // it doesn't make sense to read a pointer from a
+                              // file.  For now it is unused, so just ignore it.
+    SCBytes SC;               // First section contribution of this module.
+    ulittle16_t Flags;        // See Flags definition.
+    ulittle16_t ModDiStream;  // Stream Number of module debug info
+    ulittle32_t SymBytes;     // Size of local symbol debug info in above stream
+    ulittle32_t LineBytes;    // Size of line number debug info in above stream
+    ulittle32_t C13Bytes;     // Size of C13 line number info in above stream
+    ulittle16_t NumFiles;     // Number of files contributing to this module
+    char Padding1[2];         // Padding so the next field is 4-byte aligned.
+    ulittle32_t FileNameOffs; // array of [0..NumFiles) DBI name buffer offsets.
+                              // This field is a pointer in the reference
+                              // implementation, but as with `Mod`, we ignore it
+                              // for now since it is unused.
+    ulittle32_t SrcFileNameNI; // Name Index for src file name
+    ulittle32_t PdbFilePathNI; // Name Index for path to compiler PDB
+                               // Null terminated Module name
+                               // Null terminated Obj File Name
+  };
 
 public:
   ModInfo();

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawError.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawError.h?rev=276426&r1=276425&r2=276426&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawError.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawError.h Fri Jul 22 10:46:37 2016
@@ -19,11 +19,14 @@ namespace pdb {
 enum class raw_error_code {
   unspecified = 1,
   feature_unsupported,
+  invalid_format,
   corrupt_file,
   insufficient_buffer,
   no_stream,
   index_out_of_bounds,
   invalid_block_address,
+  duplicate_entry,
+  no_entry,
   not_writable,
   invalid_tpi_hash,
 };

Modified: llvm/trunk/lib/DebugInfo/CodeView/StreamWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/StreamWriter.cpp?rev=276426&r1=276425&r2=276426&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/StreamWriter.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/StreamWriter.cpp Fri Jul 22 10:46:37 2016
@@ -54,7 +54,8 @@ Error StreamWriter::writeFixedString(Str
 Error StreamWriter::writeStreamRef(StreamRef Ref) {
   if (auto EC = writeStreamRef(Ref, Ref.getLength()))
     return EC;
-  Offset += Ref.getLength();
+  // Don't increment Offset here, it is done by the overloaded call to
+  // writeStreamRef.
   return Error::success();
 }
 

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp?rev=276426&r1=276425&r2=276426&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp Fri Jul 22 10:46:37 2016
@@ -142,14 +142,11 @@ Error DbiStream::reload() {
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "DBI type server substream not aligned.");
 
-  // Since each ModInfo in the stream is a variable length, we have to iterate
-  // them to know how many there actually are.
-  VarStreamArray<ModInfo> ModInfoArray;
-  if (auto EC = Reader.readArray(ModInfoArray, Header->ModiSubstreamSize))
+  if (auto EC =
+          Reader.readStreamRef(ModInfoSubstream, Header->ModiSubstreamSize))
+    return EC;
+  if (auto EC = initializeModInfoArray())
     return EC;
-  for (auto &Info : ModInfoArray) {
-    ModuleInfos.emplace_back(Info);
-  }
 
   if (auto EC = Reader.readStreamRef(SecContrSubstream,
                                      Header->SecContrSubstreamSize))
@@ -285,6 +282,24 @@ Error DbiStream::initializeSectionContri
                               "Unsupported DBI Section Contribution version");
 }
 
+Error DbiStream::initializeModInfoArray() {
+  if (ModInfoSubstream.getLength() == 0)
+    return Error::success();
+
+  // Since each ModInfo in the stream is a variable length, we have to iterate
+  // them to know how many there actually are.
+  StreamReader Reader(ModInfoSubstream);
+
+  VarStreamArray<ModInfo> ModInfoArray;
+  if (auto EC = Reader.readArray(ModInfoArray, ModInfoSubstream.getLength()))
+    return EC;
+  for (auto &Info : ModInfoArray) {
+    ModuleInfos.emplace_back(Info);
+  }
+
+  return Error::success();
+}
+
 // Initializes this->SectionHeaders.
 Error DbiStream::initializeSectionHeadersData() {
   if (DbgStreams.size() == 0)
@@ -437,7 +452,10 @@ Error DbiStream::initializeFileInfo() {
 }
 
 uint32_t DbiStream::getDebugStreamIndex(DbgHeaderType Type) const {
-  return DbgStreams[static_cast<uint16_t>(Type)];
+  uint16_t T = static_cast<uint16_t>(Type);
+  if (T >= DbgStreams.size())
+    return DbiStream::InvalidStreamIndex;
+  return DbgStreams[T];
 }
 
 Expected<StringRef> DbiStream::getFileNameForIndex(uint32_t Index) const {
@@ -458,5 +476,26 @@ Error DbiStream::commit() {
   if (auto EC = Writer.writeObject(*Header))
     return EC;
 
+  if (auto EC = Writer.writeStreamRef(ModInfoSubstream))
+    return EC;
+
+  if (auto EC = Writer.writeStreamRef(SecContrSubstream,
+                                      SecContrSubstream.getLength()))
+    return EC;
+  if (auto EC =
+          Writer.writeStreamRef(SecMapSubstream, SecMapSubstream.getLength()))
+    return EC;
+  if (auto EC = Writer.writeStreamRef(FileInfoSubstream,
+                                      FileInfoSubstream.getLength()))
+    return EC;
+  if (auto EC = Writer.writeStreamRef(TypeServerMapSubstream,
+                                      TypeServerMapSubstream.getLength()))
+    return EC;
+  if (auto EC = Writer.writeStreamRef(ECSubstream, ECSubstream.getLength()))
+    return EC;
+
+  if (Writer.bytesRemaining() > 0)
+    return make_error<RawError>(raw_error_code::invalid_format,
+                                "Unexpected bytes found in DBI Stream");
   return Error::success();
 }

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp?rev=276426&r1=276425&r2=276426&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp Fri Jul 22 10:46:37 2016
@@ -18,9 +18,13 @@ using namespace llvm;
 using namespace llvm::codeview;
 using namespace llvm::pdb;
 
-DbiStreamBuilder::DbiStreamBuilder()
-    : Age(1), BuildNumber(0), PdbDllVersion(0), PdbDllRbld(0), Flags(0),
-      MachineType(PDB_Machine::x86) {}
+namespace {
+class ModiSubstreamBuilder {};
+}
+
+DbiStreamBuilder::DbiStreamBuilder(BumpPtrAllocator &Allocator)
+    : Allocator(Allocator), Age(1), BuildNumber(0), PdbDllVersion(0),
+      PdbDllRbld(0), Flags(0), MachineType(PDB_Machine::x86) {}
 
 void DbiStreamBuilder::setVersionHeader(PdbRaw_DbiVer V) { VerHeader = V; }
 
@@ -38,7 +42,157 @@ void DbiStreamBuilder::setMachineType(PD
 
 uint32_t DbiStreamBuilder::calculateSerializedLength() const {
   // For now we only support serializing the header.
-  return sizeof(DbiStream::HeaderInfo);
+  return sizeof(DbiStream::HeaderInfo) + calculateFileInfoSubstreamSize() +
+         calculateModiSubstreamSize();
+}
+
+Error DbiStreamBuilder::addModuleInfo(StringRef ObjFile, StringRef Module) {
+  auto Entry = llvm::make_unique<ModuleInfo>();
+  ModuleInfo *M = Entry.get();
+  Entry->Mod = Module;
+  Entry->Obj = ObjFile;
+  auto Result = ModuleInfos.insert(std::make_pair(Module, std::move(Entry)));
+  if (!Result.second)
+    return make_error<RawError>(raw_error_code::duplicate_entry,
+                                "The specified module already exists");
+  ModuleInfoList.push_back(M);
+  return Error::success();
+}
+
+Error DbiStreamBuilder::addModuleSourceFile(StringRef Module, StringRef File) {
+  auto ModIter = ModuleInfos.find(Module);
+  if (ModIter == ModuleInfos.end())
+    return make_error<RawError>(raw_error_code::no_entry,
+                                "The specified module was not found");
+  uint32_t Index = SourceFileNames.size();
+  SourceFileNames.insert(std::make_pair(File, Index));
+  auto &ModEntry = *ModIter;
+  ModEntry.second->SourceFiles.push_back(File);
+  return Error::success();
+}
+
+uint32_t DbiStreamBuilder::calculateModiSubstreamSize() const {
+  uint32_t Size = 0;
+  for (const auto &M : ModuleInfoList) {
+    Size += sizeof(ModInfo::FileLayout);
+    Size += M->Mod.size() + 1;
+    Size += M->Obj.size() + 1;
+  }
+  return Size;
+}
+
+uint32_t DbiStreamBuilder::calculateFileInfoSubstreamSize() const {
+  //   ulittle16_t NumModules;
+  //   ulittle16_t NumSourceFiles;
+  //   ulittle16_t ModIndices[NumModules];
+  //   ulittle16_t ModFileCounts[NumModules];
+  //   ulittle32_t FileNameOffsets[NumSourceFiles];
+  //   char Names[NumSourceFiles][];
+  uint32_t Size = 0;
+  Size += sizeof(ulittle16_t);                         // NumModules
+  Size += sizeof(ulittle16_t);                         // NumSourceFiles
+  Size += ModuleInfoList.size() * sizeof(ulittle16_t); // ModIndices
+  Size += ModuleInfoList.size() * sizeof(ulittle16_t); // ModFileCounts
+  uint32_t NumFileInfos = 0;
+  for (const auto &M : ModuleInfoList)
+    NumFileInfos += M->SourceFiles.size();
+  Size += NumFileInfos * sizeof(ulittle32_t); // FileNameOffsets
+  Size += calculateNamesBufferSize();
+  return Size;
+}
+
+uint32_t DbiStreamBuilder::calculateNamesBufferSize() const {
+  uint32_t Size = 0;
+  for (const auto &F : SourceFileNames) {
+    Size += F.getKeyLength() + 1; // Names[I];
+  }
+  return Size;
+}
+
+Error DbiStreamBuilder::generateModiSubstream() {
+  uint32_t Size = calculateModiSubstreamSize();
+  auto Data = Allocator.Allocate<uint8_t>(Size);
+
+  ModInfoBuffer = ByteStream<true>(MutableArrayRef<uint8_t>(Data, Size));
+
+  StreamWriter ModiWriter(ModInfoBuffer);
+  for (const auto &M : ModuleInfoList) {
+    ModInfo::FileLayout Layout = {};
+    Layout.ModDiStream = DbiStream::InvalidStreamIndex;
+    Layout.NumFiles = M->SourceFiles.size();
+    if (auto EC = ModiWriter.writeObject(Layout))
+      return EC;
+    if (auto EC = ModiWriter.writeZeroString(M->Mod))
+      return EC;
+    if (auto EC = ModiWriter.writeZeroString(M->Obj))
+      return EC;
+  }
+  if (ModiWriter.bytesRemaining() != 0)
+    return make_error<RawError>(raw_error_code::invalid_format,
+                                "Unexpected bytes in Modi Stream Data");
+  return Error::success();
+}
+
+Error DbiStreamBuilder::generateFileInfoSubstream() {
+  uint32_t Size = calculateFileInfoSubstreamSize();
+  uint32_t NameSize = calculateNamesBufferSize();
+  auto Data = Allocator.Allocate<uint8_t>(Size);
+  uint32_t NamesOffset = Size - NameSize;
+
+  FileInfoBuffer = ByteStream<true>(MutableArrayRef<uint8_t>(Data, Size));
+
+  StreamRef MetadataBuffer = StreamRef(FileInfoBuffer).keep_front(NamesOffset);
+  StreamWriter MetadataWriter(MetadataBuffer);
+
+  uint16_t ModiCount = std::min<uint16_t>(UINT16_MAX, ModuleInfos.size());
+  uint16_t FileCount = std::min<uint16_t>(UINT16_MAX, SourceFileNames.size());
+  if (auto EC = MetadataWriter.writeInteger(ModiCount)) // NumModules
+    return EC;
+  if (auto EC = MetadataWriter.writeInteger(FileCount)) // NumSourceFiles
+    return EC;
+  for (uint16_t I = 0; I < ModiCount; ++I) {
+    if (auto EC = MetadataWriter.writeInteger(I)) // Mod Indices
+      return EC;
+  }
+  for (const auto MI : ModuleInfoList) {
+    FileCount = static_cast<uint16_t>(MI->SourceFiles.size());
+    if (auto EC = MetadataWriter.writeInteger(FileCount)) // Mod File Counts
+      return EC;
+  }
+
+  // Before writing the FileNameOffsets array, write the NamesBuffer array.
+  // A side effect of this is that this will actually compute the various
+  // file name offsets, so we can then go back and write the FileNameOffsets
+  // array to the other substream.
+  NamesBuffer = StreamRef(FileInfoBuffer).drop_front(NamesOffset);
+  StreamWriter NameBufferWriter(NamesBuffer);
+  for (auto &Name : SourceFileNames) {
+    Name.second = NameBufferWriter.getOffset();
+    if (auto EC = NameBufferWriter.writeZeroString(Name.getKey()))
+      return EC;
+  }
+
+  for (const auto MI : ModuleInfoList) {
+    for (StringRef Name : MI->SourceFiles) {
+      auto Result = SourceFileNames.find(Name);
+      if (Result == SourceFileNames.end())
+        return make_error<RawError>(raw_error_code::no_entry,
+                                    "The source file was not found.");
+      if (auto EC = MetadataWriter.writeInteger(Result->second))
+        return EC;
+    }
+  }
+
+  if (NameBufferWriter.bytesRemaining() > 0)
+    return make_error<RawError>(raw_error_code::invalid_format,
+                                "The names buffer contained unexpected data.");
+
+  if (MetadataWriter.bytesRemaining() > 0)
+    return make_error<RawError>(
+        raw_error_code::invalid_format,
+        "The metadata buffer contained unexpected data.");
+
+  return Error::success();
 }
 
 Expected<std::unique_ptr<DbiStream>> DbiStreamBuilder::build(PDBFile &File) {
@@ -54,6 +208,12 @@ Expected<std::unique_ptr<DbiStream>> Dbi
       static_cast<DbiStream::HeaderInfo *>(DS->getAllocator().Allocate(
           sizeof(DbiStream::HeaderInfo),
           llvm::AlignOf<DbiStream::HeaderInfo>::Alignment));
+
+  if (auto EC = generateModiSubstream())
+    return std::move(EC);
+  if (auto EC = generateFileInfoSubstream())
+    return std::move(EC);
+
   H->VersionHeader = *VerHeader;
   H->VersionSignature = -1;
   H->Age = Age;
@@ -64,8 +224,8 @@ Expected<std::unique_ptr<DbiStream>> Dbi
   H->MachineType = static_cast<uint16_t>(MachineType);
 
   H->ECSubstreamSize = 0;
-  H->FileInfoSize = 0;
-  H->ModiSubstreamSize = 0;
+  H->FileInfoSize = FileInfoBuffer.getLength();
+  H->ModiSubstreamSize = ModInfoBuffer.getLength();
   H->OptionalDbgHdrSize = 0;
   H->SecContrSubstreamSize = 0;
   H->SectionMapSize = 0;
@@ -77,5 +237,11 @@ Expected<std::unique_ptr<DbiStream>> Dbi
 
   auto Dbi = llvm::make_unique<DbiStream>(File, std::move(DS));
   Dbi->Header = H;
+  Dbi->FileInfoSubstream = StreamRef(FileInfoBuffer);
+  Dbi->ModInfoSubstream = StreamRef(ModInfoBuffer);
+  if (auto EC = Dbi->initializeModInfoArray())
+    return std::move(EC);
+  if (auto EC = Dbi->initializeFileInfo())
+    return std::move(EC);
   return std::move(Dbi);
 }

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp?rev=276426&r1=276425&r2=276426&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp Fri Jul 22 10:46:37 2016
@@ -17,55 +17,6 @@ using namespace llvm;
 using namespace llvm::pdb;
 using namespace llvm::support;
 
-namespace {
-
-struct SCBytes {
-  ulittle16_t Section;
-  char Padding1[2];
-  little32_t Offset;
-  little32_t Size;
-  ulittle32_t Characteristics;
-  ulittle16_t ModuleIndex;
-  char Padding2[2];
-  ulittle32_t DataCrc;
-  ulittle32_t RelocCrc;
-};
-
-// struct Flags {
-//  uint16_t fWritten : 1;   // True if ModInfo is dirty
-//  uint16_t fECEnabled : 1; // Is EC symbolic info present?  (What is EC?)
-//  uint16_t unused : 6;     // Reserved
-//  uint16_t iTSM : 8;       // Type Server Index for this module
-//};
-const uint16_t HasECFlagMask = 0x2;
-
-const uint16_t TypeServerIndexMask = 0xFF00;
-const uint16_t TypeServerIndexShift = 8;
-}
-
-struct ModInfo::FileLayout {
-  ulittle32_t Mod;           // Currently opened module.  This field is a
-                             // pointer in the reference implementation, but
-                             // that won't work on 64-bit systems, and anyway
-                             // it doesn't make sense to read a pointer from a
-                             // file.  For now it is unused, so just ignore it.
-  SCBytes SC;                // First section contribution of this module.
-  ulittle16_t Flags;         // See Flags definition.
-  ulittle16_t ModDiStream;   // Stream Number of module debug info
-  ulittle32_t SymBytes;      // Size of local symbol debug info in above stream
-  ulittle32_t LineBytes;     // Size of line number debug info in above stream
-  ulittle32_t C13Bytes;      // Size of C13 line number info in above stream
-  ulittle16_t NumFiles;      // Number of files contributing to this module
-  char Padding1[2];          // Padding so the next field is 4-byte aligned.
-  ulittle32_t FileNameOffs;  // array of [0..NumFiles) DBI name buffer offsets.
-                             // This field is a pointer in the reference
-                             // implementation, but as with `Mod`, we ignore it
-                             // for now since it is unused.
-  ulittle32_t SrcFileNameNI; // Name Index for src file name
-  ulittle32_t PdbFilePathNI; // Name Index for path to compiler PDB
-                             // Null terminated Module name
-                             // Null terminated Obj File Name
-};
 
 ModInfo::ModInfo() : Layout(nullptr) {}
 

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp?rev=276426&r1=276425&r2=276426&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp Fri Jul 22 10:46:37 2016
@@ -53,7 +53,7 @@ InfoStreamBuilder &PDBFileBuilder::getIn
 
 DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() {
   if (!Dbi)
-    Dbi = llvm::make_unique<DbiStreamBuilder>();
+    Dbi = llvm::make_unique<DbiStreamBuilder>(File->Allocator);
   return *Dbi;
 }
 

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/RawError.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/RawError.cpp?rev=276426&r1=276425&r2=276426&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/RawError.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/RawError.cpp Fri Jul 22 10:46:37 2016
@@ -19,6 +19,8 @@ public:
       return "An unknown error has occurred.";
     case raw_error_code::feature_unsupported:
       return "The feature is unsupported by the implementation.";
+    case raw_error_code::invalid_format:
+      return "The record is in an unexpected format.";
     case raw_error_code::corrupt_file:
       return "The PDB file is corrupt.";
     case raw_error_code::insufficient_buffer:
@@ -30,6 +32,10 @@ public:
       return "The specified item does not exist in the array.";
     case raw_error_code::invalid_block_address:
       return "The specified block address is not valid.";
+    case raw_error_code::duplicate_entry:
+      return "The entry already exists.";
+    case raw_error_code::no_entry:
+      return "The entry does not exist.";
     case raw_error_code::not_writable:
       return "The PDB does not support writing.";
     case raw_error_code::invalid_tpi_hash:

Modified: llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp?rev=276426&r1=276425&r2=276426&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp Fri Jul 22 10:46:37 2016
@@ -153,6 +153,7 @@ void MappingTraits<PdbDbiStream>::mappin
   IO.mapRequired("PdbDllRbld", Obj.PdbDllRbld);
   IO.mapRequired("Flags", Obj.Flags);
   IO.mapRequired("MachineType", Obj.MachineType);
+  IO.mapOptional("Modules", Obj.ModInfos);
 }
 
 void MappingTraits<NamedStreamMapping>::mapping(IO &IO,
@@ -160,3 +161,9 @@ void MappingTraits<NamedStreamMapping>::
   IO.mapRequired("Name", Obj.StreamName);
   IO.mapRequired("StreamNum", Obj.StreamNumber);
 }
+
+void MappingTraits<PdbDbiModuleInfo>::mapping(IO &IO, PdbDbiModuleInfo &Obj) {
+  IO.mapRequired("Module", Obj.Mod);
+  IO.mapRequired("ObjFile", Obj.Obj);
+  IO.mapOptional("SourceFiles", Obj.SourceFiles);
+}

Modified: llvm/trunk/tools/llvm-pdbdump/PdbYaml.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PdbYaml.h?rev=276426&r1=276425&r2=276426&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PdbYaml.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/PdbYaml.h Fri Jul 22 10:46:37 2016
@@ -51,6 +51,12 @@ struct PdbInfoStream {
   std::vector<NamedStreamMapping> NamedStreams;
 };
 
+struct PdbDbiModuleInfo {
+  StringRef Obj;
+  StringRef Mod;
+  std::vector<StringRef> SourceFiles;
+};
+
 struct PdbDbiStream {
   PdbRaw_DbiVer VerHeader;
   uint32_t Age;
@@ -59,6 +65,8 @@ struct PdbDbiStream {
   uint16_t PdbDllRbld;
   uint16_t Flags;
   PDB_Machine MachineType;
+
+  std::vector<PdbDbiModuleInfo> ModInfos;
 };
 
 struct PdbObject {
@@ -102,11 +110,17 @@ template <> struct MappingTraits<pdb::ya
 template <> struct MappingTraits<pdb::yaml::NamedStreamMapping> {
   static void mapping(IO &IO, pdb::yaml::NamedStreamMapping &Obj);
 };
+
+template <> struct MappingTraits<pdb::yaml::PdbDbiModuleInfo> {
+  static void mapping(IO &IO, pdb::yaml::PdbDbiModuleInfo &Obj);
+};
 }
 }
 
 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::NamedStreamMapping)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbDbiModuleInfo)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::StreamBlockList)
 
 #endif // LLVM_TOOLS_LLVMPDBDUMP_PDBYAML_H

Modified: llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp?rev=276426&r1=276425&r2=276426&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp Fri Jul 22 10:46:37 2016
@@ -25,6 +25,10 @@ YAMLOutputStyle::YAMLOutputStyle(PDBFile
 Error YAMLOutputStyle::dump() {
   if (opts::pdb2yaml::StreamDirectory)
     opts::pdb2yaml::StreamMetadata = true;
+  if (opts::pdb2yaml::DbiModuleSourceFileInfo)
+    opts::pdb2yaml::DbiModuleInfo = true;
+  if (opts::pdb2yaml::DbiModuleInfo)
+    opts::pdb2yaml::DbiStream = true;
 
   if (auto EC = dumpFileHeaders())
     return EC;
@@ -133,6 +137,16 @@ Error YAMLOutputStyle::dumpDbiStream() {
   Obj.DbiStream->PdbDllRbld = DS.getPdbDllRbld();
   Obj.DbiStream->PdbDllVersion = DS.getPdbDllVersion();
   Obj.DbiStream->VerHeader = DS.getDbiVersion();
+  if (opts::pdb2yaml::DbiModuleInfo) {
+    for (const auto &MI : DS.modules()) {
+      yaml::PdbDbiModuleInfo DMI;
+      DMI.Mod = MI.Info.getModuleName();
+      DMI.Obj = MI.Info.getObjFileName();
+      if (opts::pdb2yaml::DbiModuleSourceFileInfo)
+        DMI.SourceFiles = MI.SourceFiles;
+      Obj.DbiStream->ModInfos.push_back(DMI);
+    }
+  }
   return Error::success();
 }
 

Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=276426&r1=276425&r2=276426&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Fri Jul 22 10:46:37 2016
@@ -285,6 +285,16 @@ cl::opt<bool> PdbStream("pdb-stream",
 cl::opt<bool> DbiStream("dbi-stream",
                         cl::desc("Dump the DBI Stream (Stream 2)"),
                         cl::sub(PdbToYamlSubcommand), cl::init(false));
+cl::opt<bool>
+    DbiModuleInfo("dbi-module-info",
+                  cl::desc("Dump DBI Module Information (implies -dbi-stream)"),
+                  cl::sub(PdbToYamlSubcommand), cl::init(false));
+
+cl::opt<bool> DbiModuleSourceFileInfo(
+    "dbi-module-source-info",
+    cl::desc(
+        "Dump DBI Module Source File Information (implies -dbi-module-info"),
+    cl::sub(PdbToYamlSubcommand), cl::init(false));
 
 cl::list<std::string> InputFilename(cl::Positional,
                                     cl::desc("<input PDB file>"), cl::Required,
@@ -375,6 +385,11 @@ static void yamlToPdb(StringRef Path) {
     DbiBuilder.setPdbDllRbld(YamlObj.DbiStream->PdbDllRbld);
     DbiBuilder.setPdbDllVersion(YamlObj.DbiStream->PdbDllVersion);
     DbiBuilder.setVersionHeader(YamlObj.DbiStream->VerHeader);
+    for (const auto &MI : YamlObj.DbiStream->ModInfos) {
+      ExitOnErr(DbiBuilder.addModuleInfo(MI.Obj, MI.Mod));
+      for (auto S : MI.SourceFiles)
+        ExitOnErr(DbiBuilder.addModuleSourceFile(MI.Mod, S));
+    }
   }
 
   auto Pdb = Builder.build();

Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h?rev=276426&r1=276425&r2=276426&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h Fri Jul 22 10:46:37 2016
@@ -62,6 +62,8 @@ extern llvm::cl::opt<bool> StreamMetadat
 extern llvm::cl::opt<bool> StreamDirectory;
 extern llvm::cl::opt<bool> PdbStream;
 extern llvm::cl::opt<bool> DbiStream;
+extern llvm::cl::opt<bool> DbiModuleInfo;
+extern llvm::cl::opt<bool> DbiModuleSourceFileInfo;
 extern llvm::cl::list<std::string> InputFilename;
 }
 }




More information about the llvm-commits mailing list