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