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_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBINDEX_H 10 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_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 24 namespace llvm { 25 namespace pdb { 26 class DbiStream; 27 class TpiStream; 28 class TpiStream; 29 class InfoStream; 30 class PublicsStream; 31 class GlobalsStream; 32 class SymbolStream; 33 } // namespace pdb 34 } // namespace llvm 35 36 namespace lldb_private { 37 namespace npdb { 38 struct 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. 48 class PdbIndex { 49 50 /// The underlying PDB file. 51 llvm::pdb::PDBFile *m_file = nullptr; 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 112 public: 113 static llvm::Expected<std::unique_ptr<PdbIndex>> create(llvm::pdb::PDBFile *); 114 115 void SetLoadAddress(lldb::addr_t addr) { m_load_address = addr; } 116 lldb::addr_t GetLoadAddress() const { return m_load_address; } 117 void ParseSectionContribs(); 118 119 llvm::pdb::PDBFile &pdb() { return *m_file; } 120 const llvm::pdb::PDBFile &pdb() const { return *m_file; } 121 122 llvm::pdb::DbiStream &dbi() { return *m_dbi; } 123 const llvm::pdb::DbiStream &dbi() const { return *m_dbi; } 124 125 llvm::pdb::TpiStream &tpi() { return *m_tpi; } 126 const llvm::pdb::TpiStream &tpi() const { return *m_tpi; } 127 128 llvm::pdb::TpiStream &ipi() { return *m_ipi; } 129 const llvm::pdb::TpiStream &ipi() const { return *m_ipi; } 130 131 llvm::pdb::InfoStream &info() { return *m_info; } 132 const llvm::pdb::InfoStream &info() const { return *m_info; } 133 134 llvm::pdb::PublicsStream &publics() { return *m_publics; } 135 const llvm::pdb::PublicsStream &publics() const { return *m_publics; } 136 137 llvm::pdb::GlobalsStream &globals() { return *m_globals; } 138 const llvm::pdb::GlobalsStream &globals() const { return *m_globals; } 139 140 llvm::pdb::SymbolStream &symrecords() { return *m_symrecords; } 141 const llvm::pdb::SymbolStream &symrecords() const { return *m_symrecords; } 142 143 CompileUnitIndex &compilands() { return m_cus; } 144 const CompileUnitIndex &compilands() const { return m_cus; } 145 146 lldb::addr_t MakeVirtualAddress(uint16_t segment, uint32_t offset) const; 147 lldb::addr_t MakeVirtualAddress(const SegmentOffset &so) const; 148 149 std::vector<SymbolAndUid> FindSymbolsByVa(lldb::addr_t va); 150 151 llvm::codeview::CVSymbol ReadSymbolRecord(PdbCompilandSymId cu_sym) const; 152 llvm::codeview::CVSymbol ReadSymbolRecord(PdbGlobalSymId global) const; 153 154 llvm::Optional<uint16_t> GetModuleIndexForAddr(uint16_t segment, 155 uint32_t offset) const; 156 llvm::Optional<uint16_t> GetModuleIndexForVa(lldb::addr_t va) const; 157 }; 158 } // namespace npdb 159 } // namespace lldb_private 160 161 #endif 162