]> granicus.if.org Git - llvm/commitdiff
[lld/pdb] Create an empty public symbol record stream.
authorZachary Turner <zturner@google.com>
Mon, 10 Jul 2017 22:40:20 +0000 (22:40 +0000)
committerZachary Turner <zturner@google.com>
Mon, 10 Jul 2017 22:40:20 +0000 (22:40 +0000)
This is part of the continuing effort to increase parity between
LLD and MSVC PDBs.  link still doesn't like our PDBs, so the most
obvious thing to check was whether adding an empty publics stream
would get it to do something else.  It still fails in the same way
but at least this removes one more variable from the equation.
The next logical step would be to try creating an empty globals
stream.

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

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

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

index 7d676e87ecd7780ff687816ab2e9ab2fd67b52d3..63eb34f0326afa1f67ae0a8d81c787fe87c0fccf 100644 (file)
@@ -59,6 +59,9 @@ public:
 
   uint32_t calculateSerializedLength() const;
 
+  void setPublicsStreamIndex(uint32_t Index);
+  void setSymbolRecordStreamIndex(uint32_t Index);
+
   Expected<DbiModuleDescriptorBuilder &> addModuleInfo(StringRef ModuleName);
   Error addModuleSourceFile(StringRef Module, StringRef File);
   Error addModuleSourceFile(DbiModuleDescriptorBuilder &Module, StringRef File);
@@ -90,7 +93,6 @@ private:
   uint32_t calculateNamesBufferSize() const;
   uint32_t calculateDbgStreamsSize() const;
 
-  Error generateModiSubstream();
   Error generateFileInfoSubstream();
 
   msf::MSFBuilder &Msf;
@@ -103,6 +105,8 @@ private:
   uint16_t PdbDllRbld;
   uint16_t Flags;
   PDB_Machine MachineType;
+  uint32_t PublicsStreamIndex = kInvalidStreamIndex;
+  uint32_t SymRecordStreamIndex = kInvalidStreamIndex;
 
   const DbiStreamHeader *Header;
 
index cd7d3b0637933656f461f1732357b4570b185d3a..2dc23f819d3bd065c9668b7f991496a67c2c2e7c 100644 (file)
@@ -31,11 +31,13 @@ class MSFBuilder;
 namespace pdb {
 class DbiStreamBuilder;
 class InfoStreamBuilder;
+class PublicsStreamBuilder;
 class TpiStreamBuilder;
 
 class PDBFileBuilder {
 public:
   explicit PDBFileBuilder(BumpPtrAllocator &Allocator);
+  ~PDBFileBuilder();
   PDBFileBuilder(const PDBFileBuilder &) = delete;
   PDBFileBuilder &operator=(const PDBFileBuilder &) = delete;
 
@@ -47,6 +49,7 @@ public:
   TpiStreamBuilder &getTpiBuilder();
   TpiStreamBuilder &getIpiBuilder();
   PDBStringTableBuilder &getStringTableBuilder();
+  PublicsStreamBuilder &getPublicsBuilder();
 
   Error commit(StringRef Filename);
 
@@ -61,6 +64,7 @@ private:
   std::unique_ptr<msf::MSFBuilder> Msf;
   std::unique_ptr<InfoStreamBuilder> Info;
   std::unique_ptr<DbiStreamBuilder> Dbi;
+  std::unique_ptr<PublicsStreamBuilder> Publics;
   std::unique_ptr<TpiStreamBuilder> Tpi;
   std::unique_ptr<TpiStreamBuilder> Ipi;
 
index 4570c80c76d7c33318565fd6fd41002c7022c4f5..9ace826bd8f71e114616cc52a87626e6f0437300 100644 (file)
@@ -25,8 +25,6 @@ struct GSIHashHeader;
 class PDBFile;
 
 class PublicsStream {
-  struct HeaderInfo;
-
 public:
   PublicsStream(PDBFile &File, std::unique_ptr<msf::MappedBlockStream> Stream);
   ~PublicsStream();
@@ -65,7 +63,7 @@ private:
   FixedStreamArray<support::ulittle32_t> ThunkMap;
   FixedStreamArray<SectionOffset> SectionOffsets;
 
-  const HeaderInfo *Header;
+  const PublicsStreamHeader *Header;
   const GSIHashHeader *HashHdr;
 };
 }
diff --git a/include/llvm/DebugInfo/PDB/Native/PublicsStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/PublicsStreamBuilder.h
new file mode 100644 (file)
index 0000000..5ab57eb
--- /dev/null
@@ -0,0 +1,54 @@
+//===- PublicsStreamBuilder.h - PDB Publics 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_PDBPUBLICSTREAMBUILDER_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBPUBLICSTREAMBUILDER_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 PublicsStream;
+struct PublicsStreamHeader;
+
+class PublicsStreamBuilder {
+public:
+  explicit PublicsStreamBuilder(msf::MSFBuilder &Msf);
+  ~PublicsStreamBuilder();
+
+  PublicsStreamBuilder(const PublicsStreamBuilder &) = delete;
+  PublicsStreamBuilder &operator=(const PublicsStreamBuilder &) = delete;
+
+  Error finalizeMsfLayout();
+  uint32_t calculateSerializedLength() const;
+
+  Error commit(BinaryStreamWriter &PublicsWriter);
+
+  uint32_t getStreamIndex() const { return StreamIdx; }
+  uint32_t getRecordStreamIdx() const { return RecordStreamIdx; }
+
+private:
+  uint32_t StreamIdx = kInvalidStreamIndex;
+  uint32_t RecordStreamIdx = kInvalidStreamIndex;
+  std::vector<PSHashRecord> HashRecords;
+  msf::MSFBuilder &Msf;
+};
+} // namespace pdb
+} // namespace llvm
+
+#endif
index 771272d6a47d1d0862a326fb1099a1ca6c02ba40..a3cdd3f09a44e758cc3b535f1389edff76c33cb0 100644 (file)
@@ -255,6 +255,19 @@ struct ModuleInfoHeader {
   /// char ObjFileName[];
 };
 
