| //===-- SymbolFileDWARFDwo.cpp ----------------------------------*- 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 |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "SymbolFileDWARFDwo.h" |
| |
| #include "lldb/Core/Section.h" |
| #include "lldb/Expression/DWARFExpression.h" |
| #include "lldb/Symbol/ObjectFile.h" |
| #include "lldb/Utility/LLDBAssert.h" |
| #include "llvm/Support/Casting.h" |
| |
| #include "DWARFCompileUnit.h" |
| #include "DWARFDebugInfo.h" |
| #include "DWARFUnit.h" |
| |
| using namespace lldb; |
| using namespace lldb_private; |
| |
| char SymbolFileDWARFDwo::ID; |
| |
| SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile, |
| DWARFCompileUnit &dwarf_cu) |
| : SymbolFileDWARF(objfile, objfile->GetSectionList( |
| /*update_module_section_list*/ false)), |
| m_base_dwarf_cu(dwarf_cu) { |
| SetID(((lldb::user_id_t)dwarf_cu.GetID()) << 32); |
| } |
| |
| void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type, |
| DWARFDataExtractor &data) { |
| const SectionList *section_list = |
| m_objfile_sp->GetSectionList(false /* update_module_section_list */); |
| if (section_list) { |
| SectionSP section_sp(section_list->FindSectionByType(sect_type, true)); |
| if (section_sp) { |
| |
| if (m_objfile_sp->ReadSectionData(section_sp.get(), data) != 0) |
| return; |
| |
| data.Clear(); |
| } |
| } |
| |
| SymbolFileDWARF::LoadSectionData(sect_type, data); |
| } |
| |
| lldb::CompUnitSP |
| SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { |
| assert(GetCompileUnit() == &dwarf_cu && |
| "SymbolFileDWARFDwo::ParseCompileUnit called with incompatible " |
| "compile unit"); |
| return GetBaseSymbolFile().ParseCompileUnit(m_base_dwarf_cu); |
| } |
| |
| DWARFCompileUnit *SymbolFileDWARFDwo::GetCompileUnit() { |
| if (!m_cu) |
| m_cu = ComputeCompileUnit(); |
| return m_cu; |
| } |
| |
| DWARFCompileUnit *SymbolFileDWARFDwo::ComputeCompileUnit() { |
| DWARFDebugInfo *debug_info = DebugInfo(); |
| if (!debug_info) |
| return nullptr; |
| |
| // Right now we only support dwo files with one compile unit. If we don't have |
| // type units, we can just check for the unit count. |
| if (!debug_info->ContainsTypeUnits() && debug_info->GetNumUnits() == 1) |
| return llvm::cast<DWARFCompileUnit>(debug_info->GetUnitAtIndex(0)); |
| |
| // Otherwise, we have to run through all units, and find the compile unit that |
| // way. |
| DWARFCompileUnit *cu = nullptr; |
| for (size_t i = 0; i < debug_info->GetNumUnits(); ++i) { |
| if (auto *candidate = |
| llvm::dyn_cast<DWARFCompileUnit>(debug_info->GetUnitAtIndex(i))) { |
| if (cu) |
| return nullptr; // More that one CU found. |
| cu = candidate; |
| } |
| } |
| return cu; |
| } |
| |
| DWARFUnit * |
| SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) { |
| return GetCompileUnit(); |
| } |
| |
| SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() { |
| return GetBaseSymbolFile().GetDIEToType(); |
| } |
| |
| SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() { |
| return GetBaseSymbolFile().GetDIEToVariable(); |
| } |
| |
| SymbolFileDWARF::DIEToClangType & |
| SymbolFileDWARFDwo::GetForwardDeclDieToClangType() { |
| return GetBaseSymbolFile().GetForwardDeclDieToClangType(); |
| } |
| |
| SymbolFileDWARF::ClangTypeToDIE & |
| SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() { |
| return GetBaseSymbolFile().GetForwardDeclClangTypeToDie(); |
| } |
| |
| size_t SymbolFileDWARFDwo::GetObjCMethodDIEOffsets( |
| lldb_private::ConstString class_name, DIEArray &method_die_offsets) { |
| return GetBaseSymbolFile().GetObjCMethodDIEOffsets(class_name, |
| method_die_offsets); |
| } |
| |
| UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() { |
| return GetBaseSymbolFile().GetUniqueDWARFASTTypeMap(); |
| } |
| |
| lldb::TypeSP SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext( |
| const DWARFDeclContext &die_decl_ctx) { |
| return GetBaseSymbolFile().FindDefinitionTypeForDWARFDeclContext( |
| die_decl_ctx); |
| } |
| |
| lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE( |
| const DWARFDIE &die, lldb_private::ConstString type_name, |
| bool must_be_implementation) { |
| return GetBaseSymbolFile().FindCompleteObjCDefinitionTypeForDIE( |
| die, type_name, must_be_implementation); |
| } |
| |
| SymbolFileDWARF &SymbolFileDWARFDwo::GetBaseSymbolFile() { |
| return m_base_dwarf_cu.GetSymbolFileDWARF(); |
| } |
| |
| llvm::Expected<TypeSystem &> |
| SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) { |
| return GetBaseSymbolFile().GetTypeSystemForLanguage(language); |
| } |
| |
| DWARFDIE |
| SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) { |
| if (*die_ref.dwo_num() == GetDwoNum()) |
| return DebugInfo()->GetDIE(die_ref); |
| return GetBaseSymbolFile().GetDIE(die_ref); |
| } |