]> granicus.if.org Git - llvm/commitdiff
[PDB] Start emitting source file and line information
authorReid Kleckner <rnk@google.com>
Mon, 19 Jun 2017 17:21:45 +0000 (17:21 +0000)
committerReid Kleckner <rnk@google.com>
Mon, 19 Jun 2017 17:21:45 +0000 (17:21 +0000)
Summary:
This is a first step towards getting line info to show up in VS and
windbg. So far, only llvm-pdbutil can parse the PDBs that we produce.
cvdump doesn't like something about our file checksum tables. I'll have
to dig into that next.

This patch adds a new DebugSubsectionRecordBuilder which takes bytes
directly from some other producer, such as a linker, and sticks it into
the PDB. Line tables only need to be relocated. No data needs to be
rewritten.

File checksums and string tables, on the other hand, need to be re-done.

Reviewers: zturner, ruiu

Subscribers: llvm-commits, hiraditya

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305713 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h
lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp
lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp

index 6947317420643638e5b429311a3460ab939fc152..ee17b47d8e631bd289fe519c314c87e79b5077ae 100644 (file)
@@ -51,11 +51,23 @@ class DebugSubsectionRecordBuilder {
 public:
   DebugSubsectionRecordBuilder(std::shared_ptr<DebugSubsection> Subsection,
                                CodeViewContainer Container);
+
+  /// Use this to copy existing subsections directly from source to destination.
+  /// For example, line table subsections in an object file only need to be
+  /// relocated before being copied into the PDB.
+  DebugSubsectionRecordBuilder(const DebugSubsectionRecord &Contents,
+                               CodeViewContainer Container);
+
   uint32_t calculateSerializedLength();
   Error commit(BinaryStreamWriter &Writer) const;
 
 private:
+  /// The subsection to build. Will be null if Contents is non-empty.
   std::shared_ptr<DebugSubsection> Subsection;
+
+  /// The bytes of the subsection. Only non-empty if Subsection is null.
+  DebugSubsectionRecord Contents;
+
   CodeViewContainer Container;
 };
 
index a89e26ae943c9b4a6e33704af1d46bd67860effa..e4cb1b24e30d06dd565667f370c01394340b745c 100644 (file)
@@ -14,6 +14,7 @@
 #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
 #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
 #include "llvm/Support/Error.h"
@@ -52,6 +53,9 @@ public:
   void
   addDebugSubsection(std::shared_ptr<codeview::DebugSubsection> Subsection);
 
+  void
+  addDebugSubsection(const codeview::DebugSubsectionRecord &SubsectionContents);
+
   uint16_t getStreamIndex() const;
   StringRef getModuleName() const { return ModuleName; }
   StringRef getObjFileName() const { return ObjFileName; }
index aeb2e2ab026a519a6c3a09a3dd0b4320cdd1724c..744411854181f241b7e91016ffbe348c6489f03c 100644 (file)
@@ -58,6 +58,7 @@ public:
 
   Expected<DbiModuleDescriptorBuilder &> addModuleInfo(StringRef ModuleName);
   Error addModuleSourceFile(StringRef Module, StringRef File);
+  Error addModuleSourceFile(DbiModuleDescriptorBuilder &Module, StringRef File);
   Expected<uint32_t> getSourceFileNameIndex(StringRef FileName);
 
   Error finalizeMsfLayout();
index 334c5e002bbca1727da07ce42215775a222298c2..d69eca018e0c168cb19b3c6ee86f39d3346023b9 100644 (file)
@@ -53,12 +53,16 @@ DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
     std::shared_ptr<DebugSubsection> Subsection, CodeViewContainer Container)
     : Subsection(std::move(Subsection)), Container(Container) {}
 
+DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
+    const DebugSubsectionRecord &Contents, CodeViewContainer Container)
+    : Contents(Contents), Container(Container) {}
+
 uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() {
-  // The length of the entire subsection is always padded to 4 bytes, regardless
-  // of the container kind.
-  uint32_t Size = sizeof(DebugSubsectionHeader) +
-                  alignTo(Subsection->calculateSerializedSize(), 4);
-  return Size;
+  uint32_t DataSize = Subsection ? Subsection->calculateSerializedSize()
+                                 : Contents.getRecordData().getLength();
+  // The length of the entire subsection is always padded to 4 bytes,
+  // regardless of the container kind.
+  return sizeof(DebugSubsectionHeader) + alignTo(DataSize, 4);
 }
 
 Error DebugSubsectionRecordBuilder::commit(BinaryStreamWriter &Writer) const {
@@ -66,16 +70,22 @@ Error DebugSubsectionRecordBuilder::commit(BinaryStreamWriter &Writer) const {
          "Debug Subsection not properly aligned");
 
   DebugSubsectionHeader Header;
-  Header.Kind = uint32_t(Subsection->kind());
+  Header.Kind = uint32_t(Subsection ? Subsection->kind() : Contents.kind());
   // The value written into the Header's Length field is only padded to the
   // container's alignment
-  Header.Length =
-      alignTo(Subsection->calculateSerializedSize(), alignOf(Container));
+  uint32_t DataSize = Subsection ? Subsection->calculateSerializedSize()
+                                 : Contents.getRecordData().getLength();
+  Header.Length = alignTo(DataSize, alignOf(Container));
 
   if (auto EC = Writer.writeObject(Header))
     return EC;
-  if (auto EC = Subsection->commit(Writer))
-    return EC;
+  if (Subsection) {
+    if (auto EC = Subsection->commit(Writer))
+      return EC;
+  } else {
+    if (auto EC = Writer.writeStreamRef(Contents.getRecordData()))
+      return EC;
+  }
   if (auto EC = Writer.padToAlignment(4))
     return EC;
 
index 81a9d3eeec6199ac72535a005f20f6c018dc6dfb..59ecbb50143815ee00c6131b7dc622c83221bdd1 100644 (file)
@@ -182,3 +182,9 @@ void DbiModuleDescriptorBuilder::addDebugSubsection(
   C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
       std::move(Subsection), CodeViewContainer::Pdb));
 }
+
+void DbiModuleDescriptorBuilder::addDebugSubsection(
+    const DebugSubsectionRecord &SubsectionContents) {
+  C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
+      SubsectionContents, CodeViewContainer::Pdb));
+}
index e7304b444f23f896e588b1597410ed014dbc0ecf..0ad461546d728ee0518ed5f48de87e0e04e3172a 100644 (file)
@@ -90,10 +90,14 @@ Error DbiStreamBuilder::addModuleSourceFile(StringRef Module, StringRef File) {
   if (ModIter == ModiMap.end())
     return make_error<RawError>(raw_error_code::no_entry,
                                 "The specified module was not found");
+  return addModuleSourceFile(*ModIter->second, File);
+}
+
+Error DbiStreamBuilder::addModuleSourceFile(DbiModuleDescriptorBuilder &Module,
+                                            StringRef File) {
   uint32_t Index = SourceFileNames.size();
   SourceFileNames.insert(std::make_pair(File, Index));
-  auto &ModEntry = *ModIter;
-  ModEntry.second->addSourceFile(File);
+  Module.addSourceFile(File);
   return Error::success();
 }