diff options
| author | Zachary Turner <zturner@google.com> | 2016-09-14 23:00:02 +0000 |
|---|---|---|
| committer | Zachary Turner <zturner@google.com> | 2016-09-14 23:00:02 +0000 |
| commit | 620961deb9bc4c0415d56bed9b2fe20391bd2ad2 (patch) | |
| tree | c313b23899ec22d2871cedecf1b65b93905cfa3b /llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp | |
| parent | 31263731da2214579540198ae96c0990b315d0ed (diff) | |
| download | bcm5719-llvm-620961deb9bc4c0415d56bed9b2fe20391bd2ad2.tar.gz bcm5719-llvm-620961deb9bc4c0415d56bed9b2fe20391bd2ad2.zip | |
[pdb] Write TPI hash values to the TPI stream.
This completes being able to write all the interesting
values of a PDB TPI stream.
Reviewed By: rnk
Differential Revision: https://reviews.llvm.org/D24370
llvm-svn: 281555
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp')
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp | 96 |
1 files changed, 4 insertions, 92 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp index 5560643c864..fc5e7ce5a83 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp @@ -17,11 +17,11 @@ #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/MSF/StreamReader.h" -#include "llvm/DebugInfo/PDB/Raw/Hash.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" #include "llvm/DebugInfo/PDB/Raw/RawConstants.h" #include "llvm/DebugInfo/PDB/Raw/RawError.h" #include "llvm/DebugInfo/PDB/Raw/RawTypes.h" +#include "llvm/DebugInfo/PDB/Raw/TpiHashing.h" #include "llvm/Support/Endian.h" @@ -37,97 +37,6 @@ TpiStream::TpiStream(const PDBFile &File, TpiStream::~TpiStream() {} -// Corresponds to `fUDTAnon`. -template <typename T> static bool isAnonymous(T &Rec) { - StringRef Name = Rec.getName(); - return Name == "<unnamed-tag>" || Name == "__unnamed" || - Name.endswith("::<unnamed-tag>") || Name.endswith("::__unnamed"); -} - -// Computes a hash for a given TPI record. -template <typename T> -static uint32_t getTpiHash(T &Rec, const CVRecord<TypeLeafKind> &RawRec) { - auto Opts = static_cast<uint16_t>(Rec.getOptions()); - - bool ForwardRef = - Opts & static_cast<uint16_t>(ClassOptions::ForwardReference); - bool Scoped = Opts & static_cast<uint16_t>(ClassOptions::Scoped); - bool UniqueName = Opts & static_cast<uint16_t>(ClassOptions::HasUniqueName); - bool IsAnon = UniqueName && isAnonymous(Rec); - - if (!ForwardRef && !Scoped && !IsAnon) - return hashStringV1(Rec.getName()); - if (!ForwardRef && UniqueName && !IsAnon) - return hashStringV1(Rec.getUniqueName()); - return hashBufferV8(RawRec.RawData); -} - -namespace { -class TpiHashVerifier : public TypeVisitorCallbacks { -public: - TpiHashVerifier(FixedStreamArray<support::ulittle32_t> &HashValues, - uint32_t NumHashBuckets) - : HashValues(HashValues), NumHashBuckets(NumHashBuckets) {} - - Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, - UdtSourceLineRecord &Rec) override { - return verifySourceLine(Rec); - } - - Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, - UdtModSourceLineRecord &Rec) override { - return verifySourceLine(Rec); - } - - Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, - ClassRecord &Rec) override { - return verify(Rec); - } - Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, - EnumRecord &Rec) override { - return verify(Rec); - } - Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, - UnionRecord &Rec) override { - return verify(Rec); - } - - Error visitTypeBegin(CVRecord<TypeLeafKind> &Rec) override { - ++Index; - RawRecord = Rec; - return Error::success(); - } - -private: - template <typename T> Error verify(T &Rec) { - uint32_t Hash = getTpiHash(Rec, RawRecord); - if (Hash % NumHashBuckets != HashValues[Index]) - return errorInvalidHash(); - return Error::success(); - } - - template <typename T> Error verifySourceLine(T &Rec) { - char Buf[4]; - support::endian::write32le(Buf, Rec.getUDT().getIndex()); - uint32_t Hash = hashStringV1(StringRef(Buf, 4)); - if (Hash % NumHashBuckets != HashValues[Index]) - return errorInvalidHash(); - return Error::success(); - } - - Error errorInvalidHash() { - return make_error<RawError>( - raw_error_code::invalid_tpi_hash, - "Type index is 0x" + utohexstr(TypeIndex::FirstNonSimpleIndex + Index)); - } - - FixedStreamArray<support::ulittle32_t> HashValues; - CVRecord<TypeLeafKind> RawRecord; - uint32_t NumHashBuckets; - uint32_t Index = -1; -}; -} - // Verifies that a given type record matches with a given hash value. // Currently we only verify SRC_LINE records. Error TpiStream::verifyHashValues() { @@ -193,6 +102,9 @@ Error TpiStream::reload() { HSR.setOffset(Header->HashValueBuffer.Off); if (auto EC = HSR.readArray(HashValues, NumHashValues)) return EC; + std::vector<ulittle32_t> HashValueList; + for (auto I : HashValues) + HashValueList.push_back(I); HSR.setOffset(Header->IndexOffsetBuffer.Off); uint32_t NumTypeIndexOffsets = |

