diff options
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp')
-rw-r--r-- | source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 1404 |
1 files changed, 637 insertions, 767 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 2a0a89f0b25a..e2ddcfc5d64b 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1,9 +1,8 @@ //===-- SymbolFileDWARF.cpp ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -30,7 +29,6 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" -#include "lldb/Host/Symbols.h" #include "lldb/Interpreter/OptionValueFileSpecList.h" #include "lldb/Interpreter/OptionValueProperties.h" @@ -43,6 +41,7 @@ #include "lldb/Symbol/CompilerDeclContext.h" #include "lldb/Symbol/DebugMacros.h" #include "lldb/Symbol/LineTable.h" +#include "lldb/Symbol/LocateSymbolFile.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/TypeMap.h" @@ -50,11 +49,12 @@ #include "lldb/Symbol/VariableList.h" #include "lldb/Target/Language.h" +#include "lldb/Target/Target.h" #include "AppleDWARFIndex.h" #include "DWARFASTParser.h" #include "DWARFASTParserClang.h" -#include "DWARFDIECollection.h" +#include "DWARFCompileUnit.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugAranges.h" #include "DWARFDebugInfo.h" @@ -63,6 +63,7 @@ #include "DWARFDebugRanges.h" #include "DWARFDeclContext.h" #include "DWARFFormValue.h" +#include "DWARFTypeUnit.h" #include "DWARFUnit.h" #include "DebugNamesDWARFIndex.h" #include "LogChannelDWARF.h" @@ -73,7 +74,9 @@ #include "llvm/Support/FileSystem.h" +#include <algorithm> #include <map> +#include <memory> #include <ctype.h> #include <string.h> @@ -131,12 +134,12 @@ public: } PluginProperties() { - m_collection_sp.reset(new OptionValueProperties(GetSettingName())); + m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName()); m_collection_sp->Initialize(g_properties); } - FileSpecList &GetSymLinkPaths() { - OptionValueFileSpecList *option_value = + FileSpecList GetSymLinkPaths() { + const OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList( nullptr, true, ePropertySymLinkPaths); assert(option_value); @@ -158,68 +161,8 @@ static const SymbolFileDWARFPropertiesSP &GetGlobalPluginProperties() { } // anonymous namespace end -static const char *removeHostnameFromPathname(const char *path_from_dwarf) { - if (!path_from_dwarf || !path_from_dwarf[0]) { - return path_from_dwarf; - } - - const char *colon_pos = strchr(path_from_dwarf, ':'); - if (nullptr == colon_pos) { - return path_from_dwarf; - } - - const char *slash_pos = strchr(path_from_dwarf, '/'); - if (slash_pos && (slash_pos < colon_pos)) { - return path_from_dwarf; - } - - // check whether we have a windows path, and so the first character is a - // drive-letter not a hostname. - if (colon_pos == path_from_dwarf + 1 && isalpha(*path_from_dwarf) && - strlen(path_from_dwarf) > 2 && '\\' == path_from_dwarf[2]) { - return path_from_dwarf; - } - - return colon_pos + 1; -} - -static FileSpec resolveCompDir(const char *path_from_dwarf) { - if (!path_from_dwarf) - return FileSpec(); - - // DWARF2/3 suggests the form hostname:pathname for compilation directory. - // Remove the host part if present. - const char *local_path = removeHostnameFromPathname(path_from_dwarf); - if (!local_path) - return FileSpec(); - - bool is_symlink = false; - // Always normalize our compile unit directory to get rid of redundant - // slashes and other path anomalies before we use it for path prepending - FileSpec local_spec(local_path); - const auto &file_specs = GetGlobalPluginProperties()->GetSymLinkPaths(); - for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i) - is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i), - local_spec, true); - - if (!is_symlink) - return local_spec; - - namespace fs = llvm::sys::fs; - if (fs::get_file_type(local_spec.GetPath(), false) != - fs::file_type::symlink_file) - return local_spec; - - FileSpec resolved_symlink; - const auto error = FileSystem::Instance().Readlink(local_spec, resolved_symlink); - if (error.Success()) - return resolved_symlink; - - return local_spec; -} - -DWARFUnit *SymbolFileDWARF::GetBaseCompileUnit() { - return nullptr; +FileSpecList SymbolFileDWARF::GetSymlinkPaths() { + return GetGlobalPluginProperties()->GetSymLinkPaths(); } void SymbolFileDWARF::Initialize() { @@ -255,7 +198,8 @@ const char *SymbolFileDWARF::GetPluginDescriptionStatic() { } SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFile *obj_file) { - return new SymbolFileDWARF(obj_file); + return new SymbolFileDWARF(obj_file, + /*dwo_section_list*/ nullptr); } TypeList *SymbolFileDWARF::GetTypeList() { @@ -346,23 +290,23 @@ size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope, ASSERT_MODULE_LOCK(this); TypeSet type_set; - CompileUnit *comp_unit = NULL; - DWARFUnit *dwarf_cu = NULL; + CompileUnit *comp_unit = nullptr; + DWARFUnit *dwarf_cu = nullptr; if (sc_scope) comp_unit = sc_scope->CalculateSymbolContextCompileUnit(); if (comp_unit) { dwarf_cu = GetDWARFCompileUnit(comp_unit); - if (dwarf_cu == 0) + if (dwarf_cu == nullptr) return 0; GetTypes(dwarf_cu->DIE(), dwarf_cu->GetOffset(), - dwarf_cu->GetNextCompileUnitOffset(), type_mask, type_set); + dwarf_cu->GetNextUnitOffset(), type_mask, type_set); } else { DWARFDebugInfo *info = DebugInfo(); if (info) { - const size_t num_cus = info->GetNumCompileUnits(); + const size_t num_cus = info->GetNumUnits(); for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx) { - dwarf_cu = info->GetCompileUnitAtIndex(cu_idx); + dwarf_cu = info->GetUnitAtIndex(cu_idx); if (dwarf_cu) { GetTypes(dwarf_cu->DIE(), 0, UINT32_MAX, type_mask, type_set); } @@ -383,10 +327,8 @@ size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope, return num_types_added; } -//---------------------------------------------------------------------- // Gets the first parent that is a lexical block, function or inlined // subroutine, or compile unit. -//---------------------------------------------------------------------- DWARFDIE SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) { DWARFDIE die; @@ -405,23 +347,21 @@ SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) { return DWARFDIE(); } -SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile) - : SymbolFile(objfile), UserID(uint64_t(DW_INVALID_OFFSET) - << 32), // Used by SymbolFileDWARFDebugMap to - // when this class parses .o files to - // contain the .o file index/ID - m_debug_map_module_wp(), m_debug_map_symfile(NULL), m_data_debug_abbrev(), - m_data_debug_aranges(), m_data_debug_frame(), m_data_debug_info(), - m_data_debug_line(), m_data_debug_macro(), m_data_debug_loc(), - m_data_debug_ranges(), m_data_debug_rnglists(), m_data_debug_str(), - m_data_apple_names(), m_data_apple_types(), m_data_apple_namespaces(), - m_abbr(), m_info(), m_line(), m_fetched_external_modules(false), - m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), m_ranges(), +SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile, + SectionList *dwo_section_list) + : SymbolFile(objfile), + UserID(0x7fffffff00000000), // Used by SymbolFileDWARFDebugMap to + // when this class parses .o files to + // contain the .o file index/ID + m_debug_map_module_wp(), m_debug_map_symfile(nullptr), + m_context(objfile->GetModule()->GetSectionList(), dwo_section_list), + m_data_debug_loc(), m_abbr(), m_info(), m_fetched_external_modules(false), + m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), m_unique_ast_type_map() {} SymbolFileDWARF::~SymbolFileDWARF() {} -static const ConstString &GetDWARFMachOSegmentName() { +static ConstString GetDWARFMachOSegmentName() { static ConstString g_dwarf_section_name("__DWARF"); return g_dwarf_section_name; } @@ -449,15 +389,6 @@ TypeSystem *SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) { void SymbolFileDWARF::InitializeObject() { Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); - ModuleSP module_sp(m_obj_file->GetModule()); - if (module_sp) { - const SectionList *section_list = module_sp->GetSectionList(); - Section *section = - section_list->FindSectionByName(GetDWARFMachOSegmentName()).get(); - - if (section) - m_obj_file->ReadSectionData(section, m_dwarf_data); - } if (!GetGlobalPluginProperties()->IgnoreFileIndexes()) { DWARFDataExtractor apple_names, apple_namespaces, apple_types, apple_objc; @@ -468,7 +399,7 @@ void SymbolFileDWARF::InitializeObject() { m_index = AppleDWARFIndex::Create( *GetObjectFile()->GetModule(), apple_names, apple_namespaces, - apple_types, apple_objc, get_debug_str_data()); + apple_types, apple_objc, m_context.getOrLoadStrData()); if (m_index) return; @@ -477,9 +408,9 @@ void SymbolFileDWARF::InitializeObject() { LoadSectionData(eSectionTypeDWARFDebugNames, debug_names); if (debug_names.GetByteSize() > 0) { llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or = - DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(), - debug_names, get_debug_str_data(), - DebugInfo()); + DebugNamesDWARFIndex::Create( + *GetObjectFile()->GetModule(), debug_names, + m_context.getOrLoadStrData(), DebugInfo()); if (index_or) { m_index = std::move(*index_or); return; @@ -499,25 +430,11 @@ bool SymbolFileDWARF::SupportedVersion(uint16_t version) { uint32_t SymbolFileDWARF::CalculateAbilities() { uint32_t abilities = 0; - if (m_obj_file != NULL) { - const Section *section = NULL; + if (m_obj_file != nullptr) { + const Section *section = nullptr; const SectionList *section_list = m_obj_file->GetSectionList(); - if (section_list == NULL) - return 0; - - // On non Apple platforms we might have .debug_types debug info that is - // created by using "-fdebug-types-section". LLDB currently will try to - // load this debug info, but it causes crashes during debugging when types - // are missing since it doesn't know how to parse the info in the - // .debug_types type units. This causes all complex debug info types to be - // unresolved. Because this causes LLDB to crash and since it really - // doesn't provide a solid debuggiung experience, we should disable trying - // to debug this kind of DWARF until support gets added or deprecated. - if (section_list->FindSectionByName(ConstString(".debug_types"))) { - m_obj_file->GetModule()->ReportWarning( - "lldb doesn’t support .debug_types debug info"); + if (section_list == nullptr) return 0; - } uint64_t debug_abbrev_file_size = 0; uint64_t debug_info_file_size = 0; @@ -530,7 +447,7 @@ uint32_t SymbolFileDWARF::CalculateAbilities() { section = section_list->FindSectionByType(eSectionTypeDWARFDebugInfo, true).get(); - if (section != NULL) { + if (section != nullptr) { debug_info_file_size = section->GetFileSize(); section = @@ -604,53 +521,15 @@ void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type, DWARFDataExtractor &data) { ModuleSP module_sp(m_obj_file->GetModule()); const SectionList *section_list = module_sp->GetSectionList(); - if (section_list) { - SectionSP section_sp(section_list->FindSectionByType(sect_type, true)); - if (section_sp) { - // See if we memory mapped the DWARF segment? - if (m_dwarf_data.GetByteSize()) { - data.SetData(m_dwarf_data, section_sp->GetOffset(), - section_sp->GetFileSize()); - } else { - if (m_obj_file->ReadSectionData(section_sp.get(), data) == 0) - data.Clear(); - } - } - } -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_abbrev_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugAbbrev, - m_data_debug_abbrev); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_addr_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugAddr, m_data_debug_addr); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_aranges_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugAranges, - m_data_debug_aranges); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_frame_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugFrame, m_data_debug_frame); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_info_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugInfo, m_data_debug_info); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugLine, m_data_debug_line); -} + if (!section_list) + return; -const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_str_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugLineStr, m_data_debug_line_str); -} + SectionSP section_sp(section_list->FindSectionByType(sect_type, true)); + if (!section_sp) + return; -const DWARFDataExtractor &SymbolFileDWARF::get_debug_macro_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugMacro, m_data_debug_macro); + data.Clear(); + m_obj_file->ReadSectionData(section_sp.get(), data); } const DWARFDataExtractor &SymbolFileDWARF::DebugLocData() { @@ -669,60 +548,24 @@ const DWARFDataExtractor &SymbolFileDWARF::get_debug_loclists_data() { m_data_debug_loclists); } -const DWARFDataExtractor &SymbolFileDWARF::get_debug_ranges_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugRanges, - m_data_debug_ranges); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_rnglists_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugRngLists, - m_data_debug_rnglists); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugStr, m_data_debug_str); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_offsets_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugStrOffsets, - m_data_debug_str_offsets); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_types_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugTypes, m_data_debug_types); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_apple_names_data() { - return GetCachedSectionData(eSectionTypeDWARFAppleNames, m_data_apple_names); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_apple_types_data() { - return GetCachedSectionData(eSectionTypeDWARFAppleTypes, m_data_apple_types); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_apple_namespaces_data() { - return GetCachedSectionData(eSectionTypeDWARFAppleNamespaces, - m_data_apple_namespaces); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_apple_objc_data() { - return GetCachedSectionData(eSectionTypeDWARFAppleObjC, m_data_apple_objc); -} +DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() { + if (m_abbr) + return m_abbr.get(); -const DWARFDataExtractor &SymbolFileDWARF::get_gnu_debugaltlink() { - return GetCachedSectionData(eSectionTypeDWARFGNUDebugAltLink, - m_data_gnu_debugaltlink); -} + const DWARFDataExtractor &debug_abbrev_data = m_context.getOrLoadAbbrevData(); + if (debug_abbrev_data.GetByteSize() == 0) + return nullptr; -DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() { - if (m_abbr.get() == NULL) { - const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data(); - if (debug_abbrev_data.GetByteSize() > 0) { - m_abbr.reset(new DWARFDebugAbbrev()); - if (m_abbr.get()) - m_abbr->Parse(debug_abbrev_data); - } + auto abbr = llvm::make_unique<DWARFDebugAbbrev>(); + llvm::Error error = abbr->parse(debug_abbrev_data); + if (error) { + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); + LLDB_LOG_ERROR(log, std::move(error), + "Unable to read .debug_abbrev section: {0}"); + return nullptr; } + + m_abbr = std::move(abbr); return m_abbr.get(); } @@ -731,16 +574,12 @@ const DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() const { } DWARFDebugInfo *SymbolFileDWARF::DebugInfo() { - if (m_info.get() == NULL) { + if (m_info == nullptr) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION, static_cast<void *>(this)); - if (get_debug_info_data().GetByteSize() > 0) { - m_info.reset(new DWARFDebugInfo()); - if (m_info.get()) { - m_info->SetDwarfData(this); - } - } + if (m_context.getOrLoadDebugInfoData().GetByteSize() > 0) + m_info = llvm::make_unique<DWARFDebugInfo>(*this, m_context); } return m_info.get(); } @@ -756,109 +595,90 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) { DWARFDebugInfo *info = DebugInfo(); if (info) { - // Just a normal DWARF file whose user ID for the compile unit is the DWARF - // offset itself - - DWARFUnit *dwarf_cu = - info->GetCompileUnit((dw_offset_t)comp_unit->GetID()); - if (dwarf_cu && dwarf_cu->GetUserData() == NULL) + // The compile unit ID is the index of the DWARF unit. + DWARFUnit *dwarf_cu = info->GetUnitAtIndex(comp_unit->GetID()); + if (dwarf_cu && dwarf_cu->GetUserData() == nullptr) dwarf_cu->SetUserData(comp_unit); return dwarf_cu; } - return NULL; + return nullptr; } -DWARFDebugRangesBase *SymbolFileDWARF::DebugRanges() { - if (m_ranges.get() == NULL) { +DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRanges() { + if (!m_ranges) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION, static_cast<void *>(this)); - if (get_debug_ranges_data().GetByteSize() > 0) + if (m_context.getOrLoadRangesData().GetByteSize() > 0) m_ranges.reset(new DWARFDebugRanges()); - else if (get_debug_rnglists_data().GetByteSize() > 0) - m_ranges.reset(new DWARFDebugRngLists()); - if (m_ranges.get()) - m_ranges->Extract(this); + if (m_ranges) + m_ranges->Extract(m_context); } return m_ranges.get(); } -const DWARFDebugRangesBase *SymbolFileDWARF::DebugRanges() const { - return m_ranges.get(); +DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRngLists() { + if (!m_rnglists) { + static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); + Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION, + static_cast<void *>(this)); + + if (m_context.getOrLoadRngListsData().GetByteSize() > 0) + m_rnglists.reset(new DWARFDebugRngLists()); + + if (m_rnglists) + m_rnglists->Extract(m_context); + } + return m_rnglists.get(); } -lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFUnit *dwarf_cu, - uint32_t cu_idx) { +lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { CompUnitSP cu_sp; - if (dwarf_cu) { - CompileUnit *comp_unit = (CompileUnit *)dwarf_cu->GetUserData(); - if (comp_unit) { - // We already parsed this compile unit, had out a shared pointer to it - cu_sp = comp_unit->shared_from_this(); + CompileUnit *comp_unit = (CompileUnit *)dwarf_cu.GetUserData(); + if (comp_unit) { + // We already parsed this compile unit, had out a shared pointer to it + cu_sp = comp_unit->shared_from_this(); + } else { + if (&dwarf_cu.GetSymbolFileDWARF() != this) { + return dwarf_cu.GetSymbolFileDWARF().ParseCompileUnit(dwarf_cu); + } else if (dwarf_cu.GetOffset() == 0 && GetDebugMapSymfile()) { + // Let the debug map create the compile unit + cu_sp = m_debug_map_symfile->GetCompileUnit(this); + dwarf_cu.SetUserData(cu_sp.get()); } else { - if (dwarf_cu->GetSymbolFileDWARF() != this) { - return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu, - cu_idx); - } else if (dwarf_cu->GetOffset() == 0 && GetDebugMapSymfile()) { - // Let the debug map create the compile unit - cu_sp = m_debug_map_symfile->GetCompileUnit(this); - dwarf_cu->SetUserData(cu_sp.get()); - } else { - ModuleSP module_sp(m_obj_file->GetModule()); - if (module_sp) { - const DWARFDIE cu_die = dwarf_cu->DIE(); - if (cu_die) { - FileSpec cu_file_spec(cu_die.GetName()); - if (cu_file_spec) { - // If we have a full path to the compile unit, we don't need to - // resolve the file. This can be expensive e.g. when the source - // files are - // NFS mounted. - if (cu_file_spec.IsRelative()) { - const char *cu_comp_dir{ - cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)}; - cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir)); - } - - std::string remapped_file; - if (module_sp->RemapSourceFile(cu_file_spec.GetPath(), - remapped_file)) - cu_file_spec.SetFile(remapped_file, FileSpec::Style::native); - } + ModuleSP module_sp(m_obj_file->GetModule()); + if (module_sp) { + const DWARFDIE cu_die = dwarf_cu.DIE(); + if (cu_die) { + FileSpec cu_file_spec(cu_die.GetName(), dwarf_cu.GetPathStyle()); + if (cu_file_spec) { + // If we have a full path to the compile unit, we don't need to + // resolve the file. This can be expensive e.g. when the source + // files are NFS mounted. + cu_file_spec.MakeAbsolute(dwarf_cu.GetCompilationDirectory()); + + std::string remapped_file; + if (module_sp->RemapSourceFile(cu_file_spec.GetPath(), + remapped_file)) + cu_file_spec.SetFile(remapped_file, FileSpec::Style::native); + } - LanguageType cu_language = DWARFUnit::LanguageTypeFromDWARF( - cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0)); - - bool is_optimized = dwarf_cu->GetIsOptimized(); - cu_sp.reset(new CompileUnit( - module_sp, dwarf_cu, cu_file_spec, dwarf_cu->GetID(), - cu_language, is_optimized ? eLazyBoolYes : eLazyBoolNo)); - if (cu_sp) { - // If we just created a compile unit with an invalid file spec, - // try and get the first entry in the supports files from the - // line table as that should be the compile unit. - if (!cu_file_spec) { - cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1); - if (cu_file_spec) { - (FileSpec &)(*cu_sp) = cu_file_spec; - // Also fix the invalid file spec which was copied from the - // compile unit. - cu_sp->GetSupportFiles().Replace(0, cu_file_spec); - } - } + LanguageType cu_language = DWARFUnit::LanguageTypeFromDWARF( + cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0)); - dwarf_cu->SetUserData(cu_sp.get()); + bool is_optimized = dwarf_cu.GetIsOptimized(); + BuildCuTranslationTable(); + cu_sp = std::make_shared<CompileUnit>( + module_sp, &dwarf_cu, cu_file_spec, + *GetDWARFUnitIndex(dwarf_cu.GetID()), cu_language, + is_optimized ? eLazyBoolYes : eLazyBoolNo); - // Figure out the compile unit index if we weren't given one - if (cu_idx == UINT32_MAX) - DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx); + dwarf_cu.SetUserData(cu_sp.get()); - m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex( - cu_idx, cu_sp); - } - } + m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex( + dwarf_cu.GetID(), cu_sp); } } } @@ -866,23 +686,56 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFUnit *dwarf_cu, return cu_sp; } +void SymbolFileDWARF::BuildCuTranslationTable() { + if (!m_lldb_cu_to_dwarf_unit.empty()) + return; + + DWARFDebugInfo *info = DebugInfo(); + if (!info) + return; + + if (!info->ContainsTypeUnits()) { + // We can use a 1-to-1 mapping. No need to build a translation table. + return; + } + for (uint32_t i = 0, num = info->GetNumUnits(); i < num; ++i) { + if (auto *cu = llvm::dyn_cast<DWARFCompileUnit>(info->GetUnitAtIndex(i))) { + cu->SetID(m_lldb_cu_to_dwarf_unit.size()); + m_lldb_cu_to_dwarf_unit.push_back(i); + } + } +} + +llvm::Optional<uint32_t> SymbolFileDWARF::GetDWARFUnitIndex(uint32_t cu_idx) { + BuildCuTranslationTable(); + if (m_lldb_cu_to_dwarf_unit.empty()) + return cu_idx; + if (cu_idx >= m_lldb_cu_to_dwarf_unit.size()) + return llvm::None; + return m_lldb_cu_to_dwarf_unit[cu_idx]; +} + uint32_t SymbolFileDWARF::GetNumCompileUnits() { DWARFDebugInfo *info = DebugInfo(); - if (info) - return info->GetNumCompileUnits(); - return 0; + if (!info) + return 0; + BuildCuTranslationTable(); + return m_lldb_cu_to_dwarf_unit.empty() ? info->GetNumUnits() + : m_lldb_cu_to_dwarf_unit.size(); } CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) { ASSERT_MODULE_LOCK(this); - CompUnitSP cu_sp; DWARFDebugInfo *info = DebugInfo(); - if (info) { - DWARFUnit *dwarf_cu = info->GetCompileUnitAtIndex(cu_idx); - if (dwarf_cu) - cu_sp = ParseCompileUnit(dwarf_cu, cu_idx); + if (!info) + return {}; + + if (llvm::Optional<uint32_t> dwarf_idx = GetDWARFUnitIndex(cu_idx)) { + if (auto *dwarf_cu = llvm::cast_or_null<DWARFCompileUnit>( + info->GetUnitAtIndex(*dwarf_idx))) + return ParseCompileUnit(*dwarf_cu); } - return cu_sp; + return {}; } Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit, @@ -920,50 +773,74 @@ lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) { size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) { ASSERT_MODULE_LOCK(this); - size_t functions_added = 0; DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); - if (dwarf_cu) { - DWARFDIECollection function_dies; - const size_t num_functions = - dwarf_cu->AppendDIEsWithTag(DW_TAG_subprogram, function_dies); - size_t func_idx; - for (func_idx = 0; func_idx < num_functions; ++func_idx) { - DWARFDIE die = function_dies.GetDIEAtIndex(func_idx); - if (comp_unit.FindFunctionByUID(die.GetID()).get() == NULL) { - if (ParseFunction(comp_unit, die)) - ++functions_added; - } - } - // FixupTypes(); + if (!dwarf_cu) + return 0; + + size_t functions_added = 0; + std::vector<DWARFDIE> function_dies; + dwarf_cu->AppendDIEsWithTag(DW_TAG_subprogram, function_dies); + for (const DWARFDIE &die : function_dies) { + if (comp_unit.FindFunctionByUID(die.GetID())) + continue; + if (ParseFunction(comp_unit, die)) + ++functions_added; } + // FixupTypes(); return functions_added; } bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit, FileSpecList &support_files) { ASSERT_MODULE_LOCK(this); - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); - if (dwarf_cu) { - const DWARFBaseDIE cu_die = dwarf_cu->GetUnitDIEOnly(); - - if (cu_die) { - FileSpec cu_comp_dir = resolveCompDir( - cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)); - const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned( - DW_AT_stmt_list, DW_INVALID_OFFSET); - if (stmt_list != DW_INVALID_OFFSET) { - // All file indexes in DWARF are one based and a file of index zero is - // supposed to be the compile unit itself. - support_files.Append(comp_unit); - return DWARFDebugLine::ParseSupportFiles( - comp_unit.GetModule(), get_debug_line_data(), cu_comp_dir, - stmt_list, support_files, dwarf_cu); - } + if (DWARFUnit *unit = GetDWARFCompileUnit(&comp_unit)) { + const dw_offset_t stmt_list = unit->GetLineTableOffset(); + if (stmt_list != DW_INVALID_OFFSET) { + // All file indexes in DWARF are one based and a file of index zero is + // supposed to be the compile unit itself. + support_files.Append(comp_unit); + return DWARFDebugLine::ParseSupportFiles(comp_unit.GetModule(), + m_context.getOrLoadLineData(), + stmt_list, support_files, unit); } } return false; } +FileSpec SymbolFileDWARF::GetFile(DWARFUnit &unit, size_t file_idx) { + if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(&unit)) { + if (CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(*dwarf_cu)) + return lldb_cu->GetSupportFiles().GetFileSpecAtIndex(file_idx); + return FileSpec(); + } + + auto &tu = llvm::cast<DWARFTypeUnit>(unit); + return GetTypeUnitSupportFiles(tu).GetFileSpecAtIndex(file_idx); +} + +const FileSpecList & +SymbolFileDWARF::GetTypeUnitSupportFiles(DWARFTypeUnit &tu) { + static FileSpecList empty_list; + + dw_offset_t offset = tu.GetLineTableOffset(); + if (offset == DW_INVALID_OFFSET || + offset == llvm::DenseMapInfo<dw_offset_t>::getEmptyKey() || + offset == llvm::DenseMapInfo<dw_offset_t>::getTombstoneKey()) + return empty_list; + + // Many type units can share a line table, so parse the support file list + // once, and cache it based on the offset field. + auto iter_bool = m_type_unit_support_files.try_emplace(offset); + FileSpecList &list = iter_bool.first->second; + if (iter_bool.second) { + list.Append(FileSpec()); + DWARFDebugLine::ParseSupportFiles(GetObjectFile()->GetModule(), + m_context.getOrLoadLineData(), offset, + list, &tu); + } + return list; +} + bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) { ASSERT_MODULE_LOCK(this); DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); @@ -974,54 +851,63 @@ bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) { bool SymbolFileDWARF::ParseImportedModules( const lldb_private::SymbolContext &sc, - std::vector<lldb_private::ConstString> &imported_modules) { + std::vector<SourceModule> &imported_modules) { ASSERT_MODULE_LOCK(this); assert(sc.comp_unit); DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); - if (dwarf_cu) { - if (ClangModulesDeclVendor::LanguageSupportsClangModules( - sc.comp_unit->GetLanguage())) { - UpdateExternalModuleListIfNeeded(); + if (!dwarf_cu) + return false; + if (!ClangModulesDeclVendor::LanguageSupportsClangModules( + sc.comp_unit->GetLanguage())) + return false; + UpdateExternalModuleListIfNeeded(); - if (sc.comp_unit) { - const DWARFDIE die = dwarf_cu->DIE(); + const DWARFDIE die = dwarf_cu->DIE(); + if (!die) + return false; - if (die) { - for (DWARFDIE child_die = die.GetFirstChild(); child_die; - child_die = child_die.GetSibling()) { - if (child_die.Tag() == DW_TAG_imported_declaration) { - if (DWARFDIE module_die = - child_die.GetReferencedDIE(DW_AT_import)) { - if (module_die.Tag() == DW_TAG_module) { - if (const char *name = module_die.GetAttributeValueAsString( - DW_AT_name, nullptr)) { - ConstString const_name(name); - imported_modules.push_back(const_name); - } - } - } - } - } - } - } else { - for (const auto &pair : m_external_type_modules) { - imported_modules.push_back(pair.first); - } + for (DWARFDIE child_die = die.GetFirstChild(); child_die; + child_die = child_die.GetSibling()) { + if (child_die.Tag() != DW_TAG_imported_declaration) + continue; + + DWARFDIE module_die = child_die.GetReferencedDIE(DW_AT_import); + if (module_die.Tag() != DW_TAG_module) + continue; + + if (const char *name = + module_die.GetAttributeValueAsString(DW_AT_name, nullptr)) { + SourceModule module; + module.path.push_back(ConstString(name)); + + DWARFDIE parent_die = module_die; + while ((parent_die = parent_die.GetParent())) { + if (parent_die.Tag() != DW_TAG_module) + break; + if (const char *name = + parent_die.GetAttributeValueAsString(DW_AT_name, nullptr)) + module.path.push_back(ConstString(name)); } + std::reverse(module.path.begin(), module.path.end()); + if (const char *include_path = module_die.GetAttributeValueAsString( + DW_AT_LLVM_include_path, nullptr)) + module.search_path = ConstString(include_path); + if (const char *sysroot = module_die.GetAttributeValueAsString( + DW_AT_LLVM_isysroot, nullptr)) + module.sysroot = ConstString(sysroot); + imported_modules.push_back(module); } } - return false; + return true; } struct ParseDWARFLineTableCallbackInfo { LineTable *line_table; - std::unique_ptr<LineSequence> sequence_ap; + std::unique_ptr<LineSequence> sequence_up; lldb::addr_t addr_mask; }; -//---------------------------------------------------------------------- // ParseStatementTableCallback -//---------------------------------------------------------------------- static void ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State &state, void *userData) { @@ -1035,26 +921,26 @@ static void ParseDWARFLineTableCallback(dw_offset_t offset, LineTable *line_table = info->line_table; // If this is our first time here, we need to create a sequence container. - if (!info->sequence_ap.get()) { - info->sequence_ap.reset(line_table->CreateLineSequenceContainer()); - assert(info->sequence_ap.get()); + if (!info->sequence_up) { + info->sequence_up.reset(line_table->CreateLineSequenceContainer()); + assert(info->sequence_up.get()); } line_table->AppendLineEntryToSequence( - info->sequence_ap.get(), state.address & info->addr_mask, state.line, + info->sequence_up.get(), state.address & info->addr_mask, state.line, state.column, state.file, state.is_stmt, state.basic_block, state.prologue_end, state.epilogue_begin, state.end_sequence); if (state.end_sequence) { // First, put the current sequence into the line table. - line_table->InsertSequence(info->sequence_ap.get()); + line_table->InsertSequence(info->sequence_up.get()); // Then, empty it to prepare for the next sequence. - info->sequence_ap->Clear(); + info->sequence_up->Clear(); } } } bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { ASSERT_MODULE_LOCK(this); - if (comp_unit.GetLineTable() != NULL) + if (comp_unit.GetLineTable() != nullptr) return true; DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); @@ -1065,10 +951,10 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET); if (cu_line_offset != DW_INVALID_OFFSET) { - std::unique_ptr<LineTable> line_table_ap(new LineTable(&comp_unit)); - if (line_table_ap.get()) { + std::unique_ptr<LineTable> line_table_up(new LineTable(&comp_unit)); + if (line_table_up) { ParseDWARFLineTableCallbackInfo info; - info.line_table = line_table_ap.get(); + info.line_table = line_table_up.get(); /* * MIPS: @@ -1091,9 +977,9 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { } lldb::offset_t offset = cu_line_offset; - DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, - ParseDWARFLineTableCallback, - &info, dwarf_cu); + DWARFDebugLine::ParseStatementTable( + m_context.getOrLoadLineData(), &offset, + ParseDWARFLineTableCallback, &info, dwarf_cu); SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); if (debug_map_symfile) { // We have an object file that has a line table with addresses that @@ -1101,9 +987,9 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { // addresses that are relative to the .o file into addresses for // the main executable. comp_unit.SetLineTable( - debug_map_symfile->LinkOSOLineTable(this, line_table_ap.get())); + debug_map_symfile->LinkOSOLineTable(this, line_table_up.get())); } else { - comp_unit.SetLineTable(line_table_ap.release()); + comp_unit.SetLineTable(line_table_up.release()); return true; } } @@ -1119,7 +1005,7 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) { if (iter != m_debug_macros_map.end()) return iter->second; - const DWARFDataExtractor &debug_macro_data = get_debug_macro_data(); + const DWARFDataExtractor &debug_macro_data = m_context.getOrLoadMacroData(); if (debug_macro_data.GetByteSize() == 0) return DebugMacrosSP(); @@ -1128,9 +1014,9 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) { const DWARFDebugMacroHeader &header = DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset); - DWARFDebugMacroEntry::ReadMacroEntries(debug_macro_data, get_debug_str_data(), - header.OffsetIs64Bit(), offset, this, - debug_macros_sp); + DWARFDebugMacroEntry::ReadMacroEntries( + debug_macro_data, m_context.getOrLoadStrData(), header.OffsetIs64Bit(), + offset, this, debug_macros_sp); return debug_macros_sp; } @@ -1171,7 +1057,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive( case DW_TAG_inlined_subroutine: case DW_TAG_subprogram: case DW_TAG_lexical_block: { - Block *block = NULL; + Block *block = nullptr; if (tag == DW_TAG_subprogram) { // Skip any DW_TAG_subprogram DIEs that are inside of a normal or // inlined functions. These will be parsed on their own as separate @@ -1187,8 +1073,8 @@ size_t SymbolFileDWARF::ParseBlocksRecursive( block = block_sp.get(); } DWARFRangeList ranges; - const char *name = NULL; - const char *mangled_name = NULL; + const char *name = nullptr; + const char *mangled_name = nullptr; int decl_file = 0; int decl_line = 0; @@ -1236,21 +1122,21 @@ size_t SymbolFileDWARF::ParseBlocksRecursive( block->FinalizeRanges(); if (tag != DW_TAG_subprogram && - (name != NULL || mangled_name != NULL)) { - std::unique_ptr<Declaration> decl_ap; + (name != nullptr || mangled_name != nullptr)) { + std::unique_ptr<Declaration> decl_up; if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_ap.reset(new Declaration( + decl_up.reset(new Declaration( comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column)); - std::unique_ptr<Declaration> call_ap; + std::unique_ptr<Declaration> call_up; if (call_file != 0 || call_line != 0 || call_column != 0) - call_ap.reset(new Declaration( + call_up.reset(new Declaration( comp_unit.GetSupportFiles().GetFileSpecAtIndex(call_file), call_line, call_column)); - block->SetInlinedFunctionInfo(name, mangled_name, decl_ap.get(), - call_ap.get()); + block->SetInlinedFunctionInfo(name, mangled_name, decl_up.get(), + call_up.get()); } ++blocks_added; @@ -1313,7 +1199,17 @@ void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) { ast_parser->GetDeclForUIDFromDWARF(decl); } -SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) { +user_id_t SymbolFileDWARF::GetUID(DIERef ref) { + if (GetDebugMapSymfile()) + return GetID() | ref.die_offset(); + + return user_id_t(GetDwoNum().getValueOr(0x7fffffff)) << 32 | + ref.die_offset() | + (lldb::user_id_t(ref.section() == DIERef::Section::DebugTypes) << 63); +} + +llvm::Optional<SymbolFileDWARF::DecodedUID> +SymbolFileDWARF::DecodeUID(lldb::user_id_t uid) { // This method can be called without going through the symbol vendor so we // need to lock the module. std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); @@ -1324,28 +1220,37 @@ SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) { // references to other DWARF objects and we must be ready to receive a // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF // instance. - SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile(); - if (debug_map) - return debug_map->GetSymbolFileByOSOIndex( + if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) { + SymbolFileDWARF *dwarf = debug_map->GetSymbolFileByOSOIndex( debug_map->GetOSOIndexFromUserID(uid)); - return this; + return DecodedUID{ + *dwarf, {llvm::None, DIERef::Section::DebugInfo, dw_offset_t(uid)}}; + } + dw_offset_t die_offset = uid; + if (die_offset == DW_INVALID_OFFSET) + return llvm::None; + + DIERef::Section section = + uid >> 63 ? DIERef::Section::DebugTypes : DIERef::Section::DebugInfo; + + llvm::Optional<uint32_t> dwo_num = uid >> 32 & 0x7fffffff; + if (*dwo_num == 0x7fffffff) + dwo_num = llvm::None; + + return DecodedUID{*this, {dwo_num, section, die_offset}}; } DWARFDIE -SymbolFileDWARF::GetDIEFromUID(lldb::user_id_t uid) { +SymbolFileDWARF::GetDIE(lldb::user_id_t uid) { // This method can be called without going through the symbol vendor so we // need to lock the module. std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); - // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we - // must make sure we use the correct DWARF file when resolving things. On - // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple - // SymbolFileDWARF classes, one for each .o file. We can often end up with - // references to other DWARF objects and we must be ready to receive a - // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF - // instance. - SymbolFileDWARF *dwarf = GetDWARFForUID(uid); - if (dwarf) - return dwarf->GetDIE(DIERef(uid, dwarf)); + + llvm::Optional<DecodedUID> decoded = DecodeUID(uid); + + if (decoded) + return decoded->dwarf.GetDIE(decoded->ref); + return DWARFDIE(); } @@ -1354,10 +1259,9 @@ CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) { // need to lock the module. std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling - // SymbolFileDWARF::GetDIEFromUID(). See comments inside the - // SymbolFileDWARF::GetDIEFromUID() for details. - DWARFDIE die = GetDIEFromUID(type_uid); - if (die) + // SymbolFileDWARF::GetDIE(). See comments inside the + // SymbolFileDWARF::GetDIE() for details. + if (DWARFDIE die = GetDIE(type_uid)) return die.GetDecl(); return CompilerDecl(); } @@ -1368,10 +1272,9 @@ SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) { // need to lock the module. std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling - // SymbolFileDWARF::GetDIEFromUID(). See comments inside the - // SymbolFileDWARF::GetDIEFromUID() for details. - DWARFDIE die = GetDIEFromUID(type_uid); - if (die) + // SymbolFileDWARF::GetDIE(). See comments inside the + // SymbolFileDWARF::GetDIE() for details. + if (DWARFDIE die = GetDIE(type_uid)) return die.GetDeclContext(); return CompilerDeclContext(); } @@ -1382,10 +1285,9 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) { // need to lock the module. std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling - // SymbolFileDWARF::GetDIEFromUID(). See comments inside the - // SymbolFileDWARF::GetDIEFromUID() for details. - DWARFDIE die = GetDIEFromUID(type_uid); - if (die) + // SymbolFileDWARF::GetDIE(). See comments inside the + // SymbolFileDWARF::GetDIE() for details. + if (DWARFDIE die = GetDIE(type_uid)) return die.GetContainingDeclContext(); return CompilerDeclContext(); } @@ -1395,10 +1297,9 @@ Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) { // need to lock the module. std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling - // SymbolFileDWARF::GetDIEFromUID(). See comments inside the - // SymbolFileDWARF::GetDIEFromUID() for details. - DWARFDIE type_die = GetDIEFromUID(type_uid); - if (type_die) + // SymbolFileDWARF::GetDIE(). See comments inside the + // SymbolFileDWARF::GetDIE() for details. + if (DWARFDIE type_die = GetDIE(type_uid)) return type_die.ResolveType(); else return nullptr; @@ -1408,8 +1309,7 @@ llvm::Optional<SymbolFile::ArrayInfo> SymbolFileDWARF::GetDynamicArrayInfoForUID( lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); - DWARFDIE type_die = GetDIEFromUID(type_uid); - if (type_die) + if (DWARFDIE type_die = GetDIE(type_uid)) return DWARFASTParser::ParseChildArrayInfo(type_die, exe_ctx); else return llvm::None; @@ -1454,7 +1354,7 @@ Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die, } return ResolveType(die); } - return NULL; + return nullptr; } // This function is used when SymbolFileDWARFDebugMap owns a bunch of @@ -1548,15 +1448,14 @@ Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die, } CompileUnit * -SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFUnit *dwarf_cu, - uint32_t cu_idx) { +SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu) { // Check if the symbol vendor already knows about this compile unit? - if (dwarf_cu->GetUserData() == NULL) { + if (dwarf_cu.GetUserData() == nullptr) { // The symbol vendor doesn't know about this compile unit, we need to parse // and add it to the symbol vendor object. - return ParseCompileUnit(dwarf_cu, cu_idx).get(); + return ParseCompileUnit(dwarf_cu).get(); } - return (CompileUnit *)dwarf_cu->GetUserData(); + return (CompileUnit *)dwarf_cu.GetUserData(); } size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name, @@ -1569,12 +1468,13 @@ size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name, bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) { sc.Clear(false); - if (die) { + if (die && llvm::isa<DWARFCompileUnit>(die.GetCU())) { // Check if the symbol vendor already knows about this compile unit? - sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX); + sc.comp_unit = + GetCompUnitForDWARFCompUnit(llvm::cast<DWARFCompileUnit>(*die.GetCU())); sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get(); - if (sc.function == NULL) + if (sc.function == nullptr) sc.function = ParseFunction(*sc.comp_unit, die); if (sc.function) { @@ -1597,6 +1497,14 @@ lldb::ModuleSP SymbolFileDWARF::GetDWOModule(ConstString name) { DWARFDIE SymbolFileDWARF::GetDIE(const DIERef &die_ref) { + if (die_ref.dwo_num()) { + return DebugInfo() + ->GetUnitAtIndex(*die_ref.dwo_num()) + ->GetDwoSymbolFile() + ->GetDIE(die_ref); + } + + DWARFDebugInfo *debug_info = DebugInfo(); if (debug_info) return debug_info->GetDIE(die_ref); @@ -1606,24 +1514,29 @@ SymbolFileDWARF::GetDIE(const DIERef &die_ref) { std::unique_ptr<SymbolFileDWARFDwo> SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( - DWARFUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) { + DWARFUnit &unit, const DWARFDebugInfoEntry &cu_die) { // If we are using a dSYM file, we never want the standard DWO files since // the -gmodules support uses the same DWO machanism to specify full debug // info files for modules. if (GetDebugMapSymfile()) return nullptr; - const char *dwo_name = cu_die.GetAttributeValueAsString( - this, &dwarf_cu, DW_AT_GNU_dwo_name, nullptr); + DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(&unit); + // Only compile units can be split into two parts. + if (!dwarf_cu) + return nullptr; + + const char *dwo_name = + cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_GNU_dwo_name, nullptr); if (!dwo_name) return nullptr; SymbolFileDWARFDwp *dwp_symfile = GetDwpSymbolFile(); if (dwp_symfile) { - uint64_t dwo_id = cu_die.GetAttributeValueAsUnsigned(this, &dwarf_cu, - DW_AT_GNU_dwo_id, 0); + uint64_t dwo_id = + cu_die.GetAttributeValueAsUnsigned(dwarf_cu, DW_AT_GNU_dwo_id, 0); std::unique_ptr<SymbolFileDWARFDwo> dwo_symfile = - dwp_symfile->GetSymbolFileForDwoId(&dwarf_cu, dwo_id); + dwp_symfile->GetSymbolFileForDwoId(*dwarf_cu, dwo_id); if (dwo_symfile) return dwo_symfile; } @@ -1631,8 +1544,8 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( FileSpec dwo_file(dwo_name); FileSystem::Instance().Resolve(dwo_file); if (dwo_file.IsRelative()) { - const char *comp_dir = cu_die.GetAttributeValueAsString( - this, &dwarf_cu, DW_AT_comp_dir, nullptr); + const char *comp_dir = + cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_comp_dir, nullptr); if (!comp_dir) return nullptr; @@ -1654,7 +1567,7 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( if (dwo_obj_file == nullptr) return nullptr; - return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, &dwarf_cu); + return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, *dwarf_cu); } void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { @@ -1666,7 +1579,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { const uint32_t num_compile_units = GetNumCompileUnits(); for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { - DWARFUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); + DWARFUnit *dwarf_cu = debug_info->GetUnitAtIndex(cu_idx); const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly(); if (die && !die.HasChildren()) { @@ -1708,16 +1621,14 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { // printed. However, as one can notice in this case we don't // actually need to try to load the already loaded module // (corresponding to .dwo) so we simply skip it. - if (m_obj_file->GetFileSpec() - .GetFileNameExtension() - .GetStringRef() == ".dwo" && + if (m_obj_file->GetFileSpec().GetFileNameExtension() == ".dwo" && llvm::StringRef(m_obj_file->GetFileSpec().GetPath()) .endswith(dwo_module_spec.GetFileSpec().GetPath())) { continue; } Status error = ModuleList::GetSharedModule( - dwo_module_spec, module_sp, NULL, NULL, NULL); + dwo_module_spec, module_sp, nullptr, nullptr, nullptr); if (!module_sp) { GetObjectFile()->GetModule()->ReportWarning( "0x%8.8x: unable to locate module needed for external types: " @@ -1737,8 +1648,8 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { } SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() { - if (!m_global_aranges_ap) { - m_global_aranges_ap.reset(new GlobalVariableMap()); + if (!m_global_aranges_up) { + m_global_aranges_up.reset(new GlobalVariableMap()); ModuleSP module_sp = GetObjectFile()->GetModule(); if (module_sp) { @@ -1763,8 +1674,9 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() { location_result.GetScalar().ULongLong(); lldb::addr_t byte_size = 1; if (var_sp->GetType()) - byte_size = var_sp->GetType()->GetByteSize(); - m_global_aranges_ap->Append(GlobalVariableMap::Entry( + byte_size = + var_sp->GetType()->GetByteSize().getValueOr(0); + m_global_aranges_up->Append(GlobalVariableMap::Entry( file_addr, byte_size, var_sp.get())); } } @@ -1774,9 +1686,9 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() { } } } - m_global_aranges_ap->Sort(); + m_global_aranges_up->Sort(); } - return *m_global_aranges_ap; + return *m_global_aranges_up; } uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, @@ -1798,8 +1710,17 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, DWARFDebugInfo *debug_info = DebugInfo(); if (debug_info) { - const dw_offset_t cu_offset = - debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr); + llvm::Expected<DWARFDebugAranges &> aranges = + debug_info->GetCompileUnitAranges(); + if (!aranges) { + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); + LLDB_LOG_ERROR(log, aranges.takeError(), + "SymbolFileDWARF::ResolveSymbolContext failed to get cu " + "aranges. {0}"); + return 0; + } + + const dw_offset_t cu_offset = aranges->FindAddress(file_vm_addr); if (cu_offset == DW_INVALID_OFFSET) { // Global variables are not in the compile unit address ranges. The // only way to currently find global variables is to iterate over the @@ -1822,10 +1743,10 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, } } else { uint32_t cu_idx = DW_INVALID_INDEX; - DWARFUnit *dwarf_cu = - debug_info->GetCompileUnit(cu_offset, &cu_idx); - if (dwarf_cu) { - sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx); + if (auto *dwarf_cu = llvm::dyn_cast_or_null<DWARFCompileUnit>( + debug_info->GetUnitAtOffset(DIERef::Section::DebugInfo, + cu_offset, &cu_idx))) { + sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); if (sc.comp_unit) { resolved |= eSymbolContextCompUnit; @@ -1837,7 +1758,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, if (function_die) { sc.function = sc.comp_unit->FindFunctionByUID(function_die.GetID()).get(); - if (sc.function == NULL) + if (sc.function == nullptr) sc.function = ParseFunction(*sc.comp_unit, function_die); if (sc.function && (resolve_scope & eSymbolContextBlock)) @@ -1852,7 +1773,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, force_check_line_table = true; } - if (sc.function != NULL) { + if (sc.function != nullptr) { resolved |= eSymbolContextFunction; if (resolve_scope & eSymbolContextBlock) { @@ -1871,7 +1792,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, if ((resolve_scope & eSymbolContextLineEntry) || force_check_line_table) { LineTable *line_table = sc.comp_unit->GetLineTable(); - if (line_table != NULL) { + if (line_table != nullptr) { // And address that makes it into this function should be in // terms of this debug file if there is no debug map, or it // will be an address in the .o file which needs to be fixed up @@ -1895,7 +1816,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, // only happen when there aren't other functions from other // compile units in these gaps. This helps keep the size of the // aranges down. - sc.comp_unit = NULL; + sc.comp_unit = nullptr; resolved &= ~eSymbolContextCompUnit; } } else { @@ -1918,110 +1839,100 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec, SymbolContextList &sc_list) { const uint32_t prev_size = sc_list.GetSize(); if (resolve_scope & eSymbolContextCompUnit) { - DWARFDebugInfo *debug_info = DebugInfo(); - if (debug_info) { - uint32_t cu_idx; - DWARFUnit *dwarf_cu = NULL; - - for (cu_idx = 0; - (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; - ++cu_idx) { - CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx); - const bool full_match = (bool)file_spec.GetDirectory(); - bool file_spec_matches_cu_file_spec = - dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match); - if (check_inlines || file_spec_matches_cu_file_spec) { - SymbolContext sc(m_obj_file->GetModule()); - sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx); - if (sc.comp_unit) { - uint32_t file_idx = UINT32_MAX; + for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus; + ++cu_idx) { + CompileUnit *dc_cu = ParseCompileUnitAtIndex(cu_idx).get(); + if (!dc_cu) + continue; + + const bool full_match = (bool)file_spec.GetDirectory(); + bool file_spec_matches_cu_file_spec = + FileSpec::Equal(file_spec, *dc_cu, full_match); + if (check_inlines || file_spec_matches_cu_file_spec) { + SymbolContext sc(m_obj_file->GetModule()); + sc.comp_unit = dc_cu; + uint32_t file_idx = UINT32_MAX; + + // If we are looking for inline functions only and we don't find it + // in the support files, we are done. + if (check_inlines) { + file_idx = + sc.comp_unit->GetSupportFiles().FindFileIndex(1, file_spec, true); + if (file_idx == UINT32_MAX) + continue; + } - // If we are looking for inline functions only and we don't find it - // in the support files, we are done. - if (check_inlines) { + if (line != 0) { + LineTable *line_table = sc.comp_unit->GetLineTable(); + + if (line_table != nullptr && line != 0) { + // We will have already looked up the file index if we are + // searching for inline entries. + if (!check_inlines) file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex( 1, file_spec, true); - if (file_idx == UINT32_MAX) - continue; - } - - if (line != 0) { - LineTable *line_table = sc.comp_unit->GetLineTable(); - if (line_table != NULL && line != 0) { - // We will have already looked up the file index if we are - // searching for inline entries. - if (!check_inlines) - file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex( - 1, file_spec, true); - - if (file_idx != UINT32_MAX) { - uint32_t found_line; - uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex( - 0, file_idx, line, false, &sc.line_entry); - found_line = sc.line_entry.line; - - while (line_idx != UINT32_MAX) { - sc.function = NULL; - sc.block = NULL; - if (resolve_scope & - (eSymbolContextFunction | eSymbolContextBlock)) { - const lldb::addr_t file_vm_addr = - sc.line_entry.range.GetBaseAddress().GetFileAddress(); - if (file_vm_addr != LLDB_INVALID_ADDRESS) { - DWARFDIE function_die = - dwarf_cu->LookupAddress(file_vm_addr); - DWARFDIE block_die; - if (function_die) { - sc.function = - sc.comp_unit - ->FindFunctionByUID(function_die.GetID()) - .get(); - if (sc.function == NULL) - sc.function = - ParseFunction(*sc.comp_unit, function_die); - - if (sc.function && - (resolve_scope & eSymbolContextBlock)) - block_die = - function_die.LookupDeepestBlock(file_vm_addr); - } + if (file_idx != UINT32_MAX) { + uint32_t found_line; + uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex( + 0, file_idx, line, false, &sc.line_entry); + found_line = sc.line_entry.line; + + while (line_idx != UINT32_MAX) { + sc.function = nullptr; + sc.block = nullptr; + if (resolve_scope & + (eSymbolContextFunction | eSymbolContextBlock)) { + const lldb::addr_t file_vm_addr = + sc.line_entry.range.GetBaseAddress().GetFileAddress(); + if (file_vm_addr != LLDB_INVALID_ADDRESS) { + DWARFDIE function_die = + GetDWARFCompileUnit(dc_cu)->LookupAddress(file_vm_addr); + DWARFDIE block_die; + if (function_die) { + sc.function = + sc.comp_unit->FindFunctionByUID(function_die.GetID()) + .get(); + if (sc.function == nullptr) + sc.function = + ParseFunction(*sc.comp_unit, function_die); + + if (sc.function && (resolve_scope & eSymbolContextBlock)) + block_die = + function_die.LookupDeepestBlock(file_vm_addr); + } - if (sc.function != NULL) { - Block &block = sc.function->GetBlock(true); + if (sc.function != nullptr) { + Block &block = sc.function->GetBlock(true); - if (block_die) - sc.block = block.FindBlockByID(block_die.GetID()); - else if (function_die) - sc.block = - block.FindBlockByID(function_die.GetID()); - } - } + if (block_die) + sc.block = block.FindBlockByID(block_die.GetID()); + else if (function_die) + sc.block = block.FindBlockByID(function_die.GetID()); } - - sc_list.Append(sc); - line_idx = line_table->FindLineEntryIndexByFileIndex( - line_idx + 1, file_idx, found_line, true, - &sc.line_entry); } } - } else if (file_spec_matches_cu_file_spec && !check_inlines) { - // only append the context if we aren't looking for inline call - // sites by file and line and if the file spec matches that of - // the compile unit + sc_list.Append(sc); + line_idx = line_table->FindLineEntryIndexByFileIndex( + line_idx + 1, file_idx, found_line, true, &sc.line_entry); } - } else if (file_spec_matches_cu_file_spec && !check_inlines) { - // only append the context if we aren't looking for inline call - // sites by file and line and if the file spec matches that of - // the compile unit - sc_list.Append(sc); } - - if (!check_inlines) - break; + } else if (file_spec_matches_cu_file_spec && !check_inlines) { + // only append the context if we aren't looking for inline call + // sites by file and line and if the file spec matches that of + // the compile unit + sc_list.Append(sc); } + } else if (file_spec_matches_cu_file_spec && !check_inlines) { + // only append the context if we aren't looking for inline call + // sites by file and line and if the file spec matches that of + // the compile unit + sc_list.Append(sc); } + + if (!check_inlines) + break; } } } @@ -2066,7 +1977,7 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile( } uint32_t SymbolFileDWARF::FindGlobalVariables( - const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext *parent_decl_ctx, uint32_t max_matches, VariableList &variables) { Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); @@ -2082,7 +1993,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables( return 0; DWARFDebugInfo *info = DebugInfo(); - if (info == NULL) + if (info == nullptr) return 0; // Remember how many variables are in the list before we search. @@ -2090,6 +2001,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables( llvm::StringRef basename; llvm::StringRef context; + bool name_is_mangled = (bool)Mangled(name); if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name.GetCString(), context, basename)) @@ -2122,7 +2034,10 @@ uint32_t SymbolFileDWARF::FindGlobalVariables( break; case DW_TAG_variable: { - sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX); + auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU()); + if (!dwarf_cu) + continue; + sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); if (parent_decl_ctx) { DWARFASTParser *dwarf_ast = die.GetDWARFParser(); @@ -2139,7 +2054,8 @@ uint32_t SymbolFileDWARF::FindGlobalVariables( &variables); while (pruned_idx < variables.GetSize()) { VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx); - if (var_sp->GetName().GetStringRef().contains(name.GetStringRef())) + if (name_is_mangled || + var_sp->GetName().GetStringRef().contains(name.GetStringRef())) ++pruned_idx; else variables.RemoveVariableAtIndex(pruned_idx); @@ -2150,8 +2066,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables( } break; } } else { - m_index->ReportInvalidDIEOffset(die_ref.die_offset, - name.GetStringRef()); + m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); } } } @@ -2183,7 +2098,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex, } DWARFDebugInfo *info = DebugInfo(); - if (info == NULL) + if (info == nullptr) return 0; // Remember how many variables are in the list before we search. @@ -2203,14 +2118,18 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex, DWARFDIE die = GetDIE(die_ref); if (die) { - sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX); + DWARFCompileUnit *dwarf_cu = + llvm::dyn_cast<DWARFCompileUnit>(die.GetCU()); + if (!dwarf_cu) + continue; + sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); if (variables.GetSize() - original_size >= max_matches) break; } else - m_index->ReportInvalidDIEOffset(die_ref.die_offset, regex.GetText()); + m_index->ReportInvalidDIERef(die_ref, regex.GetText()); } } @@ -2236,7 +2155,7 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, if (die.Tag() == DW_TAG_inlined_subroutine) { inlined_die = die; - while (1) { + while (true) { die = die.GetParent(); if (die) { @@ -2253,12 +2172,12 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, if (inlined_die) { Block &function_block = sc.function->GetBlock(true); sc.block = function_block.FindBlockByID(inlined_die.GetID()); - if (sc.block == NULL) + if (sc.block == nullptr) sc.block = function_block.FindBlockByID(inlined_die.GetOffset()); - if (sc.block == NULL || !sc.block->GetStartAddress(addr)) + if (sc.block == nullptr || !sc.block->GetStartAddress(addr)) addr.Clear(); } else { - sc.block = NULL; + sc.block = nullptr; addr = sc.function->GetAddressRange().GetBaseAddress(); } @@ -2285,14 +2204,14 @@ bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx, CompilerDeclContext actual_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); if (actual_decl_ctx) - return actual_decl_ctx == *decl_ctx; + return decl_ctx->IsContainedInLookup(actual_decl_ctx); } } return false; } uint32_t SymbolFileDWARF::FindFunctions( - const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext *parent_decl_ctx, FunctionNameType name_type_mask, bool include_inlines, bool append, SymbolContextList &sc_list) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); @@ -2328,10 +2247,6 @@ uint32_t SymbolFileDWARF::FindFunctions( const uint32_t original_size = sc_list.GetSize(); - DWARFDebugInfo *info = DebugInfo(); - if (info == NULL) - return 0; - llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies; DIEArray offsets; CompilerDeclContext empty_decl_ctx; @@ -2339,7 +2254,7 @@ uint32_t SymbolFileDWARF::FindFunctions( parent_decl_ctx = &empty_decl_ctx; std::vector<DWARFDIE> dies; - m_index->GetFunctions(name, *info, *parent_decl_ctx, name_type_mask, dies); + m_index->GetFunctions(name, *this, *parent_decl_ctx, name_type_mask, dies); for (const DWARFDIE &die: dies) { if (resolved_dies.insert(die.GetDIE()).second) ResolveFunction(die, include_inlines, sc_list); @@ -2394,7 +2309,7 @@ uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression ®ex, for (DIERef ref : offsets) { DWARFDIE die = info->GetDIE(ref); if (!die) { - m_index->ReportInvalidDIEOffset(ref.die_offset, regex.GetText()); + m_index->ReportInvalidDIERef(ref, regex.GetText()); continue; } if (resolved_dies.insert(die.GetDIE()).second) @@ -2411,10 +2326,10 @@ void SymbolFileDWARF::GetMangledNamesForFunction( DWARFDebugInfo *info = DebugInfo(); uint32_t num_comp_units = 0; if (info) - num_comp_units = info->GetNumCompileUnits(); + num_comp_units = info->GetNumUnits(); for (uint32_t i = 0; i < num_comp_units; i++) { - DWARFUnit *cu = info->GetCompileUnitAtIndex(i); + DWARFUnit *cu = info->GetUnitAtIndex(i); if (cu == nullptr) continue; @@ -2423,21 +2338,15 @@ void SymbolFileDWARF::GetMangledNamesForFunction( dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names); } - NameToOffsetMap::iterator iter = - m_function_scope_qualified_name_map.find(scope_qualified_name); - if (iter == m_function_scope_qualified_name_map.end()) - return; - - DIERefSetSP set_sp = (*iter).second; - std::set<DIERef>::iterator set_iter; - for (set_iter = set_sp->begin(); set_iter != set_sp->end(); set_iter++) { - DWARFDIE die = DebugInfo()->GetDIE(*set_iter); + for (lldb::user_id_t uid : + m_function_scope_qualified_name_map.lookup(scope_qualified_name)) { + DWARFDIE die = GetDIE(uid); mangled_names.push_back(ConstString(die.GetMangledName())); } } uint32_t SymbolFileDWARF::FindTypes( - const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap &types) { @@ -2452,7 +2361,7 @@ uint32_t SymbolFileDWARF::FindTypes( searched_symbol_files.insert(this); DWARFDebugInfo *info = DebugInfo(); - if (info == NULL) + if (info == nullptr) return 0; Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); @@ -2497,8 +2406,7 @@ uint32_t SymbolFileDWARF::FindTypes( break; } } else { - m_index->ReportInvalidDIEOffset(die_ref.die_offset, - name.GetStringRef()); + m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); } } const uint32_t num_matches = types.GetSize() - initial_types_size; @@ -2576,8 +2484,7 @@ size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context, ++num_matches; } } else { - m_index->ReportInvalidDIEOffset(die_ref.die_offset, - name.GetStringRef()); + m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); } } return num_matches; @@ -2586,7 +2493,7 @@ size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context, } CompilerDeclContext -SymbolFileDWARF::FindNamespace(const ConstString &name, +SymbolFileDWARF::FindNamespace(ConstString name, const CompilerDeclContext *parent_decl_ctx) { Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); @@ -2622,8 +2529,7 @@ SymbolFileDWARF::FindNamespace(const ConstString &name, break; } } else { - m_index->ReportInvalidDIEOffset(die_ref.die_offset, - name.GetStringRef()); + m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); } } } @@ -2646,10 +2552,14 @@ TypeSP SymbolFileDWARF::GetTypeForDIE(const DWARFDIE &die, TypeSP type_sp; if (die) { Type *type_ptr = GetDIEToType().lookup(die.GetDIE()); - if (type_ptr == NULL) { - CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU()); - assert(lldb_cu); - SymbolContext sc(lldb_cu); + if (type_ptr == nullptr) { + SymbolContextScope *scope; + if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU())) + scope = GetCompUnitForDWARFCompUnit(*dwarf_cu); + else + scope = GetObjectFile()->GetModule().get(); + assert(scope); + SymbolContext sc(scope); const DWARFDebugInfoEntry *parent_die = die.GetParent().GetDIE(); while (parent_die != nullptr) { if (parent_die->Tag() == DW_TAG_subprogram) @@ -2661,7 +2571,7 @@ TypeSP SymbolFileDWARF::GetTypeForDIE(const DWARFDIE &die, !GetFunction(DWARFDIE(die.GetCU(), parent_die), sc)) sc = sc_backup; - type_sp = ParseType(sc, die, NULL); + type_sp = ParseType(sc, die, nullptr); } else if (type_ptr != DIE_IS_BEING_PARSED) { // Grab the existing type from the master types lists type_sp = type_ptr->shared_from_this(); @@ -2723,8 +2633,8 @@ SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE &orig_die) { } Symbol * -SymbolFileDWARF::GetObjCClassSymbol(const ConstString &objc_class_name) { - Symbol *objc_class_symbol = NULL; +SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) { + Symbol *objc_class_symbol = nullptr; if (m_obj_file) { Symtab *symtab = m_obj_file->GetSymtab(); if (symtab) { @@ -2753,7 +2663,7 @@ bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type( DWARFDebugInfo *debug_info = DebugInfo(); const uint32_t num_compile_units = GetNumCompileUnits(); for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { - DWARFUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); + DWARFUnit *dwarf_cu = debug_info->GetUnitAtIndex(cu_idx); if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type()) { m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; @@ -2771,7 +2681,7 @@ bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type( // This function can be used when a DIE is found that is a forward declaration // DIE and we want to try and find a type that has the complete definition. TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE( - const DWARFDIE &die, const ConstString &type_name, + const DWARFDIE &die, ConstString type_name, bool must_be_implementation) { TypeSP type_sp; @@ -2829,15 +2739,13 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE( } } } else { - m_index->ReportInvalidDIEOffset(die_ref.die_offset, - type_name.GetStringRef()); + m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef()); } } } return type_sp; } -//---------------------------------------------------------------------- // This function helps to ensure that the declaration contexts match for two // different DIEs. Often times debug information will refer to a forward // declaration of a type (the equivalent of "struct my_struct;". There will @@ -2847,14 +2755,13 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE( // type was in the same declaration context as the original DIE. This function // can efficiently compare two DIEs and will return true when the declaration // context matches, and false when they don't. -//---------------------------------------------------------------------- bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE &die1, const DWARFDIE &die2) { if (die1 == die2) return true; - DWARFDIECollection decl_ctx_1; - DWARFDIECollection decl_ctx_2; + std::vector<DWARFDIE> decl_ctx_1; + std::vector<DWARFDIE> decl_ctx_2; // The declaration DIE stack is a stack of the declaration context DIEs all // the way back to the compile unit. If a type "T" is declared inside a class // "B", and class "B" is declared inside a class "A" and class "A" is in a @@ -2870,11 +2777,11 @@ bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE &die1, // back to the compiler unit. // First lets grab the decl contexts for both DIEs - die1.GetDeclContextDIEs(decl_ctx_1); - die2.GetDeclContextDIEs(decl_ctx_2); + decl_ctx_1 = die1.GetDeclContextDIEs(); + decl_ctx_2 = die2.GetDeclContextDIEs(); // Make sure the context arrays have the same size, otherwise we are done - const size_t count1 = decl_ctx_1.Size(); - const size_t count2 = decl_ctx_2.Size(); + const size_t count1 = decl_ctx_1.size(); + const size_t count2 = decl_ctx_2.size(); if (count1 != count2) return false; @@ -2884,18 +2791,18 @@ bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE &die1, DWARFDIE decl_ctx_die2; size_t i; for (i = 0; i < count1; i++) { - decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex(i); - decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex(i); + decl_ctx_die1 = decl_ctx_1[i]; + decl_ctx_die2 = decl_ctx_2[i]; if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag()) return false; } -#if defined LLDB_CONFIGURATION_DEBUG +#ifndef NDEBUG // Make sure the top item in the decl context die array is always // DW_TAG_compile_unit or DW_TAG_partial_unit. If it isn't then // something went wrong in the DWARFDIE::GetDeclContextDIEs() // function. - dw_tag_t cu_tag = decl_ctx_1.GetDIEAtIndex(count1 - 1).Tag(); + dw_tag_t cu_tag = decl_ctx_1[count1 - 1].Tag(); UNUSED_IF_ASSERT_DISABLED(cu_tag); assert(cu_tag == DW_TAG_compile_unit || cu_tag == DW_TAG_partial_unit); @@ -2903,8 +2810,8 @@ bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE &die1, // Always skip the compile unit when comparing by only iterating up to "count // - 1". Here we compare the names as we go. for (i = 0; i < count1 - 1; i++) { - decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex(i); - decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex(i); + decl_ctx_die1 = decl_ctx_1[i]; + decl_ctx_die2 = decl_ctx_2[i]; const char *name1 = decl_ctx_die1.GetName(); const char *name2 = decl_ctx_die2.GetName(); // If the string was from a DW_FORM_strp, then the pointer will often be @@ -3039,8 +2946,7 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext( } } } else { - m_index->ReportInvalidDIEOffset(die_ref.die_offset, - type_name.GetStringRef()); + m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef()); } } } @@ -3051,42 +2957,32 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext( TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die, bool *type_is_new_ptr) { - TypeSP type_sp; + if (!die) + return {}; - if (die) { - TypeSystem *type_system = - GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); + TypeSystem *type_system = + GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); + if (!type_system) + return {}; - if (type_system) { - DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); - if (dwarf_ast) { - Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); - type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, log, type_is_new_ptr); - if (type_sp) { - TypeList *type_list = GetTypeList(); - if (type_list) - type_list->Insert(type_sp); - - if (die.Tag() == DW_TAG_subprogram) { - DIERef die_ref = die.GetDIERef(); - std::string scope_qualified_name(GetDeclContextForUID(die.GetID()) - .GetScopeQualifiedName() - .AsCString("")); - if (scope_qualified_name.size()) { - NameToOffsetMap::iterator iter = - m_function_scope_qualified_name_map.find( - scope_qualified_name); - if (iter != m_function_scope_qualified_name_map.end()) - (*iter).second->insert(die_ref); - else { - DIERefSetSP new_set(new std::set<DIERef>); - new_set->insert(die_ref); - m_function_scope_qualified_name_map.emplace( - std::make_pair(scope_qualified_name, new_set)); - } - } - } - } + DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); + if (!dwarf_ast) + return {}; + + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); + TypeSP type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, log, type_is_new_ptr); + if (type_sp) { + TypeList *type_list = GetTypeList(); + if (type_list) + type_list->Insert(type_sp); + + if (die.Tag() == DW_TAG_subprogram) { + std::string scope_qualified_name(GetDeclContextForUID(die.GetID()) + .GetScopeQualifiedName() + .AsCString("")); + if (scope_qualified_name.size()) { + m_function_scope_qualified_name_map[scope_qualified_name].insert( + die.GetID()); } } } @@ -3161,13 +3057,13 @@ size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) { size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { ASSERT_MODULE_LOCK(this); - if (sc.comp_unit != NULL) { + if (sc.comp_unit != nullptr) { DWARFDebugInfo *info = DebugInfo(); - if (info == NULL) + if (info == nullptr) return 0; if (sc.function) { - DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID(), this)); + DWARFDIE function_die = GetDIE(sc.function->GetID()); const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress( DW_AT_low_pc, LLDB_INVALID_ADDRESS); @@ -3180,20 +3076,21 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { return num_variables; } } else if (sc.comp_unit) { - DWARFUnit *dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID()); + DWARFUnit *dwarf_cu = info->GetUnitAtIndex(sc.comp_unit->GetID()); - if (dwarf_cu == NULL) + if (dwarf_cu == nullptr) return 0; uint32_t vars_added = 0; VariableListSP variables(sc.comp_unit->GetVariableList(false)); - if (variables.get() == NULL) { - variables.reset(new VariableList()); + if (variables.get() == nullptr) { + variables = std::make_shared<VariableList>(); sc.comp_unit->SetVariableList(variables); DIEArray die_offsets; - m_index->GetGlobalVariables(*dwarf_cu, die_offsets); + m_index->GetGlobalVariables(dwarf_cu->GetNonSkeletonUnit(), + die_offsets); const size_t num_matches = die_offsets.size(); if (num_matches) { for (size_t i = 0; i < num_matches; ++i) { @@ -3207,7 +3104,7 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { ++vars_added; } } else - m_index->ReportInvalidDIEOffset(die_ref.die_offset, ""); + m_index->ReportInvalidDIERef(die_ref, ""); } } } @@ -3240,12 +3137,12 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, const size_t num_attributes = die.GetAttributes(attributes); DWARFDIE spec_die; if (num_attributes > 0) { - const char *name = NULL; - const char *mangled = NULL; + const char *name = nullptr; + const char *mangled = nullptr; Declaration decl; uint32_t i; DWARFFormValue type_die_form; - DWARFExpression location(die.GetCU()); + DWARFExpression location; bool is_external = false; bool is_artificial = false; bool location_is_const_value_data = false; @@ -3296,18 +3193,16 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); uint32_t block_length = form_value.Unsigned(); - location.CopyOpcodeData(module, debug_info_data, block_offset, - block_length); + location = DWARFExpression(module, debug_info_data, die.GetCU(), + block_offset, block_length); } else if (DWARFFormValue::IsDataForm(form_value.Form())) { // Retrieve the value as a data expression. - DWARFFormValue::FixedFormSizes fixed_form_sizes = - DWARFFormValue::GetFixedFormSizesForAddressSize( - attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), - attributes.CompileUnitAtIndex(i)->IsDWARF64()); uint32_t data_offset = attributes.DIEOffsetAtIndex(i); - uint32_t data_length = - fixed_form_sizes.GetSize(form_value.Form()); - if (data_length == 0) { + if (auto data_length = form_value.GetFixedSize()) + location = + DWARFExpression(module, debug_info_data, die.GetCU(), + data_offset, *data_length); + else { const uint8_t *data_pointer = form_value.BlockData(); if (data_pointer) { form_value.Unsigned(); @@ -3316,29 +3211,23 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, // create the variable const_value = form_value; } - } else - location.CopyOpcodeData(module, debug_info_data, data_offset, - data_length); + } } else { // Retrieve the value as a string expression. if (form_value.Form() == DW_FORM_strp) { - DWARFFormValue::FixedFormSizes fixed_form_sizes = - DWARFFormValue::GetFixedFormSizesForAddressSize( - attributes.CompileUnitAtIndex(i) - ->GetAddressByteSize(), - attributes.CompileUnitAtIndex(i)->IsDWARF64()); uint32_t data_offset = attributes.DIEOffsetAtIndex(i); - uint32_t data_length = - fixed_form_sizes.GetSize(form_value.Form()); - location.CopyOpcodeData(module, debug_info_data, data_offset, - data_length); + if (auto data_length = form_value.GetFixedSize()) + location = + DWARFExpression(module, debug_info_data, die.GetCU(), + data_offset, *data_length); } else { const char *str = form_value.AsCString(); uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart(); uint32_t string_length = strlen(str) + 1; - location.CopyOpcodeData(module, debug_info_data, - string_offset, string_length); + location = + DWARFExpression(module, debug_info_data, die.GetCU(), + string_offset, string_length); } } } @@ -3352,7 +3241,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, uint32_t block_offset = form_value.BlockData() - data.GetDataStart(); uint32_t block_length = form_value.Unsigned(); - location.CopyOpcodeData(module, data, block_offset, block_length); + location = DWARFExpression(module, data, die.GetCU(), + block_offset, block_length); } else { const DWARFDataExtractor &debug_loc_data = DebugLocData(); const dw_offset_t debug_loc_offset = form_value.Unsigned(); @@ -3360,8 +3250,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, size_t loc_list_length = DWARFExpression::LocationListSize( die.GetCU(), debug_loc_data, debug_loc_offset); if (loc_list_length > 0) { - location.CopyOpcodeData(module, debug_loc_data, - debug_loc_offset, loc_list_length); + location = DWARFExpression(module, debug_loc_data, die.GetCU(), + debug_loc_offset, loc_list_length); assert(func_low_pc != LLDB_INVALID_ADDRESS); location.SetLocationListSlide( func_low_pc - @@ -3370,31 +3260,11 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, } } break; case DW_AT_specification: - spec_die = GetDIE(DIERef(form_value)); + spec_die = form_value.Reference(); + break; + case DW_AT_start_scope: + // TODO: Implement this. break; - case DW_AT_start_scope: { - if (form_value.Form() == DW_FORM_sec_offset) { - DWARFRangeList dwarf_scope_ranges; - const DWARFDebugRangesBase *debug_ranges = DebugRanges(); - debug_ranges->FindRanges(die.GetCU(), - form_value.Unsigned(), - dwarf_scope_ranges); - } else { - // TODO: Handle the case when DW_AT_start_scope have form - // constant. The - // dwarf spec is a bit ambiguous about what is the expected - // behavior in case the enclosing block have a non coninious - // address range and the DW_AT_start_scope entry have a form - // constant. - GetObjectFile()->GetModule()->ReportWarning( - "0x%8.8" PRIx64 - ": DW_AT_start_scope has unsupported form type (0x%x)\n", - die.GetID(), form_value.Form()); - } - - scope_ranges.Sort(); - scope_ranges.CombineConsecutiveRanges(); - } break; case DW_AT_artificial: is_artificial = form_value.Boolean(); break; @@ -3425,7 +3295,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, ValueType scope = eValueTypeInvalid; const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die); - SymbolContextScope *symbol_context_scope = NULL; + SymbolContextScope *symbol_context_scope = nullptr; bool has_explicit_mangled = mangled != nullptr; if (!mangled) { @@ -3471,7 +3341,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, if (op_error) { StreamString strm; location.DumpLocationForAddress(&strm, eDescriptionLevelFull, 0, 0, - NULL); + nullptr); GetObjectFile()->GetModule()->ReportError( "0x%8.8x: %s has an invalid location: %s", die.GetOffset(), die.GetTagAsCString(), strm.GetData()); @@ -3574,7 +3444,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, } } - if (symbol_context_scope == NULL) { + if (symbol_context_scope == nullptr) { switch (parent_tag) { case DW_TAG_subprogram: case DW_TAG_inlined_subroutine: @@ -3582,7 +3452,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, if (sc.function) { symbol_context_scope = sc.function->GetBlock(true).FindBlockByID( sc_parent_die.GetID()); - if (symbol_context_scope == NULL) + if (symbol_context_scope == nullptr) symbol_context_scope = sc.function; } break; @@ -3595,17 +3465,17 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, if (symbol_context_scope) { SymbolFileTypeSP type_sp( - new SymbolFileType(*this, DIERef(type_die_form).GetUID(this))); + new SymbolFileType(*this, GetUID(type_die_form.Reference()))); if (const_value.Form() && type_sp && type_sp->GetType()) - location.CopyOpcodeData(const_value.Unsigned(), - type_sp->GetType()->GetByteSize(), - die.GetCU()->GetAddressByteSize()); + location.UpdateValue(const_value.Unsigned(), + type_sp->GetType()->GetByteSize().getValueOr(0), + die.GetCU()->GetAddressByteSize()); - var_sp.reset(new Variable(die.GetID(), name, mangled, type_sp, scope, - symbol_context_scope, scope_ranges, &decl, - location, is_external, is_artificial, - is_static_member)); + var_sp = std::make_shared<Variable>( + die.GetID(), name, mangled, type_sp, scope, symbol_context_scope, + scope_ranges, &decl, location, is_external, is_artificial, + is_static_member); var_sp->SetLocationIsConstantValueData(location_is_const_value_data); } else { @@ -3644,12 +3514,11 @@ SymbolFileDWARF::FindBlockContainingSpecification( case DW_TAG_subprogram: case DW_TAG_inlined_subroutine: case DW_TAG_lexical_block: { - if (die.GetAttributeValueAsReference( - DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset) + if (die.GetReferencedDIE(DW_AT_specification).GetOffset() == + spec_block_die_offset) return die; - if (die.GetAttributeValueAsReference(DW_AT_abstract_origin, - DW_INVALID_OFFSET) == + if (die.GetReferencedDIE(DW_AT_abstract_origin).GetOffset() == spec_block_die_offset) return die; } break; @@ -3694,16 +3563,16 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc, // We haven't already parsed it, lets do that now. if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) || (tag == DW_TAG_formal_parameter && sc.function)) { - if (variable_list_sp.get() == NULL) { + if (variable_list_sp.get() == nullptr) { DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die); dw_tag_t parent_tag = sc_parent_die.Tag(); switch (parent_tag) { case DW_TAG_compile_unit: case DW_TAG_partial_unit: - if (sc.comp_unit != NULL) { + if (sc.comp_unit != nullptr) { variable_list_sp = sc.comp_unit->GetVariableList(false); - if (variable_list_sp.get() == NULL) { - variable_list_sp.reset(new VariableList()); + if (variable_list_sp.get() == nullptr) { + variable_list_sp = std::make_shared<VariableList>(); } } else { GetObjectFile()->GetModule()->ReportError( @@ -3718,31 +3587,31 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc, case DW_TAG_subprogram: case DW_TAG_inlined_subroutine: case DW_TAG_lexical_block: - if (sc.function != NULL) { + if (sc.function != nullptr) { // Check to see if we already have parsed the variables for the // given scope Block *block = sc.function->GetBlock(true).FindBlockByID( sc_parent_die.GetID()); - if (block == NULL) { + if (block == nullptr) { // This must be a specification or abstract origin with a // concrete block counterpart in the current function. We need // to find the concrete block so we can correctly add the // variable to it const DWARFDIE concrete_block_die = FindBlockContainingSpecification( - DIERef(sc.function->GetID(), this), + GetDIE(sc.function->GetID()), sc_parent_die.GetOffset()); if (concrete_block_die) block = sc.function->GetBlock(true).FindBlockByID( concrete_block_die.GetID()); } - if (block != NULL) { + if (block != nullptr) { const bool can_create = false; variable_list_sp = block->GetBlockVariableList(can_create); - if (variable_list_sp.get() == NULL) { - variable_list_sp.reset(new VariableList()); + if (variable_list_sp.get() == nullptr) { + variable_list_sp = std::make_shared<VariableList>(); block->SetVariableList(variable_list_sp); } } @@ -3770,7 +3639,7 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc, } } - bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram); + bool skip_children = (sc.function == nullptr && tag == DW_TAG_subprogram); if (!skip_children && parse_children && die.HasChildren()) { vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true, @@ -3833,15 +3702,13 @@ CollectCallEdges(DWARFDIE function_die) { std::vector<lldb_private::CallEdge> SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) { - DWARFDIE func_die = GetDIEFromUID(func_id.GetID()); + DWARFDIE func_die = GetDIE(func_id.GetID()); if (func_die.IsValid()) return CollectCallEdges(func_die); return {}; } -//------------------------------------------------------------------ // PluginInterface protocol -//------------------------------------------------------------------ ConstString SymbolFileDWARF::GetPluginName() { return GetPluginNameStatic(); } uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; } @@ -3857,7 +3724,7 @@ void SymbolFileDWARF::DumpClangAST(Stream &s) { } SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() { - if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired()) { + if (m_debug_map_symfile == nullptr && !m_debug_map_module_wp.expired()) { lldb::ModuleSP module_sp(m_debug_map_module_wp.lock()); if (module_sp) { SymbolVendor *sym_vendor = module_sp->GetSymbolVendor(); @@ -3882,7 +3749,10 @@ SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() { module_spec.GetFileSpec() = m_obj_file->GetFileSpec(); module_spec.GetSymbolFileSpec() = FileSpec(m_obj_file->GetFileSpec().GetPath() + ".dwp"); - FileSpec dwp_filespec = Symbols::LocateExecutableSymbolFile(module_spec); + + FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); + FileSpec dwp_filespec = + Symbols::LocateExecutableSymbolFile(module_spec, search_paths); if (FileSystem::Instance().Exists(dwp_filespec)) { m_dwp_symfile = SymbolFileDWARFDwp::Create(GetObjectFile()->GetModule(), dwp_filespec); |