Files
clang-p2996/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h
Aleksandr Urakov 758657e565 [PDB] Fix location retrieval for function local variables and arguments that are
stored relative to VFRAME

Summary:
This patch makes LLDB able to retrieve proper values for function arguments and
local variables stored in PDB relative to VFRAME register.

Patch contains retrieval of corresponding FPO table entries from PDB and a
generic translator from FPO programs to DWARF expressions to get correct VFRAME
value.

Patch also improves variables-locations.test and makes this test passable on
x86.

Patch By: leonid.mashinsky

Reviewers: zturner, asmith, stella.stamenova, aleksandr.urakov

Reviewed By: zturner

Subscribers: arphaman, labath, mgorny, aprantl, JDevlieghere, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D55122

llvm-svn: 352845
2019-02-01 10:01:18 +00:00

163 lines
6.3 KiB
C++

//===-- 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