1a580b014SDimitry Andric //===- HashTable.cpp - PDB Hash Table -------------------------------------===//
27a7e6055SDimitry Andric //
37a7e6055SDimitry Andric // The LLVM Compiler Infrastructure
47a7e6055SDimitry Andric //
57a7e6055SDimitry Andric // This file is distributed under the University of Illinois Open Source
67a7e6055SDimitry Andric // License. See LICENSE.TXT for details.
77a7e6055SDimitry Andric //
87a7e6055SDimitry Andric //===----------------------------------------------------------------------===//
97a7e6055SDimitry Andric
107a7e6055SDimitry Andric #include "llvm/DebugInfo/PDB/Native/HashTable.h"
117a7e6055SDimitry Andric #include "llvm/ADT/Optional.h"
127a7e6055SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawError.h"
13a580b014SDimitry Andric #include "llvm/Support/BinaryStreamReader.h"
14a580b014SDimitry Andric #include "llvm/Support/BinaryStreamWriter.h"
15a580b014SDimitry Andric #include "llvm/Support/Error.h"
16a580b014SDimitry Andric #include "llvm/Support/MathExtras.h"
17a580b014SDimitry Andric #include <algorithm>
18a580b014SDimitry Andric #include <cassert>
19a580b014SDimitry Andric #include <cstdint>
20a580b014SDimitry Andric #include <utility>
217a7e6055SDimitry Andric
227a7e6055SDimitry Andric using namespace llvm;
237a7e6055SDimitry Andric using namespace llvm::pdb;
247a7e6055SDimitry Andric
readSparseBitVector(BinaryStreamReader & Stream,SparseBitVector<> & V)25*4ba319b5SDimitry Andric Error llvm::pdb::readSparseBitVector(BinaryStreamReader &Stream,
267a7e6055SDimitry Andric SparseBitVector<> &V) {
277a7e6055SDimitry Andric uint32_t NumWords;
287a7e6055SDimitry Andric if (auto EC = Stream.readInteger(NumWords))
297a7e6055SDimitry Andric return joinErrors(
307a7e6055SDimitry Andric std::move(EC),
317a7e6055SDimitry Andric make_error<RawError>(raw_error_code::corrupt_file,
327a7e6055SDimitry Andric "Expected hash table number of words"));
337a7e6055SDimitry Andric
347a7e6055SDimitry Andric for (uint32_t I = 0; I != NumWords; ++I) {
357a7e6055SDimitry Andric uint32_t Word;
367a7e6055SDimitry Andric if (auto EC = Stream.readInteger(Word))
377a7e6055SDimitry Andric return joinErrors(std::move(EC),
387a7e6055SDimitry Andric make_error<RawError>(raw_error_code::corrupt_file,
397a7e6055SDimitry Andric "Expected hash table word"));
407a7e6055SDimitry Andric for (unsigned Idx = 0; Idx < 32; ++Idx)
417a7e6055SDimitry Andric if (Word & (1U << Idx))
427a7e6055SDimitry Andric V.set((I * 32) + Idx);
437a7e6055SDimitry Andric }
447a7e6055SDimitry Andric return Error::success();
457a7e6055SDimitry Andric }
467a7e6055SDimitry Andric
writeSparseBitVector(BinaryStreamWriter & Writer,SparseBitVector<> & Vec)47*4ba319b5SDimitry Andric Error llvm::pdb::writeSparseBitVector(BinaryStreamWriter &Writer,
487a7e6055SDimitry Andric SparseBitVector<> &Vec) {
49*4ba319b5SDimitry Andric constexpr int BitsPerWord = 8 * sizeof(uint32_t);
50*4ba319b5SDimitry Andric
517a7e6055SDimitry Andric int ReqBits = Vec.find_last() + 1;
52*4ba319b5SDimitry Andric uint32_t ReqWords = alignTo(ReqBits, BitsPerWord) / BitsPerWord;
53*4ba319b5SDimitry Andric if (auto EC = Writer.writeInteger(ReqWords))
547a7e6055SDimitry Andric return joinErrors(
557a7e6055SDimitry Andric std::move(EC),
567a7e6055SDimitry Andric make_error<RawError>(raw_error_code::corrupt_file,
577a7e6055SDimitry Andric "Could not write linear map number of words"));
587a7e6055SDimitry Andric
597a7e6055SDimitry Andric uint32_t Idx = 0;
60*4ba319b5SDimitry Andric for (uint32_t I = 0; I != ReqWords; ++I) {
617a7e6055SDimitry Andric uint32_t Word = 0;
627a7e6055SDimitry Andric for (uint32_t WordIdx = 0; WordIdx < 32; ++WordIdx, ++Idx) {
637a7e6055SDimitry Andric if (Vec.test(Idx))
647a7e6055SDimitry Andric Word |= (1 << WordIdx);
657a7e6055SDimitry Andric }
667a7e6055SDimitry Andric if (auto EC = Writer.writeInteger(Word))
677a7e6055SDimitry Andric return joinErrors(std::move(EC), make_error<RawError>(
687a7e6055SDimitry Andric raw_error_code::corrupt_file,
697a7e6055SDimitry Andric "Could not write linear map word"));
707a7e6055SDimitry Andric }
717a7e6055SDimitry Andric return Error::success();
727a7e6055SDimitry Andric }
73