OSDN Git Service

[lld/pdb] Add an empty globals stream.
authorZachary Turner <zturner@google.com>
Mon, 31 Jul 2017 19:36:08 +0000 (19:36 +0000)
committerZachary Turner <zturner@google.com>
Mon, 31 Jul 2017 19:36:08 +0000 (19:36 +0000)
We don't write any actual symbols to this stream yet, but for
now we just create the stream and hook it up to the appropriate
places and give it a valid header.

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

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

include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h
include/llvm/DebugInfo/PDB/Native/GlobalsStreamBuilder.h [new file with mode: 0644]
include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
lib/DebugInfo/PDB/CMakeLists.txt
lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
lib/DebugInfo/PDB/Native/GlobalsStreamBuilder.cpp [new file with mode: 0644]
lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp

index 63eb34f..584d531 100644 (file)
@@ -59,6 +59,7 @@ public:
 
   uint32_t calculateSerializedLength() const;
 
+  void setGlobalsStreamIndex(uint32_t Index);
   void setPublicsStreamIndex(uint32_t Index);
   void setSymbolRecordStreamIndex(uint32_t Index);
 
@@ -105,6 +106,7 @@ private:
   uint16_t PdbDllRbld;
   uint16_t Flags;
   PDB_Machine MachineType;
+  uint32_t GlobalsStreamIndex = kInvalidStreamIndex;
   uint32_t PublicsStreamIndex = kInvalidStreamIndex;
   uint32_t SymRecordStreamIndex = kInvalidStreamIndex;
 
