• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
readSparseBitVector(BinaryStreamReader & Stream,SparseBitVector<> & V)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 
writeSparseBitVector(BinaryStreamWriter & Writer,SparseBitVector<> & Vec)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