Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp =================================================================== --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -21,9 +21,11 @@ #include "lldb/Symbol/TypeMap.h" #include "llvm/DebugInfo/PDB/GenericError.h" +#include "llvm/DebugInfo/PDB/IPDBDataStream.h" #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" #include "llvm/DebugInfo/PDB/IPDBLineNumber.h" #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" +#include "llvm/DebugInfo/PDB/IPDBTable.h" #include "llvm/DebugInfo/PDB/PDBSymbol.h" #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" #include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h" @@ -93,6 +95,9 @@ SymbolFilePDB::~SymbolFilePDB() {} uint32_t SymbolFilePDB::CalculateAbilities() { + uint32_t abilities = 0; + if (!m_obj_file) + return 0; if (!m_session_up) { // Lazily load and match the PDB file, but only do this once. std::string exePath = m_obj_file->GetFileSpec().GetPath(); @@ -100,10 +105,71 @@ m_session_up); if (error) { llvm::consumeError(std::move(error)); - return 0; + if (auto module_sp = m_obj_file->GetModule()) { + // See if a symbol file was specified through the `--symfile` option. + FileSpec symfile = module_sp->GetSymbolFileFileSpec(); + if (symfile) { + error = loadDataForPDB(PDB_ReaderType::DIA, + llvm::StringRef(symfile.GetPath()), + m_session_up); + if (error) { + llvm::consumeError(std::move(error)); + return 0; + } + } else { + return 0; + } + } else { + return 0; + } + } + } + lldbassert(m_session_up.get()); + if (auto enum_tables_up = m_session_up->getEnumTables()) { + while (auto table_up = enum_tables_up->getNext()) { + if (table_up->getItemCount()) { + auto type = table_up->getTableType(); + switch (type) { + case PDB_TableType::SectionContribs: + // This table contains module/compiland information. + abilities |= CompileUnits; + break; + case PDB_TableType::Symbols: + abilities |= (Functions | Blocks); + // Check if there are sections of raw data for any variables + // in the `SECTIONHEADERS` data stream. + if (auto enum_dbg_streams_up = m_session_up->getDebugStreams()) { + while (auto dbg_stream_up = enum_dbg_streams_up->getNext()) { + auto stream_name = dbg_stream_up->getName(); + if (stream_name == "SECTIONHEADERS") { + for (int rec_idx = 0; + rec_idx < dbg_stream_up->getRecordCount(); + rec_idx++) { + auto record = dbg_stream_up->getItemAtIndex(rec_idx); + auto record_pointer = + reinterpret_cast(record->data()); + if (strncmp(record_pointer, ".data", 5) == 0 || + strncmp(record_pointer, ".bss", 4) == 0 || + strncmp(record_pointer, ".rdata", 6) == 0) { + abilities |= (GlobalVariables | LocalVariables | + VariableTypes); + break; + } + } + } + } + } + break; + case PDB_TableType::LineNumbers: + abilities |= LineTables; + break; + default: + break; + } + } } } - return CompileUnits | LineTables; + return abilities; } void SymbolFilePDB::InitializeObject() { Index: unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp =================================================================== --- unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -154,8 +154,7 @@ EXPECT_NE(nullptr, symfile); EXPECT_EQ(symfile->GetPluginName(), SymbolFilePDB::GetPluginNameStatic()); - uint32_t expected_abilities = - SymbolFile::CompileUnits | SymbolFile::LineTables; + uint32_t expected_abilities = SymbolFile::kAllAbilities; EXPECT_EQ(expected_abilities, symfile->CalculateAbilities()); }