diff --git a/include/llvm/DebugInfo/PDB/Native/GlobalsStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/GlobalsStreamBuilder.h
new file mode 100644 (file)
index 0000000..d9292f0
--- /dev/null
@@ -0,0 +1,50 @@
+//===- GlobalsStreamBuilder.h - PDB Globals Stream Creation -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBGLOBALSTREAMBUILDER_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBGLOBALSTREAMBUILDER_H
+
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace msf {
+class MSFBuilder;
+}
+namespace pdb {
+class GlobalsStream;
+
+class GlobalsStreamBuilder {
+public:
+  explicit GlobalsStreamBuilder(msf::MSFBuilder &Msf);
+  ~GlobalsStreamBuilder();
+
+  GlobalsStreamBuilder(const GlobalsStreamBuilder &) = delete;
+  GlobalsStreamBuilder &operator=(const GlobalsStreamBuilder &) = delete;
+
+  Error finalizeMsfLayout();
+  uint32_t calculateSerializedLength() const;
+
+  Error commit(BinaryStreamWriter &PublicsWriter);
+
+  uint32_t getStreamIndex() const { return StreamIdx; }
+
+private:
+  uint32_t StreamIdx = kInvalidStreamIndex;
+  msf::MSFBuilder &Msf;
+};
+} // namespace pdb
+} // namespace llvm
+
+#endif
index 2dc23f8..68d9d30 100644 (file)
@@ -32,6 +32,7 @@ namespace pdb {
 class DbiStreamBuilder;
 class InfoStreamBuilder;
 class PublicsStreamBuilder;
+class GlobalsStreamBuilder;
 class TpiStreamBuilder;
 
 class PDBFileBuilder {
@@ -50,6 +51,7 @@ public:
   TpiStreamBuilder &getIpiBuilder();
   PDBStringTableBuilder &getStringTableBuilder();
   PublicsStreamBuilder &getPublicsBuilder();
+  GlobalsStreamBuilder &getGlobalsBuilder();
 
   Error commit(StringRef Filename);
 
@@ -64,6 +66,7 @@ private:
   std::unique_ptr<msf::MSFBuilder> Msf;
   std::unique_ptr<InfoStreamBuilder> Info;
   std::unique_ptr<DbiStreamBuilder> Dbi;
+  std::unique_ptr<GlobalsStreamBuilder> Globals;
   std::unique_ptr<PublicsStreamBuilder> Publics;
   std::unique_ptr<TpiStreamBuilder> Tpi;
   std::unique_ptr<TpiStreamBuilder> Ipi;
index 5840ab1..2658584 100644 (file)
@@ -35,6 +35,7 @@ add_pdb_impl_folder(Native
   Native/DbiStreamBuilder.cpp
   Native/EnumTables.cpp
   Native/GlobalsStream.cpp
+  Native/GlobalsStreamBuilder.cpp
   Native/Hash.cpp
   Native/HashTable.cpp
   Native/InfoStream.cpp
index 25076e4..0fe583b 100644 (file)
@@ -49,6 +49,10 @@ void DbiStreamBuilder::setSectionMap(ArrayRef<SecMapEntry> SecMap) {
   SectionMap = SecMap;
 }
 
+void DbiStreamBuilder::setGlobalsStreamIndex(uint32_t Index) {
+  GlobalsStreamIndex = Index;
+}
+
 void DbiStreamBuilder::setSymbolRecordStreamIndex(uint32_t Index) {
   SymRecordStreamIndex = Index;
 }
@@ -270,7 +274,7 @@ Error DbiStreamBuilder::finalize() {
   H->SymRecordStreamIndex = SymRecordStreamIndex;
   H->PublicSymbolStreamIndex = PublicsStreamIndex;
   H->MFCTypeServerIndex = kInvalidStreamIndex;
-  H->GlobalSymbolStreamIndex = kInvalidStreamIndex;
+  H->GlobalSymbolStreamIndex = GlobalsStreamIndex;
 
   Header = H;
   return Error::success();
diff --git a/lib/DebugInfo/PDB/Native/GlobalsStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/GlobalsStreamBuilder.cpp
new file mode 100644 (file)
index 0000000..004691e
--- /dev/null
@@ -0,0 +1,79 @@
+//===- GlobalsStreamBuilder.cpp - PDB Globals Stream Creation ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/GlobalsStreamBuilder.h"
+
+#include "llvm/DebugInfo/MSF/MSFBuilder.h"
+#include "llvm/DebugInfo/MSF/MSFCommon.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+GlobalsStreamBuilder::GlobalsStreamBuilder(msf::MSFBuilder &Msf) : Msf(Msf) {}
+
+GlobalsStreamBuilder::~GlobalsStreamBuilder() {}
+
+uint32_t GlobalsStreamBuilder::calculateSerializedLength() const {
+  uint32_t Size = 0;
+  // First is the header
+  Size += sizeof(GSIHashHeader);
+
+  // Next is the records.  For now we don't write any records, just an empty
+  // stream.
+  // FIXME: Write records and account for their size here.
+  Size += 0;
+
+  // Next is a bitmap indicating which hash buckets are valid.  The bitmap
+  // is alway present, but we only write buckets for bitmap entries which are
+  // non-zero, which now is noting.
+  size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32);
+  uint32_t NumBitmapEntries = BitmapSizeInBits / 8;
+  Size += NumBitmapEntries;
+
+  // FIXME: Account for hash buckets.  For now since we we write a zero-bitmap
+  // indicating that no hash buckets are valid, we also write zero byets of hash
+  // bucket data.
+  Size += 0;
+  return Size;
+}
+
+Error GlobalsStreamBuilder::finalizeMsfLayout() {
+  Expected<uint32_t> Idx = Msf.addStream(calculateSerializedLength());
+  if (!Idx)
+    return Idx.takeError();
+  StreamIdx = *Idx;
+  return Error::success();
+}
+
+Error GlobalsStreamBuilder::commit(BinaryStreamWriter &PublicsWriter) {
+  GSIHashHeader GSH;
+
+  GSH.VerSignature = GSIHashHeader::HdrSignature;
+  GSH.VerHdr = GSIHashHeader::HdrVersion;
+  GSH.HrSize = 0;
+  GSH.NumBuckets = 0;
+
+  if (auto EC = PublicsWriter.writeObject(GSH))
+    return EC;
+
+  // FIXME: Once we start writing a value other than 0 for GSH.HrSize, we need
+  // to write the hash records here.
+  size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32);
+  uint32_t NumBitmapEntries = BitmapSizeInBits / 8;
+  std::vector<uint8_t> BitmapData(NumBitmapEntries);
+  // FIXME: Build an actual bitmap
+  if (auto EC = PublicsWriter.writeBytes(makeArrayRef(BitmapData)))
+    return EC;
+
+  // FIXME: Write actual hash buckets.
+  return Error::success();
+}
index 21e5e4b..a8b80ac 100644 (file)
@@ -15,6 +15,7 @@
 #include "llvm/DebugInfo/PDB/GenericError.h"
 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
 #include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/GlobalsStreamBuilder.h"
 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
 #include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
 #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
@@ -80,6 +81,12 @@ PublicsStreamBuilder &PDBFileBuilder::getPublicsBuilder() {
   return *Publics;
 }
 
+GlobalsStreamBuilder &PDBFileBuilder::getGlobalsBuilder() {
+  if (!Globals)
+    Globals = llvm::make_unique<GlobalsStreamBuilder>(*Msf);
+  return *Globals;
+}
+
 Error PDBFileBuilder::addNamedStream(StringRef Name, uint32_t Size) {
   auto ExpectedStream = Msf->addStream(Size);
   if (!ExpectedStream)
@@ -131,6 +138,13 @@ Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() {
     }
   }
 
+  if (Globals) {
+    if (auto EC = Globals->finalizeMsfLayout())
+      return std::move(EC);
+    if (Dbi)
+      Dbi->setGlobalsStreamIndex(Globals->getStreamIndex());
+  }
+
   return Msf->build();
 }
 
@@ -220,5 +234,13 @@ Error PDBFileBuilder::commit(StringRef Filename) {
       return EC;
   }
 
+  if (Globals) {
+    auto GS = WritableMappedBlockStream::createIndexedStream(
+        Layout, Buffer, Globals->getStreamIndex(), Allocator);
+    BinaryStreamWriter GSWriter(*GS);
+    if (auto EC = Globals->commit(GSWriter))
+      return EC;
+  }
+
   return Buffer.commit();
 }