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