Re-submit r283823: Define DbiStreamBuilder::addDbgStream to add stream.
authorRui Ueyama <ruiu@google.com>
Tue, 11 Oct 2016 19:43:12 +0000 (19:43 +0000)
committerRui Ueyama <ruiu@google.com>
Tue, 11 Oct 2016 19:43:12 +0000 (19:43 +0000)
The previous commit was failing because we filled empty slots of
the debug stream index with kInvalidStreamIndex. It should've been 0.

llvm-svn: 283925

llvm/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h
llvm/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h
llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp

index 96a9b51..7e2439d 100644 (file)
@@ -19,6 +19,7 @@
 #include "llvm/DebugInfo/PDB/PDBTypes.h"
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
 #include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+#include "llvm/Support/Endian.h"
 
 namespace llvm {
 namespace msf {
@@ -44,6 +45,9 @@ public:
   void setFlags(uint16_t F);
   void setMachineType(PDB_Machine M);
 
+  // Add given bytes as a new stream.
+  Error addDbgStream(pdb::DbgHeaderType Type, ArrayRef<uint8_t> Data);
+
   uint32_t calculateSerializedLength() const;
 
   Error addModuleInfo(StringRef ObjFile, StringRef Module);
@@ -57,6 +61,11 @@ public:
                const msf::WritableStream &Buffer);
 
 private:
+  struct DebugStream {
+    ArrayRef<uint8_t> Data;
+    uint16_t StreamNumber = 0;
+  };
+
   Error finalize();
   uint32_t calculateModiSubstreamSize() const;
   uint32_t calculateFileInfoSubstreamSize() const;
@@ -92,6 +101,8 @@ private:
   msf::WritableStreamRef NamesBuffer;
   msf::MutableByteStream ModInfoBuffer;
   msf::MutableByteStream FileInfoBuffer;
+  llvm::SmallVector<DebugStream, (int)DbgHeaderType::Max> DbgStreams{
+      (int)DbgHeaderType::Max};
 };
 }
 }
index ce5e3ff..3045ab7 100644 (file)
@@ -14,6 +14,7 @@
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
index bb0e730..2a8aeb4 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h"
 
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/DebugInfo/MSF/MSFBuilder.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/MSF/StreamWriter.h"
@@ -43,10 +44,24 @@ void DbiStreamBuilder::setFlags(uint16_t F) { Flags = F; }
 
 void DbiStreamBuilder::setMachineType(PDB_Machine M) { MachineType = M; }
 
+Error DbiStreamBuilder::addDbgStream(pdb::DbgHeaderType Type,
+                                     ArrayRef<uint8_t> Data) {
+  if (DbgStreams[(int)Type].StreamNumber)
+    return make_error<RawError>(raw_error_code::duplicate_entry,
+                                "The specified stream type already exists");
+  auto ExpectedIndex = Msf.addStream(Data.size());
+  if (!ExpectedIndex)
+    return ExpectedIndex.takeError();
+  uint32_t Index = std::move(*ExpectedIndex);
+  DbgStreams[(int)Type].Data = Data;
+  DbgStreams[(int)Type].StreamNumber = Index;
+  return Error::success();
+}
+
 uint32_t DbiStreamBuilder::calculateSerializedLength() const {
   // For now we only support serializing the header.
   return sizeof(DbiStreamHeader) + calculateFileInfoSubstreamSize() +
-         calculateModiSubstreamSize();
+         calculateModiSubstreamSize() + DbgStreams.size() * sizeof(uint16_t);
 }
 
 Error DbiStreamBuilder::addModuleInfo(StringRef ObjFile, StringRef Module) {
@@ -216,7 +231,7 @@ Error DbiStreamBuilder::finalize() {
   H->ECSubstreamSize = 0;
   H->FileInfoSize = FileInfoBuffer.getLength();
   H->ModiSubstreamSize = ModInfoBuffer.getLength();
-  H->OptionalDbgHdrSize = 0;
+  H->OptionalDbgHdrSize = DbgStreams.size() * sizeof(uint16_t);
   H->SecContrSubstreamSize = 0;
   H->SectionMapSize = 0;
   H->TypeServerSize = 0;
@@ -273,6 +288,19 @@ Error DbiStreamBuilder::commit(const msf::MSFLayout &Layout,
     return EC;
   if (auto EC = Writer.writeStreamRef(FileInfoBuffer))
     return EC;
+  for (auto &Stream : DbgStreams)
+    if (auto EC = Writer.writeInteger(Stream.StreamNumber))
+      return EC;
+
+  for (auto &Stream : DbgStreams) {
+    if (Stream.StreamNumber == kInvalidStreamIndex)
+      continue;
+    auto WritableStream = WritableMappedBlockStream::createIndexedStream(
+        Layout, Buffer, Stream.StreamNumber);
+    StreamWriter DbgStreamWriter(*WritableStream);
+    if (auto EC = DbgStreamWriter.writeArray(Stream.Data))
+      return EC;
+  }
 
   if (Writer.bytesRemaining() > 0)
     return make_error<RawError>(raw_error_code::invalid_format,