[llvm] r342333 - Give InfoStreamBuilder an opt-in method to write a hash of the PDB as GUID.

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 15 11:35:52 PDT 2018


Author: nico
Date: Sat Sep 15 11:35:51 2018
New Revision: 342333

URL: http://llvm.org/viewvc/llvm-project?rev=342333&view=rev
Log:
Give InfoStreamBuilder an opt-in method to write a hash of the PDB as GUID.

Naively computing the hash after the PDB data has been generated is in practice
as fast as other approaches I tried. I also tried online-computing the hash as
parts of the PDB were written out (https://reviews.llvm.org/D51887; that's also
where all the measuring data is) and computing the hash in parallel
(https://reviews.llvm.org/D51957). This approach here is simplest, without
being slower.

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

Modified:
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
    llvm/trunk/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
    llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h?rev=342333&r1=342332&r2=342333&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h Sat Sep 15 11:35:51 2018
@@ -35,11 +35,18 @@ public:
   InfoStreamBuilder &operator=(const InfoStreamBuilder &) = delete;
 
   void setVersion(PdbRaw_ImplVer V);
+  void addFeature(PdbRaw_FeatureSig Sig);
+
+  // If this is true, the PDB contents are hashed and this hash is used as
+  // PDB GUID and as Signature. The age is always 1.
+  void setHashPDBContentsToGUID(bool B);
+
+  // These only have an effect if hashPDBContentsToGUID() is false.
   void setSignature(uint32_t S);
   void setAge(uint32_t A);
   void setGuid(codeview::GUID G);
-  void addFeature(PdbRaw_FeatureSig Sig);
 
+  bool hashPDBContentsToGUID() const { return HashPDBContentsToGUID; }
   uint32_t getAge() const { return Age; }
   codeview::GUID getGuid() const { return Guid; }
   Optional<uint32_t> getSignature() const { return Signature; }
@@ -60,6 +67,8 @@ private:
   Optional<uint32_t> Signature;
   codeview::GUID Guid;
 
+  bool HashPDBContentsToGUID = false;
+
   NamedStreamMap &NamedStreams;
 };
 }

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h?rev=342333&r1=342332&r2=342333&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h Sat Sep 15 11:35:51 2018
@@ -53,7 +53,9 @@ public:
   PDBStringTableBuilder &getStringTableBuilder();
   GSIStreamBuilder &getGsiBuilder();
 
-  Error commit(StringRef Filename);
+  // If HashPDBContentsToGUID is true on the InfoStreamBuilder, Guid is filled
+  // with the computed PDB GUID on return.
+  Error commit(StringRef Filename, codeview::GUID *Guid);
 
   Expected<uint32_t> getNamedStreamIndex(StringRef Name) const;
   Error addNamedStream(StringRef Name, StringRef Data);

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp?rev=342333&r1=342332&r2=342333&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp Sat Sep 15 11:35:51 2018
@@ -32,15 +32,20 @@ InfoStreamBuilder::InfoStreamBuilder(msf
 
 void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; }
 
+void InfoStreamBuilder::addFeature(PdbRaw_FeatureSig Sig) {
+  Features.push_back(Sig);
+}
+
+void InfoStreamBuilder::setHashPDBContentsToGUID(bool B) {
+  HashPDBContentsToGUID = B;
+}
+
 void InfoStreamBuilder::setAge(uint32_t A) { Age = A; }
 
 void InfoStreamBuilder::setSignature(uint32_t S) { Signature = S; }
 
 void InfoStreamBuilder::setGuid(GUID G) { Guid = G; }
 
-void InfoStreamBuilder::addFeature(PdbRaw_FeatureSig Sig) {
-  Features.push_back(Sig);
-}
 
 Error InfoStreamBuilder::finalizeMsfLayout() {
   uint32_t Length = sizeof(InfoStreamHeader) +

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp?rev=342333&r1=342332&r2=342333&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp Sat Sep 15 11:35:51 2018
@@ -25,6 +25,7 @@
 #include "llvm/Support/BinaryStreamWriter.h"
 #include "llvm/Support/JamCRC.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/xxhash.h"
 
 using namespace llvm;
 using namespace llvm::codeview;
@@ -261,13 +262,14 @@ void PDBFileBuilder::commitInjectedSourc
   }
 }
 
-Error PDBFileBuilder::commit(StringRef Filename) {
+Error PDBFileBuilder::commit(StringRef Filename, codeview::GUID *Guid) {
   assert(!Filename.empty());
   if (auto EC = finalizeMsfLayout())
     return EC;
 
   MSFLayout Layout;
-  auto ExpectedMsfBuffer = Msf->commit(Filename, Layout);
+  Expected<FileBufferByteStream> ExpectedMsfBuffer =
+      Msf->commit(Filename, Layout);
   if (!ExpectedMsfBuffer)
     return ExpectedMsfBuffer.takeError();
   FileBufferByteStream Buffer = std::move(*ExpectedMsfBuffer);
@@ -329,11 +331,28 @@ Error PDBFileBuilder::commit(StringRef F
 
   // Set the build id at the very end, after every other byte of the PDB
   // has been written.
-  // FIXME: Use a hash of the PDB rather than time(nullptr) for the signature.
-  H->Age = Info->getAge();
-  H->Guid = Info->getGuid();
-  Optional<uint32_t> Sig = Info->getSignature();
-  H->Signature = Sig.hasValue() ? *Sig : time(nullptr);
+  if (Info->hashPDBContentsToGUID()) {
+    // Compute a hash of all sections of the output file.
+    uint64_t Digest =
+        xxHash64({Buffer.getBufferStart(), Buffer.getBufferEnd()});
+
+    H->Age = 1;
+
+    memcpy(H->Guid.Guid, &Digest, 8);
+    // xxhash only gives us 8 bytes, so put some fixed data in the other half.
+    memcpy(H->Guid.Guid + 8, "LLD PDB.", 8);
+
+    // Put the hash in the Signature field too.
+    H->Signature = static_cast<uint32_t>(Digest);
+
+    // Return GUID to caller.
+    memcpy(Guid, H->Guid.Guid, 16);
+  } else {
+    H->Age = Info->getAge();
+    H->Guid = Info->getGuid();
+    Optional<uint32_t> Sig = Info->getSignature();
+    H->Signature = Sig.hasValue() ? *Sig : time(nullptr);
+  }
 
   return Buffer.commit();
 }

Modified: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp?rev=342333&r1=342332&r2=342333&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp Sat Sep 15 11:35:51 2018
@@ -803,7 +803,8 @@ static void yamlToPdb(StringRef Path) {
 
   Builder.getStringTableBuilder().setStrings(*Strings.strings());
 
-  ExitOnErr(Builder.commit(opts::yaml2pdb::YamlPdbOutputFile));
+  codeview::GUID IgnoredOutGuid;
+  ExitOnErr(Builder.commit(opts::yaml2pdb::YamlPdbOutputFile, &IgnoredOutGuid));
 }
 
 static PDBFile &loadPDB(StringRef Path, std::unique_ptr<IPDBSession> &Session) {
@@ -1263,7 +1264,9 @@ static void mergePdbs() {
     OutFile = opts::merge::InputFilenames[0];
     llvm::sys::path::replace_extension(OutFile, "merged.pdb");
   }
-  ExitOnErr(Builder.commit(OutFile));
+
+  codeview::GUID IgnoredOutGuid;
+  ExitOnErr(Builder.commit(OutFile, &IgnoredOutGuid));
 }
 
 static void explain() {




More information about the llvm-commits mailing list