From 4ca5d1c4dcbd0dd0c89614a7fde1ccfc61415d21 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Thu, 15 Mar 2018 22:31:00 +0000 Subject: [PATCH] [PDB] Fix a bug where we were serializing hash tables incorrectly. There was some code that tried to calculate the number of 4-byte words required to hold N bits, but it was instead computing the number of bytes required to hold N bits. This was leading to extraneous data being output into the hash table, which would cause certain operations in DIA (the Microsoft PDB reader) to fail. llvm-svn: 327675 --- include/llvm/DebugInfo/PDB/Native/HashTable.h | 17 ++++++++++++----- lib/DebugInfo/PDB/Native/HashTable.cpp | 8 +++++--- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/include/llvm/DebugInfo/PDB/Native/HashTable.h b/include/llvm/DebugInfo/PDB/Native/HashTable.h index 907f5ba1a3f..6361c4b76ba 100644 --- a/include/llvm/DebugInfo/PDB/Native/HashTable.h +++ b/include/llvm/DebugInfo/PDB/Native/HashTable.h @@ -161,16 +161,23 @@ public: uint32_t calculateSerializedLength() const { uint32_t Size = sizeof(Header); + constexpr int BitsPerWord = 8 * sizeof(uint32_t); + int NumBitsP = Present.find_last() + 1; int NumBitsD = Deleted.find_last() + 1; - // Present bit set number of words, followed by that many actual words. - Size += sizeof(uint32_t); - Size += alignTo(NumBitsP, sizeof(uint32_t)); + uint32_t NumWordsP = alignTo(NumBitsP, BitsPerWord) / BitsPerWord; + uint32_t NumWordsD = alignTo(NumBitsD, BitsPerWord) / BitsPerWord; - // Deleted bit set number of words, followed by that many actual words. + // Present bit set number of words (4 bytes), followed by that many actual + // words (4 bytes each). Size += sizeof(uint32_t); - Size += alignTo(NumBitsD, sizeof(uint32_t)); + Size += NumWordsP * sizeof(uint32_t); + + // Deleted bit set number of words (4 bytes), followed by that many actual + // words (4 bytes each). + Size += sizeof(uint32_t); + Size += NumWordsD * sizeof(uint32_t); // One (Key, ValueT) pair for each entry Present. Size += (sizeof(uint32_t) + sizeof(ValueT)) * size(); diff --git a/lib/DebugInfo/PDB/Native/HashTable.cpp b/lib/DebugInfo/PDB/Native/HashTable.cpp index 5ed0acc8fd7..cfabc9cd1ad 100644 --- a/lib/DebugInfo/PDB/Native/HashTable.cpp +++ b/lib/DebugInfo/PDB/Native/HashTable.cpp @@ -46,16 +46,18 @@ Error llvm::pdb::readSparseBitVector(BinaryStreamReader &Stream, Error llvm::pdb::writeSparseBitVector(BinaryStreamWriter &Writer, SparseBitVector<> &Vec) { + constexpr int BitsPerWord = 8 * sizeof(uint32_t); + int ReqBits = Vec.find_last() + 1; - uint32_t NumWords = alignTo(ReqBits, sizeof(uint32_t)) / sizeof(uint32_t); - if (auto EC = Writer.writeInteger(NumWords)) + uint32_t ReqWords = alignTo(ReqBits, BitsPerWord) / BitsPerWord; + if (auto EC = Writer.writeInteger(ReqWords)) return joinErrors( std::move(EC), make_error(raw_error_code::corrupt_file, "Could not write linear map number of words")); uint32_t Idx = 0; - for (uint32_t I = 0; I != NumWords; ++I) { + for (uint32_t I = 0; I != ReqWords; ++I) { uint32_t Word = 0; for (uint32_t WordIdx = 0; WordIdx < 32; ++WordIdx, ++Idx) { if (Vec.test(Idx))