1061da546Spatrick //===-- PdbIndex.h ----------------------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBINDEX_H 10dda28197Spatrick #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBINDEX_H 11061da546Spatrick 12061da546Spatrick #include "lldb/lldb-types.h" 13061da546Spatrick #include "llvm/ADT/IntervalMap.h" 14061da546Spatrick #include "llvm/DebugInfo/PDB/Native/PDBFile.h" 15061da546Spatrick #include "llvm/DebugInfo/PDB/PDBTypes.h" 16061da546Spatrick 17061da546Spatrick #include "CompileUnitIndex.h" 18061da546Spatrick #include "PdbSymUid.h" 19061da546Spatrick 20061da546Spatrick #include <map> 21061da546Spatrick #include <memory> 22*f6aab3d8Srobert #include <optional> 23061da546Spatrick 24061da546Spatrick namespace llvm { 25061da546Spatrick namespace pdb { 26061da546Spatrick class DbiStream; 27061da546Spatrick class TpiStream; 28061da546Spatrick class InfoStream; 29061da546Spatrick class PublicsStream; 30061da546Spatrick class GlobalsStream; 31061da546Spatrick class SymbolStream; 32061da546Spatrick } // namespace pdb 33061da546Spatrick } // namespace llvm 34061da546Spatrick 35061da546Spatrick namespace lldb_private { 36061da546Spatrick namespace npdb { 37061da546Spatrick struct SegmentOffset; 38061da546Spatrick 39061da546Spatrick /// PdbIndex - Lazy access to the important parts of a PDB file. 40061da546Spatrick /// 41061da546Spatrick /// This is a layer on top of LLVM's native PDB support libraries which cache 42061da546Spatrick /// certain data when it is accessed the first time. The entire PDB file is 43061da546Spatrick /// mapped into memory, and the underlying support libraries vend out memory 44061da546Spatrick /// that is always backed by the file, so it is safe to hold StringRefs and 45061da546Spatrick /// ArrayRefs into the backing memory as long as the PdbIndex instance is 46061da546Spatrick /// alive. 47061da546Spatrick class PdbIndex { 48061da546Spatrick 49061da546Spatrick /// The underlying PDB file. 50be691f3bSpatrick llvm::pdb::PDBFile *m_file = nullptr; 51061da546Spatrick 52061da546Spatrick /// The DBI stream. This contains general high level information about the 53061da546Spatrick /// features present in the PDB file, compile units (such as the information 54061da546Spatrick /// necessary to locate full symbol information for each compile unit), 55061da546Spatrick /// section contributions, and other data which is not specifically symbol or 56061da546Spatrick /// type records. 57061da546Spatrick llvm::pdb::DbiStream *m_dbi = nullptr; 58061da546Spatrick 59061da546Spatrick /// TPI (types) and IPI (indices) streams. These are both in the exact same 60061da546Spatrick /// format with different data. Most type records are stored in the TPI 61061da546Spatrick /// stream but certain specific types of records are stored in the IPI stream. 62061da546Spatrick /// The IPI stream records can refer to the records in the TPI stream, but not 63061da546Spatrick /// the other way around. 64061da546Spatrick llvm::pdb::TpiStream *m_tpi = nullptr; 65061da546Spatrick llvm::pdb::TpiStream *m_ipi = nullptr; 66061da546Spatrick 67061da546Spatrick /// This is called the "PDB Stream" in the Microsoft reference implementation. 68061da546Spatrick /// It contains information about the structure of the file, as well as fields 69061da546Spatrick /// used to match EXE and PDB. 70061da546Spatrick llvm::pdb::InfoStream *m_info = nullptr; 71061da546Spatrick 72061da546Spatrick /// Publics stream. Is actually a serialized hash table where the keys are 73061da546Spatrick /// addresses of symbols in the executable, and values are a record containing 74061da546Spatrick /// mangled names and an index which can be used to locate more detailed info 75061da546Spatrick /// about the symbol in the Symbol Records stream. The publics stream only 76061da546Spatrick /// contains info about externally visible symbols. 77061da546Spatrick llvm::pdb::PublicsStream *m_publics = nullptr; 78061da546Spatrick 79061da546Spatrick /// Globals stream. Contrary to its name, this does not contain information 80061da546Spatrick /// about all "global variables" or "global functions". Rather, it is the 81061da546Spatrick /// "global symbol table", i.e. it contains information about *every* symbol 82061da546Spatrick /// in the executable. It is a hash table keyed on name, whose values are 83061da546Spatrick /// indices into the symbol records stream to find the full record. 84061da546Spatrick llvm::pdb::GlobalsStream *m_globals = nullptr; 85061da546Spatrick 86061da546Spatrick /// Symbol records stream. The publics and globals stream refer to records 87061da546Spatrick /// in this stream. For some records, like constants and typedefs, the 88061da546Spatrick /// complete record lives in this stream. For other symbol types, such as 89061da546Spatrick /// functions, data, and other things that have been materialied into a 90061da546Spatrick /// specific compile unit, the records here simply provide a reference 91061da546Spatrick /// necessary to locate the full information. 92061da546Spatrick llvm::pdb::SymbolStream *m_symrecords = nullptr; 93061da546Spatrick 94061da546Spatrick /// Index of all compile units, mapping identifier to |CompilandIndexItem| 95061da546Spatrick /// instance. 96061da546Spatrick CompileUnitIndex m_cus; 97061da546Spatrick 98061da546Spatrick /// An allocator for the interval maps 99061da546Spatrick llvm::IntervalMap<lldb::addr_t, uint32_t>::Allocator m_allocator; 100061da546Spatrick 101061da546Spatrick /// Maps virtual address to module index 102061da546Spatrick llvm::IntervalMap<lldb::addr_t, uint16_t> m_va_to_modi; 103061da546Spatrick 104061da546Spatrick /// The address at which the program has been loaded into memory. 105061da546Spatrick lldb::addr_t m_load_address = 0; 106061da546Spatrick 107061da546Spatrick PdbIndex(); 108061da546Spatrick 109061da546Spatrick void BuildAddrToSymbolMap(CompilandIndexItem &cci); 110061da546Spatrick 111061da546Spatrick public: 112be691f3bSpatrick static llvm::Expected<std::unique_ptr<PdbIndex>> create(llvm::pdb::PDBFile *); 113061da546Spatrick SetLoadAddress(lldb::addr_t addr)114061da546Spatrick void SetLoadAddress(lldb::addr_t addr) { m_load_address = addr; } GetLoadAddress()115061da546Spatrick lldb::addr_t GetLoadAddress() const { return m_load_address; } 116061da546Spatrick void ParseSectionContribs(); 117061da546Spatrick pdb()118061da546Spatrick llvm::pdb::PDBFile &pdb() { return *m_file; } pdb()119061da546Spatrick const llvm::pdb::PDBFile &pdb() const { return *m_file; } 120061da546Spatrick dbi()121061da546Spatrick llvm::pdb::DbiStream &dbi() { return *m_dbi; } dbi()122061da546Spatrick const llvm::pdb::DbiStream &dbi() const { return *m_dbi; } 123061da546Spatrick tpi()124061da546Spatrick llvm::pdb::TpiStream &tpi() { return *m_tpi; } tpi()125061da546Spatrick const llvm::pdb::TpiStream &tpi() const { return *m_tpi; } 126061da546Spatrick ipi()127061da546Spatrick llvm::pdb::TpiStream &ipi() { return *m_ipi; } ipi()128061da546Spatrick const llvm::pdb::TpiStream &ipi() const { return *m_ipi; } 129061da546Spatrick info()130061da546Spatrick llvm::pdb::InfoStream &info() { return *m_info; } info()131061da546Spatrick const llvm::pdb::InfoStream &info() const { return *m_info; } 132061da546Spatrick publics()133061da546Spatrick llvm::pdb::PublicsStream &publics() { return *m_publics; } publics()134061da546Spatrick const llvm::pdb::PublicsStream &publics() const { return *m_publics; } 135061da546Spatrick globals()136061da546Spatrick llvm::pdb::GlobalsStream &globals() { return *m_globals; } globals()137061da546Spatrick const llvm::pdb::GlobalsStream &globals() const { return *m_globals; } 138061da546Spatrick symrecords()139061da546Spatrick llvm::pdb::SymbolStream &symrecords() { return *m_symrecords; } symrecords()140061da546Spatrick const llvm::pdb::SymbolStream &symrecords() const { return *m_symrecords; } 141061da546Spatrick compilands()142061da546Spatrick CompileUnitIndex &compilands() { return m_cus; } compilands()143061da546Spatrick const CompileUnitIndex &compilands() const { return m_cus; } 144061da546Spatrick 145061da546Spatrick lldb::addr_t MakeVirtualAddress(uint16_t segment, uint32_t offset) const; 146061da546Spatrick 147061da546Spatrick std::vector<SymbolAndUid> FindSymbolsByVa(lldb::addr_t va); 148061da546Spatrick 149061da546Spatrick llvm::codeview::CVSymbol ReadSymbolRecord(PdbCompilandSymId cu_sym) const; 150061da546Spatrick llvm::codeview::CVSymbol ReadSymbolRecord(PdbGlobalSymId global) const; 151061da546Spatrick 152*f6aab3d8Srobert std::optional<uint16_t> GetModuleIndexForAddr(uint16_t segment, 153061da546Spatrick uint32_t offset) const; 154*f6aab3d8Srobert std::optional<uint16_t> GetModuleIndexForVa(lldb::addr_t va) const; 155061da546Spatrick }; 156061da546Spatrick } // namespace npdb 157061da546Spatrick } // namespace lldb_private 158061da546Spatrick 159061da546Spatrick #endif 160