Index: lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -169,6 +169,13 @@ const llvm::pdb::IPDBSession &GetPDBSession() const; private: + struct SecContribInfo { + uint32_t Offset; + uint32_t Size; + uint32_t CompilandId; + }; + using SecContribsMap = std::map>; + lldb::CompUnitSP ParseCompileUnitForUID(uint32_t id, uint32_t index = UINT32_MAX); @@ -227,9 +234,14 @@ bool DeclContextMatchesThisSymbolFile( const lldb_private::CompilerDeclContext *decl_ctx); + uint32_t GetCompilandId(const llvm::pdb::PDBSymbolData &data); + llvm::DenseMap m_comp_units; llvm::DenseMap m_types; llvm::DenseMap m_variables; + llvm::DenseMap m_public_names; + + SecContribsMap m_sec_contribs; std::vector m_builtin_types; std::unique_ptr m_session_up; Index: lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -534,7 +534,7 @@ auto results = m_global_scope_up->findAllChildren(); if (results && results->getChildCount()) { while (auto result = results->getNext()) { - auto cu_id = result->getCompilandId(); + auto cu_id = GetCompilandId(*result); // FIXME: We are not able to determine variable's compile unit. if (cu_id == 0) continue; @@ -853,24 +853,16 @@ } std::string SymbolFilePDB::GetMangledForPDBData(const PDBSymbolData &pdb_data) { - std::string decorated_name; - auto vm_addr = pdb_data.getVirtualAddress(); - if (vm_addr != LLDB_INVALID_ADDRESS && vm_addr) { - auto result_up = - m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol); - if (result_up) { - while (auto symbol_up = result_up->getNext()) { - if (symbol_up->getRawSymbol().getVirtualAddress() == vm_addr) { - decorated_name = symbol_up->getRawSymbol().getName(); - break; - } - } - } - } - if (!decorated_name.empty()) - return decorated_name; + // Cache public names at first + if (m_public_names.empty()) + if (auto result_up = + m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol)) + while (auto symbol_up = result_up->getNext()) + if (auto addr = symbol_up->getRawSymbol().getVirtualAddress()) + m_public_names[addr] = symbol_up->getRawSymbol().getName(); - return std::string(); + // Look up the name in the cache + return m_public_names.lookup(pdb_data.getVirtualAddress()); } VariableSP SymbolFilePDB::ParseVariableForPDBData( @@ -1070,15 +1062,15 @@ sc.module_sp = m_obj_file->GetModule(); lldbassert(sc.module_sp.get()); - sc.comp_unit = ParseCompileUnitForUID(pdb_data->getCompilandId()).get(); - // FIXME: We are not able to determine the compile unit. - if (sc.comp_unit == nullptr) - continue; - if (!name.GetStringRef().equals( PDBASTParser::PDBNameDropScope(pdb_data->getName()))) continue; + sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get(); + // FIXME: We are not able to determine the compile unit. + if (sc.comp_unit == nullptr) + continue; + auto actual_parent_decl_ctx = GetDeclContextContainingUID(result->getSymIndexId()); if (actual_parent_decl_ctx != *parent_decl_ctx) @@ -1116,7 +1108,7 @@ sc.module_sp = m_obj_file->GetModule(); lldbassert(sc.module_sp.get()); - sc.comp_unit = ParseCompileUnitForUID(pdb_data->getCompilandId()).get(); + sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get(); // FIXME: We are not able to determine the compile unit. if (sc.comp_unit == nullptr) continue; @@ -1882,3 +1874,68 @@ return false; } + +uint32_t SymbolFilePDB::GetCompilandId(const llvm::pdb::PDBSymbolData &data) { + static const auto pred_upper = [](uint32_t lhs, SecContribInfo rhs) { + return lhs < rhs.Offset; + }; + + // Cache section contributions + if (m_sec_contribs.empty()) { + if (auto SecContribs = m_session_up->getSectionContribs()) { + while (auto SectionContrib = SecContribs->getNext()) { + auto comp_id = SectionContrib->getCompilandId(); + if (!comp_id) + continue; + + auto sec = SectionContrib->getAddressSection(); + auto &sec_cs = m_sec_contribs[sec]; + + auto offset = SectionContrib->getAddressOffset(); + auto it = + std::upper_bound(sec_cs.begin(), sec_cs.end(), offset, pred_upper); + + auto size = SectionContrib->getLength(); + sec_cs.insert(it, {offset, size, comp_id}); + } + } + } + + // Check by line number + if (auto Lines = data.getLineNumbers()) { + if (auto FirstLine = Lines->getNext()) + return FirstLine->getCompilandId(); + } + + // Retrieve section + offset + uint32_t DataSection = data.getAddressSection(); + uint32_t DataOffset = data.getAddressOffset(); + if (DataSection == 0) { + if (auto RVA = data.getRelativeVirtualAddress()) + m_session_up->addressForRVA(RVA, DataSection, DataOffset); + } + + if (DataSection) { + // Search by section contributions + auto &sec_cs = m_sec_contribs[DataSection]; + auto it = + std::upper_bound(sec_cs.begin(), sec_cs.end(), DataOffset, pred_upper); + if (it != sec_cs.begin()) { + --it; + if (DataOffset < it->Offset + it->Size) + return it->CompilandId; + } + } else { + // Search in lexical tree + auto LexParentId = data.getLexicalParentId(); + while (auto LexParent = m_session_up->getSymbolById(LexParentId)) { + if (LexParent->getSymTag() == PDB_SymType::Exe) + break; + if (LexParent->getSymTag() == PDB_SymType::Compiland) + return LexParentId; + LexParentId = LexParent->getRawSymbol().getLexicalParentId(); + } + } + + return 0; +}