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