reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
//===-- PdbIndex.h ----------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H
#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H

#include "lldb/lldb-types.h"
#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"

#include "CompileUnitIndex.h"
#include "PdbSymUid.h"

#include <map>
#include <memory>

namespace llvm {
namespace pdb {
class DbiStream;
class TpiStream;
class TpiStream;
class InfoStream;
class PublicsStream;
class GlobalsStream;
class SymbolStream;
} // namespace pdb
} // namespace llvm

namespace lldb_private {
namespace npdb {
struct SegmentOffset;

/// PdbIndex - Lazy access to the important parts of a PDB file.
///
/// This is a layer on top of LLVM's native PDB support libraries which cache
/// certain data when it is accessed the first time.  The entire PDB file is
/// mapped into memory, and the underlying support libraries vend out memory
/// that is always backed by the file, so it is safe to hold StringRefs and
/// ArrayRefs into the backing memory as long as the PdbIndex instance is
/// alive.
class PdbIndex {

  /// The underlying PDB file.
  std::unique_ptr<llvm::pdb::PDBFile> m_file;

  /// The DBI stream.  This contains general high level information about the
  /// features present in the PDB file, compile units (such as the information
  /// necessary to locate full symbol information for each compile unit),
  /// section contributions, and other data which is not specifically symbol or
  /// type records.
  llvm::pdb::DbiStream *m_dbi = nullptr;

  /// TPI (types) and IPI (indices) streams.  These are both in the exact same
  /// format with different data.  Most type records are stored in the TPI
  /// stream but certain specific types of records are stored in the IPI stream.
  /// The IPI stream records can refer to the records in the TPI stream, but not
  /// the other way around.
  llvm::pdb::TpiStream *m_tpi = nullptr;
  llvm::pdb::TpiStream *m_ipi = nullptr;

  /// This is called the "PDB Stream" in the Microsoft reference implementation.
  /// It contains information about the structure of the file, as well as fields
  /// used to match EXE and PDB.
  llvm::pdb::InfoStream *m_info = nullptr;

  /// Publics stream.  Is actually a serialized hash table where the keys are
  /// addresses of symbols in the executable, and values are a record containing
  /// mangled names and an index which can be used to locate more detailed info
  /// about the symbol in the Symbol Records stream.  The publics stream only
  /// contains info about externally visible symbols.
  llvm::pdb::PublicsStream *m_publics = nullptr;

  /// Globals stream.  Contrary to its name, this does not contain information
  /// about all "global variables" or "global functions".  Rather, it is the
  /// "global symbol table", i.e. it contains information about *every* symbol
  /// in the executable.  It is a hash table keyed on name, whose values are
  /// indices into the symbol records stream to find the full record.
  llvm::pdb::GlobalsStream *m_globals = nullptr;

  /// Symbol records stream.  The publics and globals stream refer to records
  /// in this stream.  For some records, like constants and typedefs, the
  /// complete record lives in this stream.  For other symbol types, such as
  /// functions, data, and other things that have been materialied into a
  /// specific compile unit, the records here simply provide a reference
  /// necessary to locate the full information.
  llvm::pdb::SymbolStream *m_symrecords = nullptr;

  /// Index of all compile units, mapping identifier to |CompilandIndexItem|
  /// instance.
  CompileUnitIndex m_cus;

  /// An allocator for the interval maps
  llvm::IntervalMap<lldb::addr_t, uint32_t>::Allocator m_allocator;

  /// Maps virtual address to module index
  llvm::IntervalMap<lldb::addr_t, uint16_t> m_va_to_modi;

  /// The address at which the program has been loaded into memory.
  lldb::addr_t m_load_address = 0;

  PdbIndex();

  void BuildAddrToSymbolMap(CompilandIndexItem &cci);

public:
  static llvm::Expected<std::unique_ptr<PdbIndex>>
      create(std::unique_ptr<llvm::pdb::PDBFile>);

  void SetLoadAddress(lldb::addr_t addr) { m_load_address = addr; }
  lldb::addr_t GetLoadAddress() const { return m_load_address; }
  void ParseSectionContribs();

  llvm::pdb::PDBFile &pdb() { return *m_file; }
  const llvm::pdb::PDBFile &pdb() const { return *m_file; }

  llvm::pdb::DbiStream &dbi() { return *m_dbi; }
  const llvm::pdb::DbiStream &dbi() const { return *m_dbi; }

  llvm::pdb::TpiStream &tpi() { return *m_tpi; }
  const llvm::pdb::TpiStream &tpi() const { return *m_tpi; }

  llvm::pdb::TpiStream &ipi() { return *m_ipi; }
  const llvm::pdb::TpiStream &ipi() const { return *m_ipi; }

  llvm::pdb::InfoStream &info() { return *m_info; }
  const llvm::pdb::InfoStream &info() const { return *m_info; }

  llvm::pdb::PublicsStream &publics() { return *m_publics; }
  const llvm::pdb::PublicsStream &publics() const { return *m_publics; }

  llvm::pdb::GlobalsStream &globals() { return *m_globals; }
  const llvm::pdb::GlobalsStream &globals() const { return *m_globals; }

  llvm::pdb::SymbolStream &symrecords() { return *m_symrecords; }
  const llvm::pdb::SymbolStream &symrecords() const { return *m_symrecords; }

  CompileUnitIndex &compilands() { return m_cus; }
  const CompileUnitIndex &compilands() const { return m_cus; }

  lldb::addr_t MakeVirtualAddress(uint16_t segment, uint32_t offset) const;
  lldb::addr_t MakeVirtualAddress(const SegmentOffset &so) const;

  std::vector<SymbolAndUid> FindSymbolsByVa(lldb::addr_t va);

  llvm::codeview::CVSymbol ReadSymbolRecord(PdbCompilandSymId cu_sym) const;
  llvm::codeview::CVSymbol ReadSymbolRecord(PdbGlobalSymId global) const;

  llvm::Optional<uint16_t> GetModuleIndexForAddr(uint16_t segment,
                                                 uint32_t offset) const;
  llvm::Optional<uint16_t> GetModuleIndexForVa(lldb::addr_t va) const;
};
} // namespace npdb
} // namespace lldb_private

#endif