zturner created this revision. zturner added a reviewer: clayborg. zturner added a subscriber: lldb-commits.
This is a first attempt at getting `SymbolFilePDB` working with line table support. A few notes: * This won't compile until a corresponding patch goes in on the LLVM side. The patch is done on my side, but not committed yet. * Right now only line tables and compilation units are supported. In particular, this means that "target modules dump line-table <file>" works, and displays output like this: * I checked in some unittests with 2 precompiled binaries and a PDB file for testing purposes. I opted for unittests and checked-in binaries here for a number of reasons. 1. The SB API does not provide a way to test something this low level. 2. Obviously not every platform has the ability to create PDB files. 3. With the help of some magic compiler switches, the binaries are very small. 4. At some point or another this will be unavoidable, as we will want to test "PDB file generated by MSVC on Windows can be read on Linux" 5. I don't feel comfortable checking in something with no tests. (lldb) file d:\src\llvmbuild\ninja\tools\lldb\unittests\SymbolFile\PDB\Inputs\test-pdb.exe Current executable set to 'd:\src\llvmbuild\ninja\tools\lldb\unittests\SymbolFile\PDB\Inputs\test-pdb.exe' (i686). (lldb) target modules dump line-table test-pdb.cpp Line table for test-pdb.cpp in `test-pdb.exe 0x00401020: :4 0x00401030: :6 0x00401033: :8 0x00401035: :9 http://reviews.llvm.org/D17363 Files: cmake/LLDBDependencies.cmake cmake/modules/AddLLDB.cmake source/API/SystemInitializerFull.cpp source/Initialization/SystemInitializerCommon.cpp source/Plugins/SymbolFile/CMakeLists.txt source/Plugins/SymbolFile/PDB/CMakeLists.txt source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp source/Plugins/SymbolFile/PDB/SymbolFilePDB.h unittests/CMakeLists.txt unittests/SymbolFile/CMakeLists.txt unittests/SymbolFile/PDB/CMakeLists.txt unittests/SymbolFile/PDB/Inputs/test-dwarf.cpp unittests/SymbolFile/PDB/Inputs/test-dwarf.exe unittests/SymbolFile/PDB/Inputs/test-pdb.cpp unittests/SymbolFile/PDB/Inputs/test-pdb.exe unittests/SymbolFile/PDB/Inputs/test-pdb.pdb unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp
Index: unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp =================================================================== --- /dev/null +++ unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -0,0 +1,158 @@ +//===-- PythonDataObjectsTests.cpp ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/Config/config.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" + +#include "lldb/Core/Address.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/LineTable.h" +#include "lldb/Symbol/SymbolVendor.h" + +#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" +#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" +#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h" + +#if defined(_MSC_VER) +#include <objbase.h> +#endif + +extern const char *TestMainArgv0; + +using namespace lldb_private; + +class SymbolFilePDBTests : public testing::Test +{ +public: + void + SetUp() override + { +#if defined(_MSC_VER) + ::CoInitializeEx(nullptr, COINIT_MULTITHREADED); +#endif + + HostInfoBase::Initialize(); + ObjectFilePECOFF::Initialize(); + SymbolFileDWARF::Initialize(); + SymbolFilePDB::Initialize(); + + llvm::StringRef exe_folder = llvm::sys::path::parent_path(TestMainArgv0); + llvm::SmallString<128> inputs_folder = exe_folder; + llvm::sys::path::append(inputs_folder, "Inputs"); + + m_pdb_test_exe = inputs_folder; + m_dwarf_test_exe = inputs_folder; + llvm::sys::path::append(m_pdb_test_exe, "test-pdb.exe"); + llvm::sys::path::append(m_dwarf_test_exe, "test-dwarf.exe"); + } + + void + TearDown() override + { +#if defined(_MSC_VER) + ::CoUninitialize(); +#endif + SymbolFilePDB::Terminate(); + SymbolFileDWARF::Terminate(); + ObjectFilePECOFF::Terminate(); + } + +protected: + llvm::SmallString<128> m_pdb_test_exe; + llvm::SmallString<128> m_dwarf_test_exe; + + void + VerifyLineEntry(lldb::ModuleSP module, LineTable <, uint32_t line, lldb::addr_t addr) + { + LineEntry entry; + Address address; + + EXPECT_TRUE(module->ResolveFileAddress(addr, address)); + EXPECT_TRUE(lt.FindLineEntryByAddress(address, entry)); + EXPECT_EQ(line, entry.line); + } +}; + +#if defined(HAVE_DIA_SDK) +#define REQUIRES_DIA_SDK(TestName) TestName +#else +#define REQUIRES_DIA_SDK(TestName) DISABLED_##TestName +#endif + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestAbilitiesForPDB)) +{ + // Test that when we have PDB debug info, SymbolFilePDB is used. + FileSpec fspec(m_pdb_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = SymbolVendor::FindPlugin(module, nullptr); + EXPECT_NE(nullptr, plugin); + SymbolFile *symfile = plugin->GetSymbolFile(); + EXPECT_NE(nullptr, symfile); + EXPECT_EQ(symfile->GetPluginName(), SymbolFilePDB::GetPluginNameStatic()); + + uint32_t expected_abilities = SymbolFile::CompileUnits | SymbolFile::LineTables; + EXPECT_EQ(expected_abilities, symfile->CalculateAbilities()); +} + +TEST_F(SymbolFilePDBTests, TestAbilitiesForDWARF) +{ + // Test that when we have Dwarf debug info, SymbolFileDWARF is used. + FileSpec fspec(m_dwarf_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = SymbolVendor::FindPlugin(module, nullptr); + EXPECT_NE(nullptr, plugin); + SymbolFile *symfile = plugin->GetSymbolFile(); + EXPECT_NE(nullptr, symfile); + EXPECT_EQ(symfile->GetPluginName(), SymbolFileDWARF::GetPluginNameStatic()); + + uint32_t expected_abilities = SymbolFile::kAllAbilities; + EXPECT_EQ(expected_abilities, symfile->CalculateAbilities()); +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestLineTablesForPDB)) +{ + FileSpec fspec(m_pdb_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = SymbolVendor::FindPlugin(module, nullptr); + SymbolFile *symfile = plugin->GetSymbolFile(); + + FileSpec source_file("test-pdb.cpp", false); + uint32_t cus = symfile->GetNumCompileUnits(); + EXPECT_EQ(2, cus); + + SymbolContextList sc_list; + uint32_t count = symfile->ResolveSymbolContext(source_file, 0, false, lldb::eSymbolContextCompUnit, sc_list); + EXPECT_EQ(1, count); + SymbolContext sc; + EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); + EXPECT_TRUE(symfile->ParseCompileUnitLineTable(sc)); + LineTable *lt = sc.comp_unit->GetLineTable(); + EXPECT_NE(nullptr, lt); + count = lt->GetSize(); + EXPECT_EQ(4, count); + VerifyLineEntry(module, *lt, 4, 0x00401020); + VerifyLineEntry(module, *lt, 6, 0x00401030); + VerifyLineEntry(module, *lt, 8, 0x00401033); + VerifyLineEntry(module, *lt, 9, 0x00401035); +} Index: unittests/SymbolFile/PDB/Inputs/test-pdb.cpp =================================================================== --- /dev/null +++ unittests/SymbolFile/PDB/Inputs/test-pdb.cpp @@ -0,0 +1,14 @@ +// Compile with "cl /c /Zi /GR- test-pdb.cpp" +// Link with "link test-pdb.obj /debug /nodefaultlib /entry:main /out:test-pdb.exe" + +int __cdecl _purecall(void) +{ + return 0; +} + +int +main(int argc, char **argv) +{ + + return 0; +} Index: unittests/SymbolFile/PDB/Inputs/test-dwarf.cpp =================================================================== --- /dev/null +++ unittests/SymbolFile/PDB/Inputs/test-dwarf.cpp @@ -0,0 +1,14 @@ +// Compile with "cl /c /Zi /GR- test.cpp" +// Link with "link test.obj /debug /nodefaultlib /entry:main /out:test.exe" + +int __cdecl _purecall(void) +{ + return 0; +} + +int +main(int argc, char **argv) +{ + + return 0; +} Index: unittests/SymbolFile/PDB/CMakeLists.txt =================================================================== --- /dev/null +++ unittests/SymbolFile/PDB/CMakeLists.txt @@ -0,0 +1,10 @@ +add_lldb_unittest(SymbolFilePDBTests + SymbolFilePDBTests.cpp + ) + +set(test_inputs + test-pdb.exe + test-pdb.pdb + test-dwarf.exe) + +add_unittest_inputs(SymbolFilePDBTests "${test_inputs}") Index: unittests/SymbolFile/CMakeLists.txt =================================================================== --- /dev/null +++ unittests/SymbolFile/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(PDB) Index: unittests/CMakeLists.txt =================================================================== --- unittests/CMakeLists.txt +++ unittests/CMakeLists.txt @@ -18,15 +18,31 @@ ${ARGN} ) + add_custom_command( + TARGET ${test_name} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/Inputs) + lldb_link_common_libs(${test_name} EXE) target_link_libraries(${test_name} ${CLANG_USED_LIBS} ${LLDB_SYSTEM_LIBS}) llvm_config(${test_name} ${LLVM_LINK_COMPONENTS}) endfunction() +function(add_unittest_inputs test_name inputs) + foreach (INPUT ${inputs}) + add_custom_command( + TARGET ${test_name} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy ${CMAKE_CURRENT_SOURCE_DIR}/Inputs/${INPUT} ${CMAKE_CURRENT_BINARY_DIR}/Inputs + COMMENT "Copying ${INPUT} to binary directory.") + endforeach() +endfunction() + add_subdirectory(Core) add_subdirectory(Editline) add_subdirectory(Expression) add_subdirectory(Host) add_subdirectory(Interpreter) add_subdirectory(ScriptInterpreter) +add_subdirectory(SymbolFile) add_subdirectory(Utility) Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.h =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -0,0 +1,185 @@ +//===-- SymbolFilePDB.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ +#define lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ + +#include <unordered_map> + +#include "lldb/Core/UserID.h" +#include "lldb/Symbol/SymbolFile.h" + +#include "llvm/DebugInfo/PDB/IPDBSession.h" +#include "llvm/DebugInfo/PDB/PDB.h" + +class SymbolFilePDB : public lldb_private::SymbolFile +{ +public: + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void + Initialize(); + + static void + Terminate(); + + static void + DebuggerInitialize(lldb_private::Debugger &debugger); + + static lldb_private::ConstString + GetPluginNameStatic(); + + static const char * + GetPluginDescriptionStatic(); + + static lldb_private::SymbolFile * + CreateInstance(lldb_private::ObjectFile *obj_file); + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + SymbolFilePDB(lldb_private::ObjectFile *ofile); + + ~SymbolFilePDB() override; + + uint32_t + CalculateAbilities() override; + + void + InitializeObject() override; + + //------------------------------------------------------------------ + // Compile Unit function calls + //------------------------------------------------------------------ + + uint32_t + GetNumCompileUnits() override; + + lldb::CompUnitSP + ParseCompileUnitAtIndex(uint32_t index) override; + + lldb::LanguageType + ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override; + + size_t + ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override; + + bool + ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override; + + bool + ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override; + + bool + ParseCompileUnitSupportFiles(const lldb_private::SymbolContext &sc, + lldb_private::FileSpecList &support_files) override; + + bool + ParseImportedModules(const lldb_private::SymbolContext &sc, + std::vector<lldb_private::ConstString> &imported_modules) override; + + size_t + ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override; + + size_t + ParseTypes(const lldb_private::SymbolContext &sc) override; + + size_t + ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; + + lldb_private::Type * + ResolveTypeUID(lldb::user_id_t type_uid) override; + + bool + CompleteType(lldb_private::CompilerType &compiler_type) override; + + lldb_private::CompilerDecl + GetDeclForUID(lldb::user_id_t uid) override; + + lldb_private::CompilerDeclContext + GetDeclContextForUID(lldb::user_id_t uid) override; + + lldb_private::CompilerDeclContext + GetDeclContextContainingUID(lldb::user_id_t uid) override; + + void + ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override; + + uint32_t + ResolveSymbolContext(const lldb_private::Address &so_addr, uint32_t resolve_scope, + lldb_private::SymbolContext &sc) override; + + uint32_t + ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines, + uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) override; + + uint32_t + FindGlobalVariables(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, + bool append, uint32_t max_matches, lldb_private::VariableList &variables) override; + + uint32_t + FindGlobalVariables(const lldb_private::RegularExpression ®ex, bool append, uint32_t max_matches, + lldb_private::VariableList &variables) override; + + uint32_t + FindFunctions(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, + uint32_t name_type_mask, bool include_inlines, bool append, + lldb_private::SymbolContextList &sc_list) override; + + uint32_t + FindFunctions(const lldb_private::RegularExpression ®ex, bool include_inlines, bool append, + lldb_private::SymbolContextList &sc_list) override; + + void + GetMangledNamesForFunction(const std::string &scope_qualified_name, + std::vector<lldb_private::ConstString> &mangled_names) override; + + uint32_t + FindTypes(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, + const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, + llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap &types) override; + + size_t + FindTypes(const std::vector<lldb_private::CompilerContext> &context, bool append, + lldb_private::TypeMap &types) override; + + lldb_private::TypeList * + GetTypeList() override; + + size_t + GetTypes(lldb_private::SymbolContextScope *sc_scope, uint32_t type_mask, + lldb_private::TypeList &type_list) override; + + lldb_private::TypeSystem * + GetTypeSystemForLanguage(lldb::LanguageType language) override; + + lldb_private::CompilerDeclContext + FindNamespace(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, + const lldb_private::CompilerDeclContext *parent_decl_ctx) override; + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + lldb_private::ConstString + GetPluginName() override; + + uint32_t + GetPluginVersion() override; + +private: + lldb::CompUnitSP + ParseCompileUnitForSymIndex(uint32_t id); + + std::unordered_map<uint32_t, lldb::CompUnitSP> m_comp_units; + + std::unique_ptr<llvm::IPDBSession> m_session; +}; + +#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -0,0 +1,403 @@ +//===-- SymbolFilePDB.cpp ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "SymbolFilePDB.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/LineTable.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolContext.h" + +#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" +#include "llvm/DebugInfo/PDB/IPDBLineNumber.h" +#include "llvm/DebugInfo/PDB/IPDBSourceFile.h" +#include "llvm/DebugInfo/PDB/PDBSymbol.h" +#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" +#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h" +#include "llvm/DebugInfo/PDB/PDBSymbolExe.h" + +using namespace lldb_private; + +void +SymbolFilePDB::Initialize() +{ + PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, + DebuggerInitialize); +} + +void +SymbolFilePDB::Terminate() +{ + PluginManager::UnregisterPlugin(CreateInstance); +} + +void +SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) +{ +} + +lldb_private::ConstString +SymbolFilePDB::GetPluginNameStatic() +{ + static ConstString g_name("pdb"); + return g_name; +} + +const char * +SymbolFilePDB::GetPluginDescriptionStatic() +{ + return "Microsoft PDB debug symbol file reader."; +} + +lldb_private::SymbolFile * +SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) +{ + return new SymbolFilePDB(obj_file); +} + +SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *ofile) : SymbolFile(ofile) +{ +} + +SymbolFilePDB::~SymbolFilePDB() +{ +} + +uint32_t +SymbolFilePDB::CalculateAbilities() +{ + if (!m_session) + { + // Lazily load and match the PDB file, but only do this once. + std::string exePath = m_obj_file->GetFileSpec().GetPath(); + auto error = llvm::loadDataForEXE(llvm::PDB_ReaderType::DIA, llvm::StringRef(exePath), m_session); + if (error != llvm::PDB_ErrorCode::Success) + return 0; + } + return CompileUnits | LineTables; +} + +void +SymbolFilePDB::InitializeObject() +{ + lldb::addr_t obj_load_address = m_obj_file->GetFileOffset(); + m_session->setLoadAddress(obj_load_address); +} + +uint32_t +SymbolFilePDB::GetNumCompileUnits() +{ + auto global = m_session->getGlobalScope(); + auto compilands = global->findAllChildren<llvm::PDBSymbolCompiland>(); + return compilands->getChildCount(); +} + +lldb::CompUnitSP +SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) +{ + auto global = m_session->getGlobalScope(); + auto compilands = global->findAllChildren<llvm::PDBSymbolCompiland>(); + auto cu = compilands->getChildAtIndex(index); + + uint32_t id = cu->getSymIndexId(); + + return ParseCompileUnitForSymIndex(id); +} + +lldb::LanguageType +SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) +{ + // Default to C++, currently DebugInfoPDB does not return the language. + return lldb::eLanguageTypeC_plus_plus; +} + +size_t +SymbolFilePDB::ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) +{ + // TODO: Implement this + return size_t(); +} + +bool +SymbolFilePDB::ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) +{ + auto global = m_session->getGlobalScope(); + auto cu = m_session->getConcreteSymbolById<llvm::PDBSymbolCompiland>(sc.comp_unit->GetID()); + + std::string path = sc.comp_unit->GetPath(); + auto file = m_session->findOneSourceFile(cu.get(), path.c_str(), llvm::PDB_NameSearchFlags::NS_CaseInsensitive); + auto line_table = llvm::make_unique<LineTable>(sc.comp_unit); + + std::unique_ptr<LineSequence> sequence(line_table->CreateLineSequenceContainer()); + auto lines = m_session->findLineNumbers(*cu, *file); + int entry_count = lines->getChildCount(); + for (int i = 0; i < entry_count; ++i) + { + auto line = lines->getChildAtIndex(i); + + uint32_t va = line->getVirtualAddress(); + uint32_t lno = line->getLineNumber(); + uint32_t cno = line->getColumnNumber(); + uint32_t source_id = line->getSourceFileId(); + bool is_statement = line->isStatement(); + line_table->AppendLineEntryToSequence(sequence.get(), va, lno, cno, source_id, is_statement, + false, // How to determine if this is the start of a basic block? + false, // How to determine if this is the end of a prologue? + false, // How to determine if this is the start of an epilogue? + false); // Is a termination entry even required? + } + line_table->InsertSequence(sequence.get()); + sc.comp_unit->SetLineTable(line_table.release()); + return true; +} + +bool +SymbolFilePDB::ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) +{ + // PDB doesn't contain information about macros + return false; +} + +bool +SymbolFilePDB::ParseCompileUnitSupportFiles(const lldb_private::SymbolContext &sc, + lldb_private::FileSpecList &support_files) +{ + // TODO: What are support files? + return false; +} + +bool +SymbolFilePDB::ParseImportedModules(const lldb_private::SymbolContext &sc, + std::vector<lldb_private::ConstString> &imported_modules) +{ + // PDB does not yet support module debug info + return false; +} + +size_t +SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc) +{ + // TODO: Implement this + return size_t(); +} + +size_t +SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) +{ + // TODO: Implement this + return size_t(); +} + +size_t +SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) +{ + // TODO: Implement this + return size_t(); +} + +lldb_private::Type * +SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) +{ + return nullptr; +} + +bool +SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) +{ + // TODO: Implement this + return false; +} + +lldb_private::CompilerDecl +SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) +{ + return lldb_private::CompilerDecl(); +} + +lldb_private::CompilerDeclContext +SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) +{ + return lldb_private::CompilerDeclContext(); +} + +lldb_private::CompilerDeclContext +SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) +{ + return lldb_private::CompilerDeclContext(); +} + +void +SymbolFilePDB::ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) +{ +} + +uint32_t +SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, uint32_t resolve_scope, + lldb_private::SymbolContext &sc) +{ + return uint32_t(); +} + +uint32_t +SymbolFilePDB::ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines, + uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) +{ + if (resolve_scope & lldb::eSymbolContextCompUnit) + { + // Locate all compilation units for the given source file. + auto compilands = + m_session->findCompilandsForSourceFile(file_spec.GetPath(), llvm::PDB_NameSearchFlags::NS_CaseInsensitive); + + // For each one, either find it or parse it and add it to the symbol context list. + while (auto compiland = compilands->getNext()) + { + SymbolContext sc; + auto cu = ParseCompileUnitForSymIndex(compiland->getSymIndexId()); + sc.comp_unit = cu.get(); + sc.module_sp = cu->GetModule(); + sc_list.Append(sc); + } + } + return sc_list.GetSize(); +} + +uint32_t +SymbolFilePDB::FindGlobalVariables(const lldb_private::ConstString &name, + const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, + uint32_t max_matches, lldb_private::VariableList &variables) +{ + return uint32_t(); +} + +uint32_t +SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression ®ex, bool append, uint32_t max_matches, + lldb_private::VariableList &variables) +{ + return uint32_t(); +} + +uint32_t +SymbolFilePDB::FindFunctions(const lldb_private::ConstString &name, + const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, + bool include_inlines, bool append, lldb_private::SymbolContextList &sc_list) +{ + return uint32_t(); +} + +uint32_t +SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression ®ex, bool include_inlines, bool append, + lldb_private::SymbolContextList &sc_list) +{ + return uint32_t(); +} + +void +SymbolFilePDB::GetMangledNamesForFunction(const std::string &scope_qualified_name, + std::vector<lldb_private::ConstString> &mangled_names) +{ +} + +uint32_t +SymbolFilePDB::FindTypes(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, + const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, + llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, + lldb_private::TypeMap &types) +{ + return uint32_t(); +} + +size_t +SymbolFilePDB::FindTypes(const std::vector<lldb_private::CompilerContext> &context, bool append, + lldb_private::TypeMap &types) +{ + return size_t(); +} + +lldb_private::TypeList * +SymbolFilePDB::GetTypeList() +{ + return nullptr; +} + +size_t +SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, uint32_t type_mask, + lldb_private::TypeList &type_list) +{ + return size_t(); +} + +lldb_private::TypeSystem * +SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) +{ + auto type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language); + if (type_system) + type_system->SetSymbolFile(this); + return type_system; +} + +lldb_private::CompilerDeclContext +SymbolFilePDB::FindNamespace(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, + const lldb_private::CompilerDeclContext *parent_decl_ctx) +{ + return lldb_private::CompilerDeclContext(); +} + +lldb_private::ConstString +SymbolFilePDB::GetPluginName() +{ + return GetPluginNameStatic(); +} + +uint32_t +SymbolFilePDB::GetPluginVersion() +{ + return 1; +} + +lldb::CompUnitSP +SymbolFilePDB::ParseCompileUnitForSymIndex(uint32_t id) +{ + auto found_cu = m_comp_units.find(id); + if (found_cu != m_comp_units.end()) + return found_cu->second; + + auto cu = m_session->getConcreteSymbolById<llvm::PDBSymbolCompiland>(id); + + // This frequently (i.e. in all cases I've seen) returns null. Hopefully + // LLDB can handle null values for this. + FileSpec path(cu->getSourceFileName(), false); + + lldb::LanguageType lang; + auto details = cu->findOneChild<llvm::PDBSymbolCompilandDetails>(); + if (!details) + lang = lldb::eLanguageTypeC_plus_plus; + else + { + switch (details->getLanguage()) + { + case llvm::PDB_Lang::Cpp: + lang = lldb::LanguageType::eLanguageTypeC_plus_plus; + break; + case llvm::PDB_Lang::C: + lang = lldb::LanguageType::eLanguageTypeC; + break; + default: + lang = lldb::LanguageType::eLanguageTypeUnknown; + break; + } + } + + // Don't support optimized code for now, DebugInfoPDB does not return this information. + bool optimized = false; + auto result = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr, path, id, lang, optimized); + m_comp_units.insert(std::make_pair(id, result)); + return result; +} Index: source/Plugins/SymbolFile/PDB/CMakeLists.txt =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/PDB/CMakeLists.txt @@ -0,0 +1,6 @@ +set(LLVM_PRIVATE_LINK_COMPONENTS + DebugInfoPDB) + +add_lldb_library(lldbPluginSymbolFilePDB + SymbolFilePDB.cpp + ) Index: source/Plugins/SymbolFile/CMakeLists.txt =================================================================== --- source/Plugins/SymbolFile/CMakeLists.txt +++ source/Plugins/SymbolFile/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(DWARF) add_subdirectory(Symtab) +add_subdirectory(PDB) Index: source/Initialization/SystemInitializerCommon.cpp =================================================================== --- source/Initialization/SystemInitializerCommon.cpp +++ source/Initialization/SystemInitializerCommon.cpp @@ -49,8 +49,9 @@ #endif #if defined(_MSC_VER) -#include "lldb/Host/windows/windows.h" #include "Plugins/Process/Windows/Common/ProcessWindowsLog.h" +#include "lldb/Host/windows/windows.h" +#include <objbase.h> #endif #include "llvm/Support/TargetSelect.h" @@ -93,6 +94,8 @@ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); } + + ::CoInitializeEx(nullptr, COINIT_MULTITHREADED); #endif Log::Initialize(); @@ -195,4 +198,8 @@ OperatingSystemGo::Terminate(); Log::Terminate(); + +#if defined(_MSC_VER) + ::CoUninitialize(); +#endif } Index: source/API/SystemInitializerFull.cpp =================================================================== --- source/API/SystemInitializerFull.cpp +++ source/API/SystemInitializerFull.cpp @@ -27,18 +27,18 @@ #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/GoASTContext.h" -#include "Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h" #include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h" #include "Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h" +#include "Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h" #include "Plugins/ABI/SysV-arm/ABISysV_arm.h" #include "Plugins/ABI/SysV-arm64/ABISysV_arm64.h" #include "Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h" #include "Plugins/ABI/SysV-i386/ABISysV_i386.h" -#include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h" -#include "Plugins/ABI/SysV-ppc/ABISysV_ppc.h" -#include "Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h" #include "Plugins/ABI/SysV-mips/ABISysV_mips.h" #include "Plugins/ABI/SysV-mips64/ABISysV_mips64.h" +#include "Plugins/ABI/SysV-ppc/ABISysV_ppc.h" +#include "Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h" +#include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h" #include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h" #include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h" #include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h" @@ -49,9 +49,9 @@ #include "Plugins/Language/ObjC/ObjCLanguage.h" #include "Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h" #include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h" +#include "Plugins/LanguageRuntime/Go/GoLanguageRuntime.h" #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h" #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h" -#include "Plugins/LanguageRuntime/Go/GoLanguageRuntime.h" #include "Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h" #include "Plugins/MemoryHistory/asan/MemoryHistoryASan.h" #include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h" @@ -60,11 +60,12 @@ #include "Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h" +#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h" #include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h" #include "Plugins/SymbolVendor/ELF/SymbolVendorELF.h" #include "Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h" -#include "Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h" #include "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h" +#include "Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h" #if defined(__APPLE__) #include "Plugins/Process/mach-core/ProcessMachCore.h" @@ -297,6 +298,7 @@ SymbolVendorELF::Initialize(); SymbolFileDWARF::Initialize(); + SymbolFilePDB::Initialize(); SymbolFileSymtab::Initialize(); UnwindAssemblyInstEmulation::Initialize(); UnwindAssembly_x86::Initialize(); @@ -415,6 +417,7 @@ AddressSanitizerRuntime::Terminate(); SymbolVendorELF::Terminate(); SymbolFileDWARF::Terminate(); + SymbolFilePDB::Terminate(); SymbolFileSymtab::Terminate(); UnwindAssembly_x86::Terminate(); UnwindAssemblyInstEmulation::Terminate(); Index: cmake/modules/AddLLDB.cmake =================================================================== --- cmake/modules/AddLLDB.cmake +++ cmake/modules/AddLLDB.cmake @@ -68,7 +68,7 @@ target_link_libraries(${name} ${cmake_2_8_12_PUBLIC} ${CLANG_USED_LIBS}) endif() endif() - llvm_config(${name} ${LLVM_LINK_COMPONENTS}) + llvm_config(${name} ${LLVM_LINK_COMPONENTS} ${LLVM_PRIVATE_LINK_COMPONENTS}) if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "liblldb") if (PARAM_SHARED) Index: cmake/LLDBDependencies.cmake =================================================================== --- cmake/LLDBDependencies.cmake +++ cmake/LLDBDependencies.cmake @@ -15,6 +15,7 @@ # Plugins lldbPluginDisassemblerLLVM lldbPluginSymbolFileDWARF + lldbPluginSymbolFilePDB lldbPluginSymbolFileSymtab lldbPluginDynamicLoaderStatic lldbPluginDynamicLoaderPosixDYLD @@ -172,7 +173,7 @@ endif() endif() -set( LLVM_LINK_COMPONENTS +set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} interpreter asmparser
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits