1 //===- HashTable.cpp - PDB Hash Table -------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/DebugInfo/PDB/Native/HashTable.h" 10 #include "llvm/DebugInfo/PDB/Native/RawError.h" 11 #include "llvm/Support/BinaryStreamReader.h" 12 #include "llvm/Support/BinaryStreamWriter.h" 13 #include "llvm/Support/Error.h" 14 #include "llvm/Support/MathExtras.h" 15 #include <cstdint> 16 #include <utility> 17 18 using namespace llvm; 19 using namespace llvm::pdb; 20 21 Error llvm::pdb::readSparseBitVector(BinaryStreamReader &Stream, 22 SparseBitVector<> &V) { 23 uint32_t NumWords; 24 if (auto EC = Stream.readInteger(NumWords)) 25 return joinErrors( 26 std::move(EC), 27 make_error<RawError>(raw_error_code::corrupt_file, 28 "Expected hash table number of words")); 29 30 for (uint32_t I = 0; I != NumWords; ++I) { 31 uint32_t Word; 32 if (auto EC = Stream.readInteger(Word)) 33 return joinErrors(std::move(EC), 34 make_error<RawError>(raw_error_code::corrupt_file, 35 "Expected hash table word")); 36 for (unsigned Idx = 0; Idx < 32; ++Idx) 37 if (Word & (1U << Idx)) 38 V.set((I * 32) + Idx); 39 } 40 return Error::success(); 41 } 42 43 Error llvm::pdb::writeSparseBitVector(BinaryStreamWriter &Writer, 44 SparseBitVector<> &Vec) { 45 constexpr int BitsPerWord = 8 * sizeof(uint32_t); 46 47 int ReqBits = Vec.find_last() + 1; 48 uint32_t ReqWords = alignTo(ReqBits, BitsPerWord) / BitsPerWord; 49 if (auto EC = Writer.writeInteger(ReqWords)) 50 return joinErrors( 51 std::move(EC), 52 make_error<RawError>(raw_error_code::corrupt_file, 53 "Could not write linear map number of words")); 54 55 uint32_t Idx = 0; 56 for (uint32_t I = 0; I != ReqWords; ++I) { 57 uint32_t Word = 0; 58 for (uint32_t WordIdx = 0; WordIdx < 32; ++WordIdx, ++Idx) { 59 if (Vec.test(Idx)) 60 Word |= (1 << WordIdx); 61 } 62 if (auto EC = Writer.writeInteger(Word)) 63 return joinErrors(std::move(EC), make_error<RawError>( 64 raw_error_code::corrupt_file, 65 "Could not write linear map word")); 66 } 67 return Error::success(); 68 } 69