1//===-- PdbIndex.h ----------------------------------------------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H 10#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H 11 12#include "lldb/lldb-types.h" 13#include "llvm/ADT/IntervalMap.h" 14#include "llvm/ADT/Optional.h" 15#include "llvm/DebugInfo/PDB/Native/PDBFile.h" 16#include "llvm/DebugInfo/PDB/PDBTypes.h" 17 18#include "CompileUnitIndex.h" 19#include "PdbSymUid.h" 20 21#include <map> 22#include <memory> 23 24namespace llvm { 25namespace pdb { 26class DbiStream; 27class TpiStream; 28class TpiStream; 29class InfoStream; 30class PublicsStream; 31class GlobalsStream; 32class SymbolStream; 33} // namespace pdb 34} // namespace llvm 35 36namespace lldb_private { 37namespace npdb { 38struct SegmentOffset; 39 40/// PdbIndex - Lazy access to the important parts of a PDB file. 41/// 42/// This is a layer on top of LLVM's native PDB support libraries which cache 43/// certain data when it is accessed the first time. The entire PDB file is 44/// mapped into memory, and the underlying support libraries vend out memory 45/// that is always backed by the file, so it is safe to hold StringRefs and 46/// ArrayRefs into the backing memory as long as the PdbIndex instance is 47/// alive. 48class PdbIndex { 49 50 /// The underlying PDB file. 51 std::unique_ptr<llvm::pdb::PDBFile> m_file; 52 53 /// The DBI stream. This contains general high level information about the 54 /// features present in the PDB file, compile units (such as the information 55 /// necessary to locate full symbol information for each compile unit), 56 /// section contributions, and other data which is not specifically symbol or 57 /// type records. 58 llvm::pdb::DbiStream *m_dbi = nullptr; 59 60 /// TPI (types) and IPI (indices) streams. These are both in the exact same 61 /// format with different data. Most type records are stored in the TPI 62 /// stream but certain specific types of records are stored in the IPI stream. 63 /// The IPI stream records can refer to the records in the TPI stream, but not 64 /// the other way around. 65 llvm::pdb::TpiStream *m_tpi = nullptr; 66 llvm::pdb::TpiStream *m_ipi = nullptr; 67 68 /// This is called the "PDB Stream" in the Microsoft reference implementation. 69 /// It contains information about the structure of the file, as well as fields 70 /// used to match EXE and PDB. 71 llvm::pdb::InfoStream *m_info = nullptr; 72 73 /// Publics stream. Is actually a serialized hash table where the keys are 74 /// addresses of symbols in the executable, and values are a record containing 75 /// mangled names and an index which can be used to locate more detailed info 76 /// about the symbol in the Symbol Records stream. The publics stream only 77 /// contains info about externally visible symbols. 78 llvm::pdb::PublicsStream *m_publics = nullptr; 79 80 /// Globals stream. Contrary to its name, this does not contain information 81 /// about all "global variables" or "global functions". Rather, it is the 82 /// "global symbol table", i.e. it contains information about *every* symbol 83 /// in the executable. It is a hash table keyed on name, whose values are 84 /// indices into the symbol records stream to find the full record. 85 llvm::pdb::GlobalsStream *m_globals = nullptr; 86 87 /// Symbol records stream. The publics and globals stream refer to records 88 /// in this stream. For some records, like constants and typedefs, the 89 /// complete record lives in this stream. For other symbol types, such as 90 /// functions, data, and other things that have been materialied into a 91 /// specific compile unit, the records here simply provide a reference 92 /// necessary to locate the full information. 93 llvm::pdb::SymbolStream *m_symrecords = nullptr; 94 95 /// Index of all compile units, mapping identifier to |CompilandIndexItem| 96 /// instance. 97 CompileUnitIndex m_cus; 98 99 /// An allocator for the interval maps 100 llvm::IntervalMap<lldb::addr_t, uint32_t>::Allocator m_allocator; 101 102 /// Maps virtual address to module index 103 llvm::IntervalMap<lldb::addr_t, uint16_t> m_va_to_modi; 104 105 /// The address at which the program has been loaded into memory. 106 lldb::addr_t m_load_address = 0; 107 108 PdbIndex(); 109 110 void BuildAddrToSymbolMap(CompilandIndexItem &cci); 111 112public: 113 static llvm::Expected<std::unique_ptr<PdbIndex>> 114 create(std::unique_ptr<llvm::pdb::PDBFile>); 115 116 void SetLoadAddress(lldb::addr_t addr) { m_load_address = addr; } 117 lldb::addr_t GetLoadAddress() const { return m_load_address; } 118 void ParseSectionContribs(); 119 120 llvm::pdb::PDBFile &pdb() { return *m_file; } 121 const llvm::pdb::PDBFile &pdb() const { return *m_file; } 122 123 llvm::pdb::DbiStream &dbi() { return *m_dbi; } 124 const llvm::pdb::DbiStream &dbi() const { return *m_dbi; } 125 126 llvm::pdb::TpiStream &tpi() { return *m_tpi; } 127 const llvm::pdb::TpiStream &tpi() const { return *m_tpi; } 128 129 llvm::pdb::TpiStream &ipi() { return *m_ipi; } 130 const llvm::pdb::TpiStream &ipi() const { return *m_ipi; } 131 132 llvm::pdb::InfoStream &info() { return *m_info; } 133 const llvm::pdb::InfoStream &info() const { return *m_info; } 134 135 llvm::pdb::PublicsStream &publics() { return *m_publics; } 136 const llvm::pdb::PublicsStream &publics() const { return *m_publics; } 137 138 llvm::pdb::GlobalsStream &globals() { return *m_globals; } 139 const llvm::pdb::GlobalsStream &globals() const { return *m_globals; } 140 141 llvm::pdb::SymbolStream &symrecords() { return *m_symrecords; } 142 const llvm::pdb::SymbolStream &symrecords() const { return *m_symrecords; } 143 144 CompileUnitIndex &compilands() { return m_cus; } 145 const CompileUnitIndex &compilands() const { return m_cus; } 146 147 lldb::addr_t MakeVirtualAddress(uint16_t segment, uint32_t offset) const; 148 lldb::addr_t MakeVirtualAddress(const SegmentOffset &so) const; 149 150 std::vector<SymbolAndUid> FindSymbolsByVa(lldb::addr_t va); 151 152 llvm::codeview::CVSymbol ReadSymbolRecord(PdbCompilandSymId cu_sym) const; 153 llvm::codeview::CVSymbol ReadSymbolRecord(PdbGlobalSymId global) const; 154 155 llvm::Optional<uint16_t> GetModuleIndexForAddr(uint16_t segment, 156 uint32_t offset) const; 157 llvm::Optional<uint16_t> GetModuleIndexForVa(lldb::addr_t va) const; 158}; 159} // namespace npdb 160} // namespace lldb_private 161 162#endif 163