llvm.org GIT mirror llvm / 23d6890
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342333 91177308-0d34-0410-b5e6-96231b3b80d8 Nico Weber a year ago
5 changed file(s) with 52 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
3434 InfoStreamBuilder &operator=(const InfoStreamBuilder &) = delete;
3535
3636 void setVersion(PdbRaw_ImplVer V);
37 void addFeature(PdbRaw_FeatureSig Sig);
38
39 // If this is true, the PDB contents are hashed and this hash is used as
40 // PDB GUID and as Signature. The age is always 1.
41 void setHashPDBContentsToGUID(bool B);
42
43 // These only have an effect if hashPDBContentsToGUID() is false.
3744 void setSignature(uint32_t S);
3845 void setAge(uint32_t A);
3946 void setGuid(codeview::GUID G);
40 void addFeature(PdbRaw_FeatureSig Sig);
4147
48 bool hashPDBContentsToGUID() const { return HashPDBContentsToGUID; }
4249 uint32_t getAge() const { return Age; }
4350 codeview::GUID getGuid() const { return Guid; }
4451 Optional getSignature() const { return Signature; }
5966 Optional Signature;
6067 codeview::GUID Guid;
6168
69 bool HashPDBContentsToGUID = false;
70
6271 NamedStreamMap &NamedStreams;
6372 };
6473 }
5252 PDBStringTableBuilder &getStringTableBuilder();
5353 GSIStreamBuilder &getGsiBuilder();
5454
55 Error commit(StringRef Filename);
55 // If HashPDBContentsToGUID is true on the InfoStreamBuilder, Guid is filled
56 // with the computed PDB GUID on return.
57 Error commit(StringRef Filename, codeview::GUID *Guid);
5658
5759 Expected getNamedStreamIndex(StringRef Name) const;
5860 Error addNamedStream(StringRef Name, StringRef Data);
3131
3232 void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; }
3333
34 void InfoStreamBuilder::addFeature(PdbRaw_FeatureSig Sig) {
35 Features.push_back(Sig);
36 }
37
38 void InfoStreamBuilder::setHashPDBContentsToGUID(bool B) {
39 HashPDBContentsToGUID = B;
40 }
41
3442 void InfoStreamBuilder::setAge(uint32_t A) { Age = A; }
3543
3644 void InfoStreamBuilder::setSignature(uint32_t S) { Signature = S; }
3745
3846 void InfoStreamBuilder::setGuid(GUID G) { Guid = G; }
3947
40 void InfoStreamBuilder::addFeature(PdbRaw_FeatureSig Sig) {
41 Features.push_back(Sig);
42 }
4348
4449 Error InfoStreamBuilder::finalizeMsfLayout() {
4550 uint32_t Length = sizeof(InfoStreamHeader) +
2424 #include "llvm/Support/BinaryStreamWriter.h"
2525 #include "llvm/Support/JamCRC.h"
2626 #include "llvm/Support/Path.h"
27 #include "llvm/Support/xxhash.h"
2728
2829 using namespace llvm;
2930 using namespace llvm::codeview;
260261 }
261262 }
262263
263 Error PDBFileBuilder::commit(StringRef Filename) {
264 Error PDBFileBuilder::commit(StringRef Filename, codeview::GUID *Guid) {
264265 assert(!Filename.empty());
265266 if (auto EC = finalizeMsfLayout())
266267 return EC;
267268
268269 MSFLayout Layout;
269 auto ExpectedMsfBuffer = Msf->commit(Filename, Layout);
270 Expected ExpectedMsfBuffer =
271 Msf->commit(Filename, Layout);
270272 if (!ExpectedMsfBuffer)
271273 return ExpectedMsfBuffer.takeError();
272274 FileBufferByteStream Buffer = std::move(*ExpectedMsfBuffer);
328330
329331 // Set the build id at the very end, after every other byte of the PDB
330332 // has been written.
331 // FIXME: Use a hash of the PDB rather than time(nullptr) for the signature.
332 H->Age = Info->getAge();
333 H->Guid = Info->getGuid();
334 Optional Sig = Info->getSignature();
335 H->Signature = Sig.hasValue() ? *Sig : time(nullptr);
333 if (Info->hashPDBContentsToGUID()) {
334 // Compute a hash of all sections of the output file.
335 uint64_t Digest =
336 xxHash64({Buffer.getBufferStart(), Buffer.getBufferEnd()});
337
338 H->Age = 1;
339
340 memcpy(H->Guid.Guid, &Digest, 8);
341 // xxhash only gives us 8 bytes, so put some fixed data in the other half.
342 memcpy(H->Guid.Guid + 8, "LLD PDB.", 8);
343
344 // Put the hash in the Signature field too.
345 H->Signature = static_cast(Digest);
346
347 // Return GUID to caller.
348 memcpy(Guid, H->Guid.Guid, 16);
349 } else {
350 H->Age = Info->getAge();
351 H->Guid = Info->getGuid();
352 Optional Sig = Info->getSignature();
353 H->Signature = Sig.hasValue() ? *Sig : time(nullptr);
354 }
336355
337356 return Buffer.commit();
338357 }
802802
803803 Builder.getStringTableBuilder().setStrings(*Strings.strings());
804804
805 ExitOnErr(Builder.commit(opts::yaml2pdb::YamlPdbOutputFile));
805 codeview::GUID IgnoredOutGuid;
806 ExitOnErr(Builder.commit(opts::yaml2pdb::YamlPdbOutputFile, &IgnoredOutGuid));
806807 }
807808
808809 static PDBFile &loadPDB(StringRef Path, std::unique_ptr &Session) {
12621263 OutFile = opts::merge::InputFilenames[0];
12631264 llvm::sys::path::replace_extension(OutFile, "merged.pdb");
12641265 }
1265 ExitOnErr(Builder.commit(OutFile));
1266
1267 codeview::GUID IgnoredOutGuid;
1268 ExitOnErr(Builder.commit(OutFile, &IgnoredOutGuid));
12661269 }
12671270
12681271 static void explain() {