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/ADT/Optional.h" 11 #include "llvm/DebugInfo/PDB/Native/RawError.h" 12 #include "llvm/Support/BinaryStreamReader.h" 13 #include "llvm/Support/BinaryStreamWriter.h" 14 #include "llvm/Support/Error.h" 15 #include "llvm/Support/MathExtras.h" 16 #include <algorithm> 17 #include <cassert> 18 #include <cstdint> 19 #include <utility> 20 21 using namespace llvm; 22 using namespace llvm::pdb; 23 24 Error llvm::pdb::readSparseBitVector(BinaryStreamReader &Stream, 25 SparseBitVector<> &V) { 26 uint32_t NumWords; 27 if (auto EC = Stream.readInteger(NumWords)) 28 return joinErrors( 29 std::move(EC), 30 make_error<RawError>(raw_error_code::corrupt_file, 31 "Expected hash table number of words")); 32 33 for (uint32_t I = 0; I != NumWords; ++I) { 34 uint32_t Word; 35 if (auto EC = Stream.readInteger(Word)) 36 return joinErrors(std::move(EC), 37 make_error<RawError>(raw_error_code::corrupt_file, 38 "Expected hash table word")); 39 for (unsigned Idx = 0; Idx < 32; ++Idx) 40 if (Word & (1U << Idx)) 41 V.set((I * 32) + Idx); 42 } 43 return Error::success(); 44 } 45 46 Error llvm::pdb::writeSparseBitVector(BinaryStreamWriter &Writer, 47 SparseBitVector<> &Vec) { 48 constexpr int BitsPerWord = 8 * sizeof(uint32_t); 49 50 int ReqBits = Vec.find_last() + 1; 51 uint32_t ReqWords = alignTo(ReqBits, BitsPerWord) / BitsPerWord; 52 if (auto EC = Writer.writeInteger(ReqWords)) 53 return joinErrors( 54 std::move(EC), 55 make_error<RawError>(raw_error_code::corrupt_file, 56 "Could not write linear map number of words")); 57 58 uint32_t Idx = 0; 59 for (uint32_t I = 0; I != ReqWords; ++I) { 60 uint32_t Word = 0; 61 for (uint32_t WordIdx = 0; WordIdx < 32; ++WordIdx, ++Idx) { 62 if (Vec.test(Idx)) 63 Word |= (1 << WordIdx); 64 } 65 if (auto EC = Writer.writeInteger(Word)) 66 return joinErrors(std::move(EC), make_error<RawError>( 67 raw_error_code::corrupt_file, 68 "Could not write linear map word")); 69 } 70 return Error::success(); 71 } 72