mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
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 llvm-svn: 342333
This commit is contained in:
parent
c2ace82589
commit
26d9f839bc
@ -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;
|
||||
};
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -32,15 +32,20 @@ InfoStreamBuilder::InfoStreamBuilder(msf::MSFBuilder &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) +
|
||||
|
@ -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::commitInjectedSources(WritableBinaryStream &MsfBuffer,
|
||||
}
|
||||
}
|
||||
|
||||
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 Filename) {
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
@ -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() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user