diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile')
11 files changed, 143 insertions, 54 deletions
diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp index ce2ba69..14932e9 100644 --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -437,7 +437,7 @@ void SymbolFileBreakpad::FindFunctions( sc.comp_unit = cu_sp.get(); sc.function = func_sp.get(); sc.module_sp = func_sp->CalculateSymbolContextModule(); - sc_list.Append(sc); + sc_list.AppendIfUnique(sc, /*merge_symbol_into_function=*/true); } } } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 63b2dc4..d65aa40 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -623,6 +623,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, switch (tag) { case DW_TAG_typedef: + case DW_TAG_template_alias: case DW_TAG_base_type: case DW_TAG_pointer_type: case DW_TAG_reference_type: @@ -748,7 +749,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc, TypeSP type_sp; CompilerType clang_type; - if (tag == DW_TAG_typedef) { + if (tag == DW_TAG_typedef || tag == DW_TAG_template_alias) { // DeclContext will be populated when the clang type is materialized in // Type::ResolveCompilerType. PrepareContextToReceiveMembers( @@ -836,6 +837,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc, encoding_data_type = Type::eEncodingIsRValueReferenceUID; break; case DW_TAG_typedef: + case DW_TAG_template_alias: encoding_data_type = Type::eEncodingIsTypedefUID; break; case DW_TAG_const_type: @@ -1705,8 +1707,11 @@ void DWARFASTParserClang::GetUniqueTypeNameAndDeclaration( // For C++, we rely solely upon the one definition rule that says // only one thing can exist at a given decl context. We ignore the // file and line that things are declared on. - if (!die.IsValid() || !Language::LanguageIsCPlusPlus(language) || - unique_typename.IsEmpty()) + // FIXME: Rust pretends to be C++ for now, so use C++ name qualification rules + if (!Language::LanguageIsCPlusPlus(language) && + language != lldb::eLanguageTypeRust) + return; + if (!die.IsValid() || unique_typename.IsEmpty()) return; decl_declaration.Clear(); std::string qualified_name; @@ -3704,12 +3709,10 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( } } - DWARFASTParserClang *src_dwarf_ast_parser = - static_cast<DWARFASTParserClang *>( - SymbolFileDWARF::GetDWARFParser(*src_class_die.GetCU())); - DWARFASTParserClang *dst_dwarf_ast_parser = - static_cast<DWARFASTParserClang *>( - SymbolFileDWARF::GetDWARFParser(*dst_class_die.GetCU())); + auto *src_dwarf_ast_parser = llvm::cast<DWARFASTParserClang>( + SymbolFileDWARF::GetDWARFParser(*src_class_die.GetCU())); + auto *dst_dwarf_ast_parser = llvm::cast<DWARFASTParserClang>( + SymbolFileDWARF::GetDWARFParser(*dst_class_die.GetCU())); auto link = [&](DWARFDIE src, DWARFDIE dst) { auto &die_to_type = dst_class_die.GetDWARF()->GetDIEToType(); clang::DeclContext *dst_decl_ctx = diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index f5f7071..6eb2b6b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -47,6 +47,11 @@ public: ~DWARFASTParserClang() override; + // LLVM RTTI support + static bool classof(const DWARFASTParser *Parser) { + return Parser->GetKind() == Kind::DWARFASTParserClang; + } + // DWARFASTParser interface. lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, @@ -264,10 +269,6 @@ protected: lldb::ModuleSP GetModuleForType(const lldb_private::plugin::dwarf::DWARFDIE &die); - static bool classof(const DWARFASTParser *Parser) { - return Parser->GetKind() == Kind::DWARFASTParserClang; - } - private: struct FieldInfo { /// Size in bits that this field occupies. Can but diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp index 64a8005..c4efc06 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp @@ -173,6 +173,14 @@ void DWARFIndex::GetNamespacesWithParents( }); } +void DWARFIndex::GetFunctions( + const std::vector<Module::LookupInfo> &lookup_infos, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, + llvm::function_ref<IterationAction(DWARFDIE die)> callback) { + for (auto &lookup_info : lookup_infos) + GetFunctions(lookup_info, dwarf, parent_decl_ctx, callback); +} + IterationAction DWARFIndex::ProcessNamespaceDieMatchParents( const CompilerDeclContext &parent_decl_ctx, DWARFDIE die, llvm::function_ref<IterationAction(DWARFDIE die)> callback) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h index be73255..eaf1da1 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h @@ -86,6 +86,11 @@ public: const CompilerDeclContext &parent_decl_ctx, llvm::function_ref<IterationAction(DWARFDIE die)> callback) = 0; virtual void + GetFunctions(const std::vector<Module::LookupInfo> &lookup_infos, + SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, + llvm::function_ref<IterationAction(DWARFDIE die)> callback); + virtual void GetFunctions(const RegularExpression ®ex, llvm::function_ref<IterationAction(DWARFDIE die)> callback) = 0; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 94fc2e83..b78e6ce8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -348,6 +348,10 @@ void DWARFUnit::ExtractDIEsRWLocked() { void DWARFUnit::SetDwoStrOffsetsBase() { lldb::offset_t baseOffset = 0; + // Size of offset for .debug_str_offsets is same as DWARF offset byte size + // of the DWARFUnit as a default. We might override this if below if needed. + m_str_offset_size = m_header.getDwarfOffsetByteSize(); + if (const llvm::DWARFUnitIndex::Entry *entry = m_header.getIndexEntry()) { if (const auto *contribution = entry->getContribution(llvm::DW_SECT_STR_OFFSETS)) @@ -357,14 +361,17 @@ void DWARFUnit::SetDwoStrOffsetsBase() { } if (GetVersion() >= 5) { - const DWARFDataExtractor &strOffsets = - GetSymbolFileDWARF().GetDWARFContext().getOrLoadStrOffsetsData(); - uint64_t length = strOffsets.GetU32(&baseOffset); - if (length == 0xffffffff) - length = strOffsets.GetU64(&baseOffset); - + const llvm::DWARFDataExtractor &strOffsets = GetSymbolFileDWARF() + .GetDWARFContext() + .getOrLoadStrOffsetsData() + .GetAsLLVMDWARF(); + + uint64_t length; + llvm::dwarf::DwarfFormat format; + std::tie(length, format) = strOffsets.getInitialLength(&baseOffset); + m_str_offset_size = format == llvm::dwarf::DwarfFormat::DWARF64 ? 8 : 4; // Check version. - if (strOffsets.GetU16(&baseOffset) < 5) + if (strOffsets.getU16(&baseOffset) < 5) return; // Skip padding. @@ -409,7 +416,16 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { SetRangesBase(form_value.Unsigned()); break; case DW_AT_str_offsets_base: + // When we have a DW_AT_str_offsets_base attribute, it points us to the + // first string offset for this DWARFUnit which is after the string + // offsets table header. In this case we use the DWARF32/DWARF64 of the + // DWARFUnit to determine the string offset byte size. DWO files do not + // use this attribute and they point to the start of the string offsets + // table header which can be used to determine the DWARF32/DWARF64 status + // of the string table. See SetDwoStrOffsetsBase() for now it figures out + // the m_str_offset_size value that should be used. SetStrOffsetsBase(form_value.Unsigned()); + m_str_offset_size = m_header.getDwarfOffsetByteSize(); break; case DW_AT_low_pc: SetBaseAddress(form_value.Address()); @@ -1079,10 +1095,9 @@ uint32_t DWARFUnit::GetHeaderByteSize() const { return m_header.getSize(); } std::optional<uint64_t> DWARFUnit::GetStringOffsetSectionItem(uint32_t index) const { - lldb::offset_t offset = - GetStrOffsetsBase() + index * m_header.getDwarfOffsetByteSize(); + lldb::offset_t offset = GetStrOffsetsBase() + index * m_str_offset_size; return m_dwarf.GetDWARFContext().getOrLoadStrOffsetsData().GetMaxU64( - &offset, m_header.getDwarfOffsetByteSize()); + &offset, m_str_offset_size); } llvm::Expected<llvm::DWARFAddressRangesVector> diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 91a6938..b5199a8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -364,6 +364,7 @@ protected: dw_offset_t m_line_table_offset = DW_INVALID_OFFSET; dw_offset_t m_str_offsets_base = 0; // Value of DW_AT_str_offsets_base. + dw_offset_t m_str_offset_size = 4; // Size in bytes of a string offset. std::optional<llvm::DWARFDebugRnglistTable> m_rnglist_table; bool m_rnglist_table_done = false; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 881268b..b755f3a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -794,12 +794,12 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { } else { ModuleSP module_sp(m_objfile_sp->GetModule()); if (module_sp) { - auto initialize_cu = [&](lldb::SupportFileSP support_file_sp, + auto initialize_cu = [&](SupportFileNSP support_file_nsp, LanguageType cu_language, SupportFileList &&support_files = {}) { BuildCuTranslationTable(); cu_sp = std::make_shared<CompileUnit>( - module_sp, &dwarf_cu, support_file_sp, + module_sp, &dwarf_cu, support_file_nsp, *GetDWARFUnitIndex(dwarf_cu.GetID()), cu_language, eLazyBoolCalculate, std::move(support_files)); @@ -1560,8 +1560,8 @@ bool SymbolFileDWARF::HasForwardDeclForCompilerType( auto clang_type_system = compiler_type.GetTypeSystem<TypeSystemClang>(); if (!clang_type_system) return false; - DWARFASTParserClang *ast_parser = - static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser()); + auto *ast_parser = + llvm::cast<DWARFASTParserClang>(clang_type_system->GetDWARFParser()); return ast_parser->GetClangASTImporter().CanImport(compiler_type); } @@ -1569,8 +1569,8 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); auto clang_type_system = compiler_type.GetTypeSystem<TypeSystemClang>(); if (clang_type_system) { - DWARFASTParserClang *ast_parser = - static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser()); + auto *ast_parser = + llvm::cast<DWARFASTParserClang>(clang_type_system->GetDWARFParser()); if (ast_parser && ast_parser->GetClangASTImporter().CanImport(compiler_type)) return ast_parser->GetClangASTImporter().CompleteType(compiler_type); @@ -1614,8 +1614,7 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) { if (decl_die != def_die) { GetDIEToType()[def_die.GetDIE()] = type; - DWARFASTParserClang *ast_parser = - static_cast<DWARFASTParserClang *>(dwarf_ast); + auto *ast_parser = llvm::cast<DWARFASTParserClang>(dwarf_ast); ast_parser->MapDeclDIEToDefDIE(decl_die, def_die); } @@ -2018,7 +2017,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { } Status error = ModuleList::GetSharedModule(dwo_module_spec, module_sp, - nullptr, nullptr, nullptr); + nullptr, nullptr); if (!module_sp) { // ReportWarning also rate-limits based on the warning string, // but in a -gmodules build, each object file has a similar DAG @@ -2341,7 +2340,7 @@ void SymbolFileDWARF::FindGlobalVariables( bool name_is_mangled = Mangled::GetManglingScheme(name.GetStringRef()) != Mangled::eManglingSchemeNone; - if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name.GetCString(), + if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name.GetStringRef(), context, basename)) basename = name.GetStringRef(); @@ -2482,7 +2481,7 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, sc.block = function_block.FindBlockByID(inlined_die.GetOffset()); } - sc_list.Append(sc); + sc_list.AppendIfUnique(sc, /*merge_symbol_into_function=*/true); return true; } @@ -2550,11 +2549,11 @@ SymbolFileDWARF::FindFunctionDefinition(const FunctionCallLabel &label, const DWARFDIE &declaration) { auto do_lookup = [this](llvm::StringRef lookup_name) -> DWARFDIE { DWARFDIE found; - Module::LookupInfo info(ConstString(lookup_name), - lldb::eFunctionNameTypeFull, - lldb::eLanguageTypeUnknown); + auto lookup_infos = Module::LookupInfo::MakeLookupInfos( + ConstString(lookup_name), lldb::eFunctionNameTypeFull, + lldb::eLanguageTypeUnknown); - m_index->GetFunctions(info, *this, {}, [&](DWARFDIE entry) { + m_index->GetFunctions(lookup_infos, *this, {}, [&](DWARFDIE entry) { if (entry.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_declaration, 0)) return IterationAction::Continue; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index aaec160..3bf113a 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -86,6 +86,40 @@ static lldb::LanguageType TranslateLanguage(PDB_Lang lang) { } } +static std::optional<std::string> +findMatchingPDBFilePath(llvm::StringRef original_pdb_path, + llvm::StringRef exe_path) { + const FileSystem &fs = FileSystem::Instance(); + + if (fs.Exists(original_pdb_path)) + return std::string(original_pdb_path); + + const auto exe_dir = FileSpec(exe_path).CopyByRemovingLastPathComponent(); + // While the exe_path uses the native style, the exe might be compiled on a + // different OS, so try to guess the style used. + const FileSpec original_pdb_spec(original_pdb_path, + FileSpec::GuessPathStyle(original_pdb_path) + .value_or(FileSpec::Style::native)); + const llvm::StringRef pdb_filename = original_pdb_spec.GetFilename(); + + // If the file doesn't exist, perhaps the path specified at build time + // doesn't match the PDB's current location, so check the location of the + // executable. + const FileSpec local_pdb = exe_dir.CopyByAppendingPathComponent(pdb_filename); + if (fs.Exists(local_pdb)) + return local_pdb.GetPath(); + + // Otherwise, search for one in target.debug-file-search-paths + FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); + for (const FileSpec &search_dir : search_paths) { + FileSpec pdb_path = search_dir.CopyByAppendingPathComponent(pdb_filename); + if (fs.Exists(pdb_path)) + return pdb_path.GetPath(); + } + + return std::nullopt; +} + static std::unique_ptr<PDBFile> loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) { // Try to find a matching PDB for an EXE. @@ -113,17 +147,14 @@ loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) { return nullptr; } - // If the file doesn't exist, perhaps the path specified at build time - // doesn't match the PDB's current location, so check the location of the - // executable. - if (!FileSystem::Instance().Exists(pdb_file)) { - const auto exe_dir = FileSpec(exe_path).CopyByRemovingLastPathComponent(); - const auto pdb_name = FileSpec(pdb_file).GetFilename().GetCString(); - pdb_file = exe_dir.CopyByAppendingPathComponent(pdb_name).GetPathAsConstString().GetStringRef(); - } + std::optional<std::string> resolved_pdb_path = + findMatchingPDBFilePath(pdb_file, exe_path); + if (!resolved_pdb_path) + return nullptr; // If the file is not a PDB or if it doesn't have a matching GUID, fail. - auto pdb = ObjectFilePDB::loadPDBFile(std::string(pdb_file), allocator); + auto pdb = + ObjectFilePDB::loadPDBFile(*std::move(resolved_pdb_path), allocator); if (!pdb) return nullptr; @@ -137,6 +168,9 @@ loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) { if (expected_info->getGuid() != guid) return nullptr; + + LLDB_LOG(GetLog(LLDBLog::Symbols), "Loading {0} for {1}", pdb->getFilePath(), + exe_path); return pdb; } @@ -1126,7 +1160,8 @@ lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) { } void SymbolFileNativePDB::AddSymbols(Symtab &symtab) { - auto *section_list = m_objfile_sp->GetSectionList(); + auto *section_list = + m_objfile_sp->GetModule()->GetObjectFile()->GetSectionList(); if (!section_list) return; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp index 1c575e9..46cf9b8 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp @@ -442,6 +442,10 @@ void UdtRecordCompleter::Record::ConstructRecord() { // The end offset to a vector of field/struct that ends at the offset. std::map<uint64_t, std::vector<Member *>> end_offset_map; + auto is_last_end_offset = [&](auto it) { + return it != end_offset_map.end() && ++it == end_offset_map.end(); + }; + for (auto &pair : fields_map) { uint64_t offset = pair.first; auto &fields = pair.second; @@ -462,8 +466,23 @@ void UdtRecordCompleter::Record::ConstructRecord() { } if (iter->second.empty()) continue; - parent = iter->second.back(); - iter->second.pop_back(); + + // If the new fields come after the already added ones + // without overlap, go back to the root. + if (iter->first <= offset && is_last_end_offset(iter)) { + if (record.kind == Member::Struct) { + parent = &record; + } else { + assert(record.kind == Member::Union && + "Current record must be a union"); + assert(!record.fields.empty()); + // For unions, append the field to the last struct + parent = record.fields.back().get(); + } + } else { + parent = iter->second.back(); + iter->second.pop_back(); + } } // If it's a field, then the field is inside a union, so we can safely // increase its size by converting it to a struct to hold multiple fields. diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 0ccb1804..97c995fc 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -287,8 +287,10 @@ uint32_t SymbolFilePDB::CalculateAbilities() { } void SymbolFilePDB::InitializeObject() { - lldb::addr_t obj_load_address = - m_objfile_sp->GetBaseAddress().GetFileAddress(); + lldb::addr_t obj_load_address = m_objfile_sp->GetModule() + ->GetObjectFile() + ->GetBaseAddress() + .GetFileAddress(); lldbassert(obj_load_address && obj_load_address != LLDB_INVALID_ADDRESS); m_session_up->setLoadAddress(obj_load_address); if (!m_global_scope_up) @@ -1479,7 +1481,8 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) { if (!results) return; - auto section_list = m_objfile_sp->GetSectionList(); + auto section_list = + m_objfile_sp->GetModule()->GetObjectFile()->GetSectionList(); if (!section_list) return; |
