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