+// This is PSGSIHDR struct defined in
+// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
+struct PublicsStreamHeader {
+  support::ulittle32_t SymHash;
+  support::ulittle32_t AddrMap;
+  support::ulittle32_t NumThunks;
+  support::ulittle32_t SizeOfThunk;
+  support::ulittle16_t ISectThunkTable;
+  char Padding[2];
+  support::ulittle32_t OffThunkTable;
+  support::ulittle32_t NumSections;
+};
+
 /// Defines a 128-bit unique identifier.  This maps to a GUID on Windows, but
 /// is abstracted here for the purposes of non-Windows platforms that don't have
 /// the GUID structure defined.
index e9fd29ccc4caf373ac43384440a3c73cbd133ff7..524fdf1dee5c089be67336d147860a50f7a54582 100644 (file)
@@ -53,6 +53,7 @@ add_pdb_impl_folder(Native
   Native/PDBStringTableBuilder.cpp
   Native/PDBTypeServerHandler.cpp
   Native/PublicsStream.cpp
+  Native/PublicsStreamBuilder.cpp
   Native/RawError.cpp
   Native/SymbolStream.cpp
   Native/TpiHashing.cpp
index e49a77b4fcec09ea4955eed7b65f2ee7806ec50b..25076e40fc98c1ab6f1d2615d62100c2fcec9c1e 100644 (file)
@@ -49,6 +49,14 @@ void DbiStreamBuilder::setSectionMap(ArrayRef<SecMapEntry> SecMap) {
   SectionMap = SecMap;
 }
 
+void DbiStreamBuilder::setSymbolRecordStreamIndex(uint32_t Index) {
+  SymRecordStreamIndex = Index;
+}
+
+void DbiStreamBuilder::setPublicsStreamIndex(uint32_t Index) {
+  PublicsStreamIndex = Index;
+}
+
 Error DbiStreamBuilder::addDbgStream(pdb::DbgHeaderType Type,
                                      ArrayRef<uint8_t> Data) {
   if (DbgStreams[(int)Type].StreamNumber != kInvalidStreamIndex)
@@ -259,8 +267,8 @@ Error DbiStreamBuilder::finalize() {
   H->SecContrSubstreamSize = calculateSectionContribsStreamSize();
   H->SectionMapSize = calculateSectionMapStreamSize();
   H->TypeServerSize = 0;
-  H->SymRecordStreamIndex = kInvalidStreamIndex;
-  H->PublicSymbolStreamIndex = kInvalidStreamIndex;
+  H->SymRecordStreamIndex = SymRecordStreamIndex;
+  H->PublicSymbolStreamIndex = PublicsStreamIndex;
   H->MFCTypeServerIndex = kInvalidStreamIndex;
   H->GlobalSymbolStreamIndex = kInvalidStreamIndex;
 
index e8ec96ecafe392e60a65036d26717f460dc47388..9f35fd73629cdccf90d095b594ab5d0412b74660 100644 (file)
@@ -18,6 +18,7 @@
 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
 #include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
 #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/PublicsStreamBuilder.h"
 #include "llvm/DebugInfo/PDB/Native/RawError.h"
 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
 #include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
@@ -33,6 +34,8 @@ using namespace llvm::support;
 PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator)
     : Allocator(Allocator) {}
 
+PDBFileBuilder::~PDBFileBuilder() {}
+
 Error PDBFileBuilder::initialize(uint32_t BlockSize) {
   auto ExpectedMsf = MSFBuilder::create(Allocator, BlockSize);
   if (!ExpectedMsf)
@@ -71,6 +74,12 @@ PDBStringTableBuilder &PDBFileBuilder::getStringTableBuilder() {
   return Strings;
 }
 
+PublicsStreamBuilder &PDBFileBuilder::getPublicsBuilder() {
+  if (!Publics)
+    Publics = llvm::make_unique<PublicsStreamBuilder>(*Msf);
+  return *Publics;
+}
+
 Error PDBFileBuilder::addNamedStream(StringRef Name, uint32_t Size) {
   auto ExpectedStream = Msf->addStream(Size);
   if (!ExpectedStream)
@@ -113,6 +122,14 @@ Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() {
     if (auto EC = Ipi->finalizeMsfLayout())
       return std::move(EC);
   }
+  if (Publics) {
+    if (auto EC = Publics->finalizeMsfLayout())
+      return std::move(EC);
+    if (Dbi) {
+      Dbi->setPublicsStreamIndex(Publics->getStreamIndex());
+      Dbi->setSymbolRecordStreamIndex(Publics->getRecordStreamIdx());
+    }
+  }
 
   return Msf->build();
 }
@@ -192,5 +209,13 @@ Error PDBFileBuilder::commit(StringRef Filename) {
       return EC;
   }
 
+  if (Publics) {
+    auto PS = WritableMappedBlockStream::createIndexedStream(
+        Layout, Buffer, Publics->getStreamIndex(), Allocator);
+    BinaryStreamWriter PSWriter(*PS);
+    if (auto EC = Publics->commit(PSWriter))
+      return EC;
+  }
+
   return Buffer.commit();
 }
index 8f3474b9ce1906687916795fcfe695501d02e0ad..9c3e654f808ba283d0b468020a3f6dce9f8378c7 100644 (file)
@@ -41,19 +41,6 @@ using namespace llvm::msf;
 using namespace llvm::support;
 using namespace llvm::pdb;
 
-// This is PSGSIHDR struct defined in
-// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
-struct PublicsStream::HeaderInfo {
-  ulittle32_t SymHash;
-  ulittle32_t AddrMap;
-  ulittle32_t NumThunks;
-  ulittle32_t SizeOfThunk;
-  ulittle16_t ISectThunkTable;
-  char Padding[2];
-  ulittle32_t OffThunkTable;
-  ulittle32_t NumSections;
-};
-
 PublicsStream::PublicsStream(PDBFile &File,
                              std::unique_ptr<MappedBlockStream> Stream)
     : Pdb(File), Stream(std::move(Stream)) {}
@@ -72,7 +59,8 @@ Error PublicsStream::reload() {
   BinaryStreamReader Reader(*Stream);
 
   // Check stream size.
-  if (Reader.bytesRemaining() < sizeof(HeaderInfo) + sizeof(GSIHashHeader))
+  if (Reader.bytesRemaining() <
+      sizeof(PublicsStreamHeader) + sizeof(GSIHashHeader))
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "Publics Stream does not contain a header.");
 
diff --git a/lib/DebugInfo/PDB/Native/PublicsStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/PublicsStreamBuilder.cpp
new file mode 100644 (file)
index 0000000..28c4a8f
--- /dev/null
@@ -0,0 +1,89 @@
+//===- DbiStreamBuilder.cpp - PDB Dbi 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/PublicsStreamBuilder.h"
+
+#include "llvm/DebugInfo/MSF/MSFBuilder.h"
+#include "llvm/DebugInfo/MSF/MSFCommon.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+
+#include "GSI.h"
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+PublicsStreamBuilder::PublicsStreamBuilder(msf::MSFBuilder &Msf) : Msf(Msf) {}
+
+PublicsStreamBuilder::~PublicsStreamBuilder() {}
+
+uint32_t PublicsStreamBuilder::calculateSerializedLength() const {
+  uint32_t Size = 0;
+  Size += sizeof(PublicsStreamHeader);
+  Size += sizeof(GSIHashHeader);
+  Size += HashRecords.size() * sizeof(PSHashRecord);
+  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 PublicsStreamBuilder::finalizeMsfLayout() {
+  Expected<uint32_t> Idx = Msf.addStream(calculateSerializedLength());
+  if (!Idx)
+    return Idx.takeError();
+  StreamIdx = *Idx;
+
+  Expected<uint32_t> RecordIdx = Msf.addStream(0);
+  if (!RecordIdx)
+    return RecordIdx.takeError();
+  RecordStreamIdx = *RecordIdx;
+  return Error::success();
+}
+
+Error PublicsStreamBuilder::commit(BinaryStreamWriter &PublicsWriter) {
+  PublicsStreamHeader PSH;
+  GSIHashHeader GSH;
+
+  // FIXME: Figure out what to put for these values.
+  PSH.AddrMap = 0;
+  PSH.ISectThunkTable = 0;
+  PSH.NumSections = 0;
+  PSH.NumThunks = 0;
+  PSH.OffThunkTable = 0;
+  PSH.SizeOfThunk = 0;
+  PSH.SymHash = 0;
+
+  GSH.VerSignature = GSIHashHeader::HdrSignature;
+  GSH.VerHdr = GSIHashHeader::HdrVersion;
+  GSH.HrSize = 0;
+  GSH.NumBuckets = 0;
+
+  if (auto EC = PublicsWriter.writeObject(PSH))
+    return EC;
+  if (auto EC = PublicsWriter.writeObject(GSH))
+    return EC;
+  if (auto EC = PublicsWriter.writeArray(makeArrayRef(HashRecords)))
+    return EC;
+
+  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();
+}