1327952Sdim//===- GlobalsStream.h - PDB Index of Symbols by Name -----------*- C++ -*-===//
2317017Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6317017Sdim//
7317017Sdim//===----------------------------------------------------------------------===//
8317017Sdim
9317017Sdim#ifndef LLVM_DEBUGINFO_PDB_RAW_GLOBALS_STREAM_H
10317017Sdim#define LLVM_DEBUGINFO_PDB_RAW_GLOBALS_STREAM_H
11317017Sdim
12344779Sdim#include "llvm/ADT/iterator.h"
13344779Sdim#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
14317017Sdim#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
15317017Sdim#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
16317017Sdim#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
17317017Sdim#include "llvm/DebugInfo/PDB/PDBTypes.h"
18317017Sdim#include "llvm/Support/BinaryStreamArray.h"
19317017Sdim#include "llvm/Support/Error.h"
20317017Sdim
21317017Sdimnamespace llvm {
22317017Sdimnamespace pdb {
23317017Sdimclass DbiStream;
24317017Sdimclass PDBFile;
25344779Sdimclass SymbolStream;
26317017Sdim
27327952Sdim/// Iterator over hash records producing symbol record offsets. Abstracts away
28327952Sdim/// the fact that symbol record offsets on disk are off-by-one.
29327952Sdimclass GSIHashIterator
30327952Sdim    : public iterator_adaptor_base<
31327952Sdim          GSIHashIterator, FixedStreamArrayIterator<PSHashRecord>,
32327952Sdim          std::random_access_iterator_tag, const uint32_t> {
33327952Sdimpublic:
34327952Sdim  template <typename T>
35327952Sdim  GSIHashIterator(T &&v)
36327952Sdim      : GSIHashIterator::iterator_adaptor_base(std::forward<T &&>(v)) {}
37327952Sdim
38327952Sdim  uint32_t operator*() const {
39327952Sdim    uint32_t Off = this->I->Off;
40327952Sdim    return --Off;
41327952Sdim  }
42327952Sdim};
43327952Sdim
44327952Sdim/// From https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.cpp
45327952Sdimenum : unsigned { IPHR_HASH = 4096 };
46327952Sdim
47327952Sdim/// A readonly view of a hash table used in the globals and publics streams.
48327952Sdim/// Most clients will only want to iterate this to get symbol record offsets
49327952Sdim/// into the PDB symbol stream.
50327952Sdimclass GSIHashTable {
51327952Sdimpublic:
52327952Sdim  const GSIHashHeader *HashHdr;
53327952Sdim  FixedStreamArray<PSHashRecord> HashRecords;
54344779Sdim  FixedStreamArray<support::ulittle32_t> HashBitmap;
55327952Sdim  FixedStreamArray<support::ulittle32_t> HashBuckets;
56344779Sdim  std::array<int32_t, IPHR_HASH + 1> BucketMap;
57327952Sdim
58327952Sdim  Error read(BinaryStreamReader &Reader);
59327952Sdim
60327952Sdim  uint32_t getVerSignature() const { return HashHdr->VerSignature; }
61327952Sdim  uint32_t getVerHeader() const { return HashHdr->VerHdr; }
62327952Sdim  uint32_t getHashRecordSize() const { return HashHdr->HrSize; }
63327952Sdim  uint32_t getNumBuckets() const { return HashHdr->NumBuckets; }
64327952Sdim
65327952Sdim  typedef GSIHashHeader iterator;
66327952Sdim  GSIHashIterator begin() const { return GSIHashIterator(HashRecords.begin()); }
67327952Sdim  GSIHashIterator end() const { return GSIHashIterator(HashRecords.end()); }
68327952Sdim};
69327952Sdim
70317017Sdimclass GlobalsStream {
71317017Sdimpublic:
72317017Sdim  explicit GlobalsStream(std::unique_ptr<msf::MappedBlockStream> Stream);
73317017Sdim  ~GlobalsStream();
74327952Sdim  const GSIHashTable &getGlobalsTable() const { return GlobalsTable; }
75317017Sdim  Error reload();
76317017Sdim
77344779Sdim  std::vector<std::pair<uint32_t, codeview::CVSymbol>>
78344779Sdim  findRecordsByName(StringRef Name, const SymbolStream &Symbols) const;
79344779Sdim
80317017Sdimprivate:
81327952Sdim  GSIHashTable GlobalsTable;
82317017Sdim  std::unique_ptr<msf::MappedBlockStream> Stream;
83317017Sdim};
84317017Sdim}
85317017Sdim}
86317017Sdim
87317017Sdim#endif
88