xref: /src/contrib/llvm-project/llvm/lib/DebugInfo/PDB/Native/HashTable.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
19df3605dSDimitry Andric //===- HashTable.cpp - PDB Hash Table -------------------------------------===//
271d5a254SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
671d5a254SDimitry Andric //
771d5a254SDimitry Andric //===----------------------------------------------------------------------===//
871d5a254SDimitry Andric 
971d5a254SDimitry Andric #include "llvm/DebugInfo/PDB/Native/HashTable.h"
1071d5a254SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawError.h"
119df3605dSDimitry Andric #include "llvm/Support/BinaryStreamReader.h"
129df3605dSDimitry Andric #include "llvm/Support/BinaryStreamWriter.h"
139df3605dSDimitry Andric #include "llvm/Support/Error.h"
149df3605dSDimitry Andric #include "llvm/Support/MathExtras.h"
159df3605dSDimitry Andric #include <cstdint>
169df3605dSDimitry Andric #include <utility>
1771d5a254SDimitry Andric 
1871d5a254SDimitry Andric using namespace llvm;
1971d5a254SDimitry Andric using namespace llvm::pdb;
2071d5a254SDimitry Andric 
readSparseBitVector(BinaryStreamReader & Stream,SparseBitVector<> & V)21eb11fae6SDimitry Andric Error llvm::pdb::readSparseBitVector(BinaryStreamReader &Stream,
2271d5a254SDimitry Andric                                      SparseBitVector<> &V) {
2371d5a254SDimitry Andric   uint32_t NumWords;
2471d5a254SDimitry Andric   if (auto EC = Stream.readInteger(NumWords))
2571d5a254SDimitry Andric     return joinErrors(
2671d5a254SDimitry Andric         std::move(EC),
2771d5a254SDimitry Andric         make_error<RawError>(raw_error_code::corrupt_file,
2871d5a254SDimitry Andric                              "Expected hash table number of words"));
2971d5a254SDimitry Andric 
3071d5a254SDimitry Andric   for (uint32_t I = 0; I != NumWords; ++I) {
3171d5a254SDimitry Andric     uint32_t Word;
3271d5a254SDimitry Andric     if (auto EC = Stream.readInteger(Word))
3371d5a254SDimitry Andric       return joinErrors(std::move(EC),
3471d5a254SDimitry Andric                         make_error<RawError>(raw_error_code::corrupt_file,
3571d5a254SDimitry Andric                                              "Expected hash table word"));
3671d5a254SDimitry Andric     for (unsigned Idx = 0; Idx < 32; ++Idx)
3771d5a254SDimitry Andric       if (Word & (1U << Idx))
3871d5a254SDimitry Andric         V.set((I * 32) + Idx);
3971d5a254SDimitry Andric   }
4071d5a254SDimitry Andric   return Error::success();
4171d5a254SDimitry Andric }
4271d5a254SDimitry Andric 
writeSparseBitVector(BinaryStreamWriter & Writer,SparseBitVector<> & Vec)43eb11fae6SDimitry Andric Error llvm::pdb::writeSparseBitVector(BinaryStreamWriter &Writer,
4471d5a254SDimitry Andric                                       SparseBitVector<> &Vec) {
45eb11fae6SDimitry Andric   constexpr int BitsPerWord = 8 * sizeof(uint32_t);
46eb11fae6SDimitry Andric 
4771d5a254SDimitry Andric   int ReqBits = Vec.find_last() + 1;
48eb11fae6SDimitry Andric   uint32_t ReqWords = alignTo(ReqBits, BitsPerWord) / BitsPerWord;
49eb11fae6SDimitry Andric   if (auto EC = Writer.writeInteger(ReqWords))
5071d5a254SDimitry Andric     return joinErrors(
5171d5a254SDimitry Andric         std::move(EC),
5271d5a254SDimitry Andric         make_error<RawError>(raw_error_code::corrupt_file,
5371d5a254SDimitry Andric                              "Could not write linear map number of words"));
5471d5a254SDimitry Andric 
5571d5a254SDimitry Andric   uint32_t Idx = 0;
56eb11fae6SDimitry Andric   for (uint32_t I = 0; I != ReqWords; ++I) {
5771d5a254SDimitry Andric     uint32_t Word = 0;
5871d5a254SDimitry Andric     for (uint32_t WordIdx = 0; WordIdx < 32; ++WordIdx, ++Idx) {
5971d5a254SDimitry Andric       if (Vec.test(Idx))
6071d5a254SDimitry Andric         Word |= (1 << WordIdx);
6171d5a254SDimitry Andric     }
6271d5a254SDimitry Andric     if (auto EC = Writer.writeInteger(Word))
6371d5a254SDimitry Andric       return joinErrors(std::move(EC), make_error<RawError>(
6471d5a254SDimitry Andric                                            raw_error_code::corrupt_file,
6571d5a254SDimitry Andric                                            "Could not write linear map word"));
6671d5a254SDimitry Andric   }
6771d5a254SDimitry Andric   return Error::success();
6871d5a254SDimitry Andric }
69