4661 lines · cpp
1//===-- SymbolFileDWARF.cpp -----------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "SymbolFileDWARF.h"10#include "clang/Basic/ABI.h"11#include "llvm/ADT/STLExtras.h"12#include "llvm/ADT/StringExtras.h"13#include "llvm/ADT/StringRef.h"14#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"15#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"16#include "llvm/Support/Casting.h"17#include "llvm/Support/Error.h"18#include "llvm/Support/FileUtilities.h"19#include "llvm/Support/FormatAdapters.h"20#include "llvm/Support/Threading.h"21 22#include "lldb/Core/Module.h"23#include "lldb/Core/ModuleList.h"24#include "lldb/Core/ModuleSpec.h"25#include "lldb/Core/PluginManager.h"26#include "lldb/Core/Progress.h"27#include "lldb/Core/Section.h"28#include "lldb/Core/Value.h"29#include "lldb/Expression/Expression.h"30#include "lldb/Utility/ArchSpec.h"31#include "lldb/Utility/LLDBLog.h"32#include "lldb/Utility/RegularExpression.h"33#include "lldb/Utility/Scalar.h"34#include "lldb/Utility/StreamString.h"35#include "lldb/Utility/StructuredData.h"36#include "lldb/Utility/Timer.h"37 38#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"39#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"40 41#include "lldb/Host/FileSystem.h"42#include "lldb/Host/Host.h"43 44#include "lldb/Interpreter/OptionValueFileSpecList.h"45#include "lldb/Interpreter/OptionValueProperties.h"46 47#include "Plugins/ExpressionParser/Clang/ClangUtil.h"48#include "Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h"49#include "Plugins/SymbolFile/DWARF/SymbolFileWasm.h"50#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"51#include "lldb/Symbol/Block.h"52#include "lldb/Symbol/CompileUnit.h"53#include "lldb/Symbol/CompilerDecl.h"54#include "lldb/Symbol/CompilerDeclContext.h"55#include "lldb/Symbol/DebugMacros.h"56#include "lldb/Symbol/LineTable.h"57#include "lldb/Symbol/ObjectFile.h"58#include "lldb/Symbol/SymbolFile.h"59#include "lldb/Symbol/TypeMap.h"60#include "lldb/Symbol/TypeSystem.h"61#include "lldb/Symbol/VariableList.h"62 63#include "lldb/Target/Language.h"64#include "lldb/Target/Target.h"65 66#include "AppleDWARFIndex.h"67#include "DWARFASTParser.h"68#include "DWARFASTParserClang.h"69#include "DWARFCompileUnit.h"70#include "DWARFDebugAranges.h"71#include "DWARFDebugInfo.h"72#include "DWARFDebugMacro.h"73#include "DWARFDeclContext.h"74#include "DWARFFormValue.h"75#include "DWARFTypeUnit.h"76#include "DWARFUnit.h"77#include "DebugNamesDWARFIndex.h"78#include "LogChannelDWARF.h"79#include "ManualDWARFIndex.h"80#include "SymbolFileDWARFDebugMap.h"81#include "SymbolFileDWARFDwo.h"82#include "lldb/lldb-private-enumerations.h"83 84#include "llvm/DebugInfo/DWARF/DWARFContext.h"85#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"86#include "llvm/Demangle/Demangle.h"87#include "llvm/Support/FileSystem.h"88#include "llvm/Support/FormatVariadic.h"89 90#include <algorithm>91#include <map>92#include <memory>93#include <optional>94 95#include <cctype>96#include <cstring>97 98//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN99 100#ifdef ENABLE_DEBUG_PRINTF101#include <cstdio>102#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)103#else104#define DEBUG_PRINTF(fmt, ...)105#endif106 107using namespace lldb;108using namespace lldb_private;109using namespace lldb_private::plugin::dwarf;110using namespace llvm::dwarf;111 112LLDB_PLUGIN_DEFINE(SymbolFileDWARF)113 114char SymbolFileDWARF::ID;115 116namespace {117 118#define LLDB_PROPERTIES_symbolfiledwarf119#include "SymbolFileDWARFProperties.inc"120 121enum {122#define LLDB_PROPERTIES_symbolfiledwarf123#include "SymbolFileDWARFPropertiesEnum.inc"124};125 126class PluginProperties : public Properties {127public:128 static llvm::StringRef GetSettingName() {129 return SymbolFileDWARF::GetPluginNameStatic();130 }131 132 PluginProperties() {133 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());134 m_collection_sp->Initialize(g_symbolfiledwarf_properties);135 }136 137 bool IgnoreFileIndexes() const {138 return GetPropertyAtIndexAs<bool>(ePropertyIgnoreIndexes, false);139 }140};141 142} // namespace143 144bool IsStructOrClassTag(llvm::dwarf::Tag Tag) {145 return Tag == llvm::dwarf::Tag::DW_TAG_class_type ||146 Tag == llvm::dwarf::Tag::DW_TAG_structure_type;147}148 149static PluginProperties &GetGlobalPluginProperties() {150 static PluginProperties g_settings;151 return g_settings;152}153 154static const llvm::DWARFDebugLine::LineTable *155ParseLLVMLineTable(DWARFContext &context, llvm::DWARFDebugLine &line,156 dw_offset_t line_offset, dw_offset_t unit_offset) {157 Log *log = GetLog(DWARFLog::DebugInfo);158 159 llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVMDWARF();160 llvm::DWARFContext &ctx = context.GetAsLLVM();161 llvm::Expected<const llvm::DWARFDebugLine::LineTable *> line_table =162 line.getOrParseLineTable(163 data, line_offset, ctx, nullptr, [&](llvm::Error e) {164 LLDB_LOG_ERROR(165 log, std::move(e),166 "SymbolFileDWARF::ParseLineTable failed to parse: {0}");167 });168 169 if (!line_table) {170 LLDB_LOG_ERROR(log, line_table.takeError(),171 "SymbolFileDWARF::ParseLineTable failed to parse: {0}");172 return nullptr;173 }174 return *line_table;175}176 177static bool ParseLLVMLineTablePrologue(DWARFContext &context,178 llvm::DWARFDebugLine::Prologue &prologue,179 dw_offset_t line_offset,180 dw_offset_t unit_offset) {181 Log *log = GetLog(DWARFLog::DebugInfo);182 bool success = true;183 llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVMDWARF();184 llvm::DWARFContext &ctx = context.GetAsLLVM();185 uint64_t offset = line_offset;186 llvm::Error error = prologue.parse(187 data, &offset,188 [&](llvm::Error e) {189 success = false;190 LLDB_LOG_ERROR(log, std::move(e),191 "SymbolFileDWARF::ParseSupportFiles failed to parse "192 "line table prologue: {0}");193 },194 ctx, nullptr);195 if (error) {196 LLDB_LOG_ERROR(log, std::move(error),197 "SymbolFileDWARF::ParseSupportFiles failed to parse line "198 "table prologue: {0}");199 return false;200 }201 return success;202}203 204static std::optional<std::string>205GetFileByIndex(const llvm::DWARFDebugLine::Prologue &prologue, size_t idx,206 llvm::StringRef compile_dir, FileSpec::Style style) {207 // Try to get an absolute path first.208 std::string abs_path;209 auto absolute = llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath;210 if (prologue.getFileNameByIndex(idx, compile_dir, absolute, abs_path, style))211 return std::move(abs_path);212 213 // Otherwise ask for a relative path.214 std::string rel_path;215 auto relative = llvm::DILineInfoSpecifier::FileLineInfoKind::RawValue;216 if (!prologue.getFileNameByIndex(idx, compile_dir, relative, rel_path, style))217 return {};218 return std::move(rel_path);219}220 221static void ParseSupportFilesFromPrologue(222 SupportFileList &support_files, const lldb::ModuleSP &module,223 const llvm::DWARFDebugLine::Prologue &prologue, FileSpec::Style style,224 llvm::StringRef compile_dir = {}) {225 // Handle the case where there are no files first to avoid having to special226 // case this later.227 if (prologue.FileNames.empty())228 return;229 230 // Before DWARF v5, the line table indexes were one based.231 const bool is_one_based = prologue.getVersion() < 5;232 const size_t file_names = prologue.FileNames.size();233 const size_t first_file_idx = is_one_based ? 1 : 0;234 const size_t last_file_idx = is_one_based ? file_names : file_names - 1;235 236 // Add a dummy entry to ensure the support file list indices match those we237 // get from the debug info and line tables.238 if (is_one_based)239 support_files.Append(FileSpec());240 241 for (size_t idx = first_file_idx; idx <= last_file_idx; ++idx) {242 std::string remapped_file;243 if (auto file_path = GetFileByIndex(prologue, idx, compile_dir, style)) {244 auto entry = prologue.getFileNameEntry(idx);245 auto source = entry.Source.getAsCString();246 if (!source)247 consumeError(source.takeError());248 else {249 llvm::StringRef source_ref(*source);250 if (!source_ref.empty()) {251 /// Wrap a path for an in-DWARF source file. Lazily write it252 /// to disk when Materialize() is called.253 struct LazyDWARFSourceFile : public SupportFile {254 LazyDWARFSourceFile(const FileSpec &fs, llvm::StringRef source,255 FileSpec::Style style)256 : SupportFile(fs), source(source), style(style) {}257 FileSpec tmp_file;258 /// The file contents buffer.259 llvm::StringRef source;260 /// Deletes the temporary file at the end.261 std::unique_ptr<llvm::FileRemover> remover;262 FileSpec::Style style;263 264 /// Write the file contents to a temporary file.265 const FileSpec &Materialize() override {266 if (tmp_file)267 return tmp_file;268 llvm::SmallString<0> name;269 int fd;270 auto orig_name = m_file_spec.GetFilename().GetStringRef();271 auto ec = llvm::sys::fs::createTemporaryFile(272 "", llvm::sys::path::filename(orig_name, style), fd, name);273 if (ec || fd <= 0) {274 LLDB_LOG(GetLog(DWARFLog::DebugInfo),275 "Could not create temporary file");276 return tmp_file;277 }278 remover = std::make_unique<llvm::FileRemover>(name);279 NativeFile file(fd, File::eOpenOptionWriteOnly, true);280 size_t num_bytes = source.size();281 file.Write(source.data(), num_bytes);282 tmp_file.SetPath(name);283 return tmp_file;284 }285 };286 support_files.Append(std::make_unique<LazyDWARFSourceFile>(287 FileSpec(*file_path), *source, style));288 continue;289 }290 }291 if (auto remapped = module->RemapSourceFile(llvm::StringRef(*file_path)))292 remapped_file = *remapped;293 else294 remapped_file = std::move(*file_path);295 }296 297 Checksum checksum;298 if (prologue.ContentTypes.HasMD5) {299 const llvm::DWARFDebugLine::FileNameEntry &file_name_entry =300 prologue.getFileNameEntry(idx);301 checksum = file_name_entry.Checksum;302 }303 304 // Unconditionally add an entry, so the indices match up.305 support_files.EmplaceBack(FileSpec(remapped_file, style), checksum);306 }307}308 309void SymbolFileDWARF::Initialize() {310 LogChannelDWARF::Initialize();311 PluginManager::RegisterPlugin(GetPluginNameStatic(),312 GetPluginDescriptionStatic(), CreateInstance,313 DebuggerInitialize);314 SymbolFileDWARFDebugMap::Initialize();315}316 317void SymbolFileDWARF::DebuggerInitialize(Debugger &debugger) {318 if (!PluginManager::GetSettingForSymbolFilePlugin(319 debugger, PluginProperties::GetSettingName())) {320 const bool is_global_setting = true;321 PluginManager::CreateSettingForSymbolFilePlugin(322 debugger, GetGlobalPluginProperties().GetValueProperties(),323 "Properties for the dwarf symbol-file plug-in.", is_global_setting);324 }325}326 327void SymbolFileDWARF::Terminate() {328 SymbolFileDWARFDebugMap::Terminate();329 PluginManager::UnregisterPlugin(CreateInstance);330 LogChannelDWARF::Terminate();331}332 333llvm::StringRef SymbolFileDWARF::GetPluginDescriptionStatic() {334 return "DWARF and DWARF3 debug symbol file reader.";335}336 337SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFileSP objfile_sp) {338 if (objfile_sp->GetArchitecture().GetTriple().isWasm())339 return new SymbolFileWasm(std::move(objfile_sp),340 /*dwo_section_list*/ nullptr);341 return new SymbolFileDWARF(std::move(objfile_sp),342 /*dwo_section_list*/ nullptr);343}344 345TypeList &SymbolFileDWARF::GetTypeList() {346 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());347 if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())348 return debug_map_symfile->GetTypeList();349 return SymbolFileCommon::GetTypeList();350}351void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,352 dw_offset_t max_die_offset, uint32_t type_mask,353 TypeSet &type_set) {354 if (die) {355 const dw_offset_t die_offset = die.GetOffset();356 357 if (die_offset >= max_die_offset)358 return;359 360 if (die_offset >= min_die_offset) {361 const dw_tag_t tag = die.Tag();362 363 bool add_type = false;364 365 switch (tag) {366 case DW_TAG_array_type:367 add_type = (type_mask & eTypeClassArray) != 0;368 break;369 case DW_TAG_unspecified_type:370 case DW_TAG_base_type:371 add_type = (type_mask & eTypeClassBuiltin) != 0;372 break;373 case DW_TAG_class_type:374 add_type = (type_mask & eTypeClassClass) != 0;375 break;376 case DW_TAG_structure_type:377 add_type = (type_mask & eTypeClassStruct) != 0;378 break;379 case DW_TAG_union_type:380 add_type = (type_mask & eTypeClassUnion) != 0;381 break;382 case DW_TAG_enumeration_type:383 add_type = (type_mask & eTypeClassEnumeration) != 0;384 break;385 case DW_TAG_subroutine_type:386 case DW_TAG_subprogram:387 case DW_TAG_inlined_subroutine:388 add_type = (type_mask & eTypeClassFunction) != 0;389 break;390 case DW_TAG_pointer_type:391 add_type = (type_mask & eTypeClassPointer) != 0;392 break;393 case DW_TAG_rvalue_reference_type:394 case DW_TAG_reference_type:395 add_type = (type_mask & eTypeClassReference) != 0;396 break;397 case DW_TAG_typedef:398 add_type = (type_mask & eTypeClassTypedef) != 0;399 break;400 case DW_TAG_ptr_to_member_type:401 add_type = (type_mask & eTypeClassMemberPointer) != 0;402 break;403 default:404 break;405 }406 407 if (add_type) {408 const bool assert_not_being_parsed = true;409 Type *type = ResolveTypeUID(die, assert_not_being_parsed);410 if (type)411 type_set.insert(type);412 }413 }414 415 for (DWARFDIE child_die : die.children()) {416 GetTypes(child_die, min_die_offset, max_die_offset, type_mask, type_set);417 }418 }419}420 421void SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,422 TypeClass type_mask, TypeList &type_list)423 424{425 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());426 TypeSet type_set;427 428 CompileUnit *comp_unit = nullptr;429 if (sc_scope)430 comp_unit = sc_scope->CalculateSymbolContextCompileUnit();431 432 const auto &get = [&](DWARFUnit *unit) {433 if (!unit)434 return;435 unit = &unit->GetNonSkeletonUnit();436 GetTypes(unit->DIE(), unit->GetOffset(), unit->GetNextUnitOffset(),437 type_mask, type_set);438 };439 if (comp_unit) {440 get(GetDWARFCompileUnit(comp_unit));441 } else {442 DWARFDebugInfo &info = DebugInfo();443 const size_t num_cus = info.GetNumUnits();444 for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx)445 get(info.GetUnitAtIndex(cu_idx));446 }447 448 std::set<CompilerType> compiler_type_set;449 for (Type *type : type_set) {450 CompilerType compiler_type = type->GetForwardCompilerType();451 if (compiler_type_set.find(compiler_type) == compiler_type_set.end()) {452 compiler_type_set.insert(compiler_type);453 type_list.Insert(type->shared_from_this());454 }455 }456}457 458// Gets the first parent that is a lexical block, function or inlined459// subroutine, or compile unit.460DWARFDIE461SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) {462 DWARFDIE die;463 for (die = child_die.GetParent(); die; die = die.GetParent()) {464 dw_tag_t tag = die.Tag();465 466 switch (tag) {467 case DW_TAG_compile_unit:468 case DW_TAG_partial_unit:469 case DW_TAG_subprogram:470 case DW_TAG_inlined_subroutine:471 case DW_TAG_lexical_block:472 return die;473 default:474 break;475 }476 }477 return DWARFDIE();478}479 480SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp,481 SectionList *dwo_section_list)482 : SymbolFileCommon(std::move(objfile_sp)), m_debug_map_module_wp(),483 m_debug_map_symfile(nullptr),484 m_context(m_objfile_sp->GetModule()->GetSectionList(), dwo_section_list),485 m_fetched_external_modules(false) {}486 487SymbolFileDWARF::~SymbolFileDWARF() = default;488 489static ConstString GetDWARFMachOSegmentName() {490 static ConstString g_dwarf_section_name("__DWARF");491 return g_dwarf_section_name;492}493 494llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> &495SymbolFileDWARF::GetDIEToType() {496 if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())497 return debug_map_symfile->GetDIEToType();498 return m_die_to_type;499}500 501llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> &502SymbolFileDWARF::GetForwardDeclCompilerTypeToDIE() {503 if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())504 return debug_map_symfile->GetForwardDeclCompilerTypeToDIE();505 return m_forward_decl_compiler_type_to_die;506}507 508UniqueDWARFASTTypeMap &SymbolFileDWARF::GetUniqueDWARFASTTypeMap() {509 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();510 if (debug_map_symfile)511 return debug_map_symfile->GetUniqueDWARFASTTypeMap();512 else513 return m_unique_ast_type_map;514}515 516llvm::Expected<lldb::TypeSystemSP>517SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) {518 if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())519 return debug_map_symfile->GetTypeSystemForLanguage(language);520 521 auto type_system_or_err =522 m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);523 if (type_system_or_err)524 if (auto ts = *type_system_or_err)525 ts->SetSymbolFile(this);526 return type_system_or_err;527}528 529void SymbolFileDWARF::InitializeObject() {530 Log *log = GetLog(DWARFLog::DebugInfo);531 532 InitializeFirstCodeAddress();533 534 if (!GetGlobalPluginProperties().IgnoreFileIndexes()) {535 StreamString module_desc;536 GetObjectFile()->GetModule()->GetDescription(module_desc.AsRawOstream(),537 lldb::eDescriptionLevelBrief);538 DWARFDataExtractor apple_names, apple_namespaces, apple_types, apple_objc;539 LoadSectionData(eSectionTypeDWARFAppleNames, apple_names);540 LoadSectionData(eSectionTypeDWARFAppleNamespaces, apple_namespaces);541 LoadSectionData(eSectionTypeDWARFAppleTypes, apple_types);542 LoadSectionData(eSectionTypeDWARFAppleObjC, apple_objc);543 544 if (apple_names.GetByteSize() > 0 || apple_namespaces.GetByteSize() > 0 ||545 apple_types.GetByteSize() > 0 || apple_objc.GetByteSize() > 0) {546 m_index = AppleDWARFIndex::Create(547 *GetObjectFile()->GetModule(), apple_names, apple_namespaces,548 apple_types, apple_objc, m_context.getOrLoadStrData());549 550 if (m_index)551 return;552 }553 554 DWARFDataExtractor debug_names;555 LoadSectionData(eSectionTypeDWARFDebugNames, debug_names);556 if (debug_names.GetByteSize() > 0) {557 Progress progress("Loading DWARF5 index", module_desc.GetData());558 llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or =559 DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(),560 debug_names,561 m_context.getOrLoadStrData(), *this);562 if (index_or) {563 m_index = std::move(*index_or);564 return;565 }566 LLDB_LOG_ERROR(log, index_or.takeError(),567 "Unable to read .debug_names data: {0}");568 }569 }570 571 m_index =572 std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(), *this);573}574 575void SymbolFileDWARF::InitializeFirstCodeAddress() {576 InitializeFirstCodeAddressRecursive(577 *m_objfile_sp->GetModule()->GetSectionList());578 if (m_first_code_address == LLDB_INVALID_ADDRESS)579 m_first_code_address = 0;580}581 582void SymbolFileDWARF::InitializeFirstCodeAddressRecursive(583 const lldb_private::SectionList §ion_list) {584 for (SectionSP section_sp : section_list) {585 if (section_sp->GetChildren().GetSize() > 0) {586 InitializeFirstCodeAddressRecursive(section_sp->GetChildren());587 } else if (section_sp->GetType() == eSectionTypeCode) {588 m_first_code_address =589 std::min(m_first_code_address, section_sp->GetFileAddress());590 }591 }592}593 594bool SymbolFileDWARF::SupportedVersion(uint16_t version) {595 return version >= 2 && version <= 5;596}597 598static std::set<dw_form_t>599GetUnsupportedForms(llvm::DWARFDebugAbbrev *debug_abbrev) {600 if (!debug_abbrev)601 return {};602 603 std::set<dw_form_t> unsupported_forms;604 for (const auto &[_, decl_set] : *debug_abbrev)605 for (const auto &decl : decl_set)606 for (const auto &attr : decl.attributes())607 if (!DWARFFormValue::FormIsSupported(attr.Form))608 unsupported_forms.insert(attr.Form);609 610 return unsupported_forms;611}612 613uint32_t SymbolFileDWARF::CalculateAbilities() {614 uint32_t abilities = 0;615 if (m_objfile_sp != nullptr) {616 const Section *section = nullptr;617 const SectionList *section_list = m_objfile_sp->GetSectionList();618 if (section_list == nullptr)619 return 0;620 621 uint64_t debug_abbrev_file_size = 0;622 uint64_t debug_info_file_size = 0;623 uint64_t debug_line_file_size = 0;624 625 section = section_list->FindSectionByName(GetDWARFMachOSegmentName()).get();626 627 if (section)628 section_list = §ion->GetChildren();629 630 section =631 section_list->FindSectionByType(eSectionTypeDWARFDebugInfo, true).get();632 if (section != nullptr) {633 debug_info_file_size = section->GetFileSize();634 635 section =636 section_list->FindSectionByType(eSectionTypeDWARFDebugAbbrev, true)637 .get();638 if (section)639 debug_abbrev_file_size = section->GetFileSize();640 641 llvm::DWARFDebugAbbrev *abbrev = DebugAbbrev();642 std::set<dw_form_t> unsupported_forms = GetUnsupportedForms(abbrev);643 if (!unsupported_forms.empty()) {644 StreamString error;645 error.Printf("unsupported DW_FORM value%s:",646 unsupported_forms.size() > 1 ? "s" : "");647 for (auto form : unsupported_forms)648 error.Printf(" %#x", form);649 m_objfile_sp->GetModule()->ReportWarning("{0}", error.GetString());650 return 0;651 }652 653 section =654 section_list->FindSectionByType(eSectionTypeDWARFDebugLine, true)655 .get();656 if (section)657 debug_line_file_size = section->GetFileSize();658 } else {659 llvm::StringRef symfile_dir =660 m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef();661 if (symfile_dir.contains_insensitive(".dsym")) {662 if (m_objfile_sp->GetType() == ObjectFile::eTypeDebugInfo) {663 // We have a dSYM file that didn't have a any debug info. If the664 // string table has a size of 1, then it was made from an665 // executable with no debug info, or from an executable that was666 // stripped.667 section =668 section_list->FindSectionByType(eSectionTypeDWARFDebugStr, true)669 .get();670 if (section && section->GetFileSize() == 1) {671 m_objfile_sp->GetModule()->ReportWarning(672 "empty dSYM file detected, dSYM was created with an "673 "executable with no debug info.");674 }675 }676 }677 }678 679 constexpr uint64_t MaxDebugInfoSize = (1ull) << DW_DIE_OFFSET_MAX_BITSIZE;680 if (debug_info_file_size >= MaxDebugInfoSize) {681 m_objfile_sp->GetModule()->ReportWarning(682 "SymbolFileDWARF can't load this DWARF. It's larger then {0:x+16}",683 MaxDebugInfoSize);684 return 0;685 }686 687 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)688 abilities |= CompileUnits | Functions | Blocks | GlobalVariables |689 LocalVariables | VariableTypes;690 691 if (debug_line_file_size > 0)692 abilities |= LineTables;693 }694 return abilities;695}696 697void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type,698 DWARFDataExtractor &data) {699 ModuleSP module_sp(m_objfile_sp->GetModule());700 const SectionList *section_list = module_sp->GetSectionList();701 if (!section_list)702 return;703 704 SectionSP section_sp(section_list->FindSectionByType(sect_type, true));705 if (!section_sp)706 return;707 708 data.Clear();709 m_objfile_sp->ReadSectionData(section_sp.get(), data);710}711 712llvm::DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {713 if (m_abbr)714 return m_abbr.get();715 716 const DWARFDataExtractor &debug_abbrev_data = m_context.getOrLoadAbbrevData();717 if (debug_abbrev_data.GetByteSize() == 0)718 return nullptr;719 720 ElapsedTime elapsed(m_parse_time);721 auto abbr =722 std::make_unique<llvm::DWARFDebugAbbrev>(debug_abbrev_data.GetAsLLVM());723 llvm::Error error = abbr->parse();724 if (error) {725 Log *log = GetLog(DWARFLog::DebugInfo);726 LLDB_LOG_ERROR(log, std::move(error),727 "Unable to read .debug_abbrev section: {0}");728 return nullptr;729 }730 731 m_abbr = std::move(abbr);732 return m_abbr.get();733}734 735DWARFDebugInfo &SymbolFileDWARF::DebugInfo() {736 llvm::call_once(m_info_once_flag, [&] {737 LLDB_SCOPED_TIMER();738 739 m_info = std::make_unique<DWARFDebugInfo>(*this, m_context);740 });741 return *m_info;742}743 744DWARFCompileUnit *SymbolFileDWARF::GetDWARFCompileUnit(CompileUnit *comp_unit) {745 if (!comp_unit)746 return nullptr;747 748 // The compile unit ID is the index of the DWARF unit.749 DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(comp_unit->GetID());750 if (dwarf_cu && dwarf_cu->GetLLDBCompUnit() == nullptr)751 dwarf_cu->SetLLDBCompUnit(comp_unit);752 753 // It must be DWARFCompileUnit when it created a CompileUnit.754 return llvm::cast_or_null<DWARFCompileUnit>(dwarf_cu);755}756 757/// Make an absolute path out of \p file_spec and remap it using the758/// module's source remapping dictionary.759static void MakeAbsoluteAndRemap(FileSpec &file_spec, DWARFUnit &dwarf_cu,760 const ModuleSP &module_sp) {761 if (!file_spec)762 return;763 // If we have a full path to the compile unit, we don't need to764 // resolve the file. This can be expensive e.g. when the source765 // files are NFS mounted.766 file_spec.MakeAbsolute(dwarf_cu.GetCompilationDirectory());767 768 if (auto remapped_file = module_sp->RemapSourceFile(file_spec.GetPath()))769 file_spec.SetFile(*remapped_file, FileSpec::Style::native);770}771 772/// Return the DW_AT_(GNU_)dwo_name.773static const char *GetDWOName(DWARFCompileUnit &dwarf_cu,774 const DWARFDebugInfoEntry &cu_die) {775 const char *dwo_name =776 cu_die.GetAttributeValueAsString(&dwarf_cu, DW_AT_GNU_dwo_name, nullptr);777 if (!dwo_name)778 dwo_name =779 cu_die.GetAttributeValueAsString(&dwarf_cu, DW_AT_dwo_name, nullptr);780 return dwo_name;781}782 783lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {784 CompUnitSP cu_sp;785 CompileUnit *comp_unit = dwarf_cu.GetLLDBCompUnit();786 if (comp_unit) {787 // We already parsed this compile unit, had out a shared pointer to it788 cu_sp = comp_unit->shared_from_this();789 } else {790 if (GetDebugMapSymfile()) {791 // Let the debug map create the compile unit792 cu_sp = m_debug_map_symfile->GetCompileUnit(this, dwarf_cu);793 dwarf_cu.SetLLDBCompUnit(cu_sp.get());794 } else {795 ModuleSP module_sp(m_objfile_sp->GetModule());796 if (module_sp) {797 auto initialize_cu = [&](SupportFileNSP support_file_nsp,798 LanguageType cu_language,799 SupportFileList &&support_files = {}) {800 BuildCuTranslationTable();801 cu_sp = std::make_shared<CompileUnit>(802 module_sp, &dwarf_cu, support_file_nsp,803 *GetDWARFUnitIndex(dwarf_cu.GetID()), cu_language,804 eLazyBoolCalculate, std::move(support_files));805 806 dwarf_cu.SetLLDBCompUnit(cu_sp.get());807 808 SetCompileUnitAtIndex(dwarf_cu.GetID(), cu_sp);809 };810 811 auto lazy_initialize_cu = [&]() {812 // If the version is < 5, we can't do lazy initialization.813 if (dwarf_cu.GetVersion() < 5)814 return false;815 816 // If there is no DWO, there is no reason to initialize817 // lazily; we will do eager initialization in that case.818 if (GetDebugMapSymfile())819 return false;820 const DWARFBaseDIE cu_die = dwarf_cu.GetUnitDIEOnly();821 if (!cu_die)822 return false;823 if (!GetDWOName(dwarf_cu, *cu_die.GetDIE()))824 return false;825 826 // With DWARFv5 we can assume that the first support827 // file is also the name of the compile unit. This828 // allows us to avoid loading the non-skeleton unit,829 // which may be in a separate DWO file.830 SupportFileList support_files;831 if (!ParseSupportFiles(dwarf_cu, module_sp, support_files))832 return false;833 if (support_files.GetSize() == 0)834 return false;835 initialize_cu(support_files.GetSupportFileAtIndex(0),836 eLanguageTypeUnknown, std::move(support_files));837 return true;838 };839 840 if (!lazy_initialize_cu()) {841 // Eagerly initialize compile unit842 const DWARFBaseDIE cu_die =843 dwarf_cu.GetNonSkeletonUnit().GetUnitDIEOnly();844 if (cu_die) {845 LanguageType cu_language = SymbolFileDWARF::LanguageTypeFromDWARF(846 dwarf_cu.GetDWARFLanguageType());847 848 FileSpec cu_file_spec(cu_die.GetName(), dwarf_cu.GetPathStyle());849 850 // Path needs to be remapped in this case. In the support files851 // case ParseSupportFiles takes care of the remapping.852 MakeAbsoluteAndRemap(cu_file_spec, dwarf_cu, module_sp);853 854 initialize_cu(std::make_shared<SupportFile>(cu_file_spec),855 cu_language);856 }857 }858 }859 }860 }861 return cu_sp;862}863 864void SymbolFileDWARF::BuildCuTranslationTable() {865 if (!m_lldb_cu_to_dwarf_unit.empty())866 return;867 868 DWARFDebugInfo &info = DebugInfo();869 if (!info.ContainsTypeUnits()) {870 // We can use a 1-to-1 mapping. No need to build a translation table.871 return;872 }873 for (uint32_t i = 0, num = info.GetNumUnits(); i < num; ++i) {874 if (auto *cu = llvm::dyn_cast<DWARFCompileUnit>(info.GetUnitAtIndex(i))) {875 cu->SetID(m_lldb_cu_to_dwarf_unit.size());876 m_lldb_cu_to_dwarf_unit.push_back(i);877 }878 }879}880 881std::optional<uint32_t> SymbolFileDWARF::GetDWARFUnitIndex(uint32_t cu_idx) {882 BuildCuTranslationTable();883 if (m_lldb_cu_to_dwarf_unit.empty())884 return cu_idx;885 if (cu_idx >= m_lldb_cu_to_dwarf_unit.size())886 return std::nullopt;887 return m_lldb_cu_to_dwarf_unit[cu_idx];888}889 890uint32_t SymbolFileDWARF::CalculateNumCompileUnits() {891 BuildCuTranslationTable();892 return m_lldb_cu_to_dwarf_unit.empty() ? DebugInfo().GetNumUnits()893 : m_lldb_cu_to_dwarf_unit.size();894}895 896CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {897 ASSERT_MODULE_LOCK(this);898 if (std::optional<uint32_t> dwarf_idx = GetDWARFUnitIndex(cu_idx)) {899 if (auto *dwarf_cu = llvm::cast_or_null<DWARFCompileUnit>(900 DebugInfo().GetUnitAtIndex(*dwarf_idx)))901 return ParseCompileUnit(*dwarf_cu);902 }903 return {};904}905 906Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,907 const DWARFDIE &die) {908 ASSERT_MODULE_LOCK(this);909 Log *log = GetLog(LLDBLog::Symbols);910 if (!die.IsValid())911 return nullptr;912 913 auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));914 if (auto err = type_system_or_err.takeError()) {915 LLDB_LOG_ERROR(log, std::move(err), "Unable to parse function: {0}");916 return nullptr;917 }918 auto ts = *type_system_or_err;919 if (!ts)920 return nullptr;921 DWARFASTParser *dwarf_ast = ts->GetDWARFParser();922 if (!dwarf_ast)923 return nullptr;924 925 AddressRanges ranges;926 ModuleSP module_sp(die.GetModule());927 if (llvm::Expected<llvm::DWARFAddressRangesVector> die_ranges =928 die.GetDIE()->GetAttributeAddressRanges(die.GetCU(),929 /*check_hi_lo_pc=*/true)) {930 for (const auto &range : *die_ranges) {931 if (range.valid() && range.LowPC < m_first_code_address)932 continue;933 if (Address base_addr(range.LowPC, module_sp->GetSectionList());934 base_addr.IsValid() && FixupAddress(base_addr))935 ranges.emplace_back(std::move(base_addr), range.HighPC - range.LowPC);936 }937 } else {938 LLDB_LOG_ERROR(log, die_ranges.takeError(), "DIE({1:x}): {0}", die.GetID());939 }940 if (ranges.empty())941 return nullptr;942 943 return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die, std::move(ranges));944}945 946ConstString947SymbolFileDWARF::ConstructFunctionDemangledName(const DWARFDIE &die) {948 ASSERT_MODULE_LOCK(this);949 if (!die.IsValid()) {950 return ConstString();951 }952 953 auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));954 if (auto err = type_system_or_err.takeError()) {955 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),956 "Unable to construct demangled name for function: {0}");957 return ConstString();958 }959 960 auto ts = *type_system_or_err;961 if (!ts) {962 LLDB_LOG(GetLog(LLDBLog::Symbols), "Type system no longer live");963 return ConstString();964 }965 DWARFASTParser *dwarf_ast = ts->GetDWARFParser();966 if (!dwarf_ast)967 return ConstString();968 969 return dwarf_ast->ConstructDemangledNameFromDWARF(die);970}971 972lldb::addr_t SymbolFileDWARF::FixupAddress(lldb::addr_t file_addr) {973 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();974 if (debug_map_symfile)975 return debug_map_symfile->LinkOSOFileAddress(this, file_addr);976 return file_addr;977}978 979bool SymbolFileDWARF::FixupAddress(Address &addr) {980 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();981 if (debug_map_symfile) {982 return debug_map_symfile->LinkOSOAddress(addr);983 }984 // This is a normal DWARF file, no address fixups need to happen985 return true;986}987lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) {988 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());989 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);990 if (dwarf_cu)991 return GetLanguage(dwarf_cu->GetNonSkeletonUnit());992 else993 return eLanguageTypeUnknown;994}995 996XcodeSDK SymbolFileDWARF::ParseXcodeSDK(CompileUnit &comp_unit) {997 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());998 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);999 if (!dwarf_cu)1000 return {};1001 const DWARFBaseDIE cu_die = dwarf_cu->GetNonSkeletonUnit().GetUnitDIEOnly();1002 if (!cu_die)1003 return {};1004 const char *sdk = cu_die.GetAttributeValueAsString(DW_AT_APPLE_sdk, nullptr);1005 if (!sdk)1006 return {};1007 llvm::StringRef sysroot =1008 cu_die.GetAttributeValueAsString(DW_AT_LLVM_sysroot, "");1009 1010 // RegisterXcodeSDK calls into xcrun which is not aware of CLT, which is1011 // expensive.1012 if (!sysroot.starts_with("/Library/Developer/CommandLineTools/SDKs")) {1013 // Register the sysroot path remapping with the module belonging to1014 // the CU as well as the one belonging to the symbol file. The two1015 // would be different if this is an OSO object and module is the1016 // corresponding debug map, in which case both should be updated.1017 ModuleSP module_sp = comp_unit.GetModule();1018 if (module_sp)1019 module_sp->RegisterXcodeSDK(sdk, sysroot);1020 1021 ModuleSP local_module_sp = m_objfile_sp->GetModule();1022 if (local_module_sp && local_module_sp != module_sp)1023 local_module_sp->RegisterXcodeSDK(sdk, sysroot);1024 }1025 1026 return {sdk, FileSpec(sysroot)};1027}1028 1029size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) {1030 LLDB_SCOPED_TIMER();1031 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1032 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);1033 if (!dwarf_cu)1034 return 0;1035 1036 size_t functions_added = 0;1037 dwarf_cu = &dwarf_cu->GetNonSkeletonUnit();1038 for (DWARFDebugInfoEntry &entry : dwarf_cu->dies()) {1039 if (entry.Tag() != DW_TAG_subprogram)1040 continue;1041 1042 DWARFDIE die(dwarf_cu, &entry);1043 if (comp_unit.FindFunctionByUID(die.GetID()))1044 continue;1045 if (ParseFunction(comp_unit, die))1046 ++functions_added;1047 }1048 // FixupTypes();1049 return functions_added;1050}1051 1052bool SymbolFileDWARF::ForEachExternalModule(1053 CompileUnit &comp_unit,1054 llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files,1055 llvm::function_ref<bool(Module &)> lambda) {1056 // Only visit each symbol file once.1057 if (!visited_symbol_files.insert(this).second)1058 return false;1059 1060 UpdateExternalModuleListIfNeeded();1061 for (auto &p : m_external_type_modules) {1062 ModuleSP module = p.second;1063 if (!module)1064 continue;1065 1066 // Invoke the action and potentially early-exit.1067 if (lambda(*module))1068 return true;1069 1070 for (std::size_t i = 0; i < module->GetNumCompileUnits(); ++i) {1071 auto cu = module->GetCompileUnitAtIndex(i);1072 bool early_exit = cu->ForEachExternalModule(visited_symbol_files, lambda);1073 if (early_exit)1074 return true;1075 }1076 }1077 return false;1078}1079 1080bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit,1081 SupportFileList &support_files) {1082 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1083 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);1084 if (!dwarf_cu)1085 return false;1086 1087 if (!ParseSupportFiles(*dwarf_cu, comp_unit.GetModule(), support_files))1088 return false;1089 1090 return true;1091}1092 1093bool SymbolFileDWARF::ParseSupportFiles(DWARFUnit &dwarf_cu,1094 const ModuleSP &module,1095 SupportFileList &support_files) {1096 1097 dw_offset_t offset = dwarf_cu.GetLineTableOffset();1098 if (offset == DW_INVALID_OFFSET)1099 return false;1100 1101 ElapsedTime elapsed(m_parse_time);1102 llvm::DWARFDebugLine::Prologue prologue;1103 if (!ParseLLVMLineTablePrologue(m_context, prologue, offset,1104 dwarf_cu.GetOffset()))1105 return false;1106 1107 std::string comp_dir = dwarf_cu.GetCompilationDirectory().GetPath();1108 ParseSupportFilesFromPrologue(support_files, module, prologue,1109 dwarf_cu.GetPathStyle(), comp_dir);1110 return true;1111}1112 1113FileSpec SymbolFileDWARF::GetFile(DWARFUnit &unit, size_t file_idx) {1114 if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(&unit)) {1115 if (CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(*dwarf_cu))1116 return lldb_cu->GetSupportFiles().GetFileSpecAtIndex(file_idx);1117 return FileSpec();1118 }1119 1120 auto &tu = llvm::cast<DWARFTypeUnit>(unit);1121 if (const SupportFileList *support_files = GetTypeUnitSupportFiles(tu))1122 return support_files->GetFileSpecAtIndex(file_idx);1123 return {};1124}1125 1126const SupportFileList *1127SymbolFileDWARF::GetTypeUnitSupportFiles(DWARFTypeUnit &tu) {1128 static SupportFileList empty_list;1129 1130 dw_offset_t offset = tu.GetLineTableOffset();1131 if (offset == DW_INVALID_OFFSET ||1132 offset == llvm::DenseMapInfo<dw_offset_t>::getEmptyKey() ||1133 offset == llvm::DenseMapInfo<dw_offset_t>::getTombstoneKey())1134 return nullptr;1135 1136 // Many type units can share a line table, so parse the support file list1137 // once, and cache it based on the offset field.1138 auto iter_bool = m_type_unit_support_files.try_emplace(offset);1139 std::unique_ptr<SupportFileList> &list = iter_bool.first->second;1140 if (iter_bool.second) {1141 list = std::make_unique<SupportFileList>();1142 uint64_t line_table_offset = offset;1143 llvm::DWARFDataExtractor data =1144 m_context.getOrLoadLineData().GetAsLLVMDWARF();1145 llvm::DWARFContext &ctx = m_context.GetAsLLVM();1146 llvm::DWARFDebugLine::Prologue prologue;1147 auto report = [](llvm::Error error) {1148 Log *log = GetLog(DWARFLog::DebugInfo);1149 LLDB_LOG_ERROR(log, std::move(error),1150 "SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse "1151 "the line table prologue: {0}");1152 };1153 ElapsedTime elapsed(m_parse_time);1154 llvm::Error error = prologue.parse(data, &line_table_offset, report, ctx);1155 if (error)1156 report(std::move(error));1157 else1158 ParseSupportFilesFromPrologue(*list, GetObjectFile()->GetModule(),1159 prologue, tu.GetPathStyle());1160 }1161 return list.get();1162}1163 1164bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) {1165 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1166 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);1167 if (dwarf_cu)1168 return dwarf_cu->GetNonSkeletonUnit().GetIsOptimized();1169 return false;1170}1171 1172bool SymbolFileDWARF::ParseImportedModules(1173 const lldb_private::SymbolContext &sc,1174 std::vector<SourceModule> &imported_modules) {1175 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1176 assert(sc.comp_unit);1177 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);1178 if (!dwarf_cu)1179 return false;1180 if (!ClangModulesDeclVendor::LanguageSupportsClangModules(1181 sc.comp_unit->GetLanguage()))1182 return false;1183 UpdateExternalModuleListIfNeeded();1184 1185 const DWARFDIE die = dwarf_cu->DIE();1186 if (!die)1187 return false;1188 1189 for (DWARFDIE child_die : die.children()) {1190 if (child_die.Tag() != DW_TAG_imported_declaration)1191 continue;1192 1193 DWARFDIE module_die = child_die.GetReferencedDIE(DW_AT_import);1194 if (module_die.Tag() != DW_TAG_module)1195 continue;1196 1197 if (const char *name =1198 module_die.GetAttributeValueAsString(DW_AT_name, nullptr)) {1199 SourceModule module;1200 module.path.push_back(ConstString(name));1201 1202 const char *include_path = module_die.GetAttributeValueAsString(1203 DW_AT_LLVM_include_path, nullptr);1204 DWARFDIE parent_die = module_die;1205 while ((parent_die = parent_die.GetParent())) {1206 if (parent_die.Tag() != DW_TAG_module)1207 break;1208 if (const char *name =1209 parent_die.GetAttributeValueAsString(DW_AT_name, nullptr))1210 module.path.push_back(ConstString(name));1211 1212 // Inferred submodule declarations may not have a1213 // DW_AT_LLVM_include_path. Pick the parent (aka umbrella) module's1214 // include path instead.1215 if (!include_path)1216 include_path = parent_die.GetAttributeValueAsString(1217 DW_AT_LLVM_include_path, nullptr);1218 }1219 std::reverse(module.path.begin(), module.path.end());1220 if (include_path) {1221 FileSpec include_spec(include_path, dwarf_cu->GetPathStyle());1222 MakeAbsoluteAndRemap(include_spec, *dwarf_cu,1223 m_objfile_sp->GetModule());1224 module.search_path = ConstString(include_spec.GetPath());1225 }1226 if (const char *sysroot = dwarf_cu->DIE().GetAttributeValueAsString(1227 DW_AT_LLVM_sysroot, nullptr))1228 module.sysroot = ConstString(sysroot);1229 imported_modules.push_back(module);1230 }1231 }1232 return true;1233}1234 1235bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {1236 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1237 if (comp_unit.GetLineTable() != nullptr)1238 return true;1239 1240 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);1241 if (!dwarf_cu)1242 return false;1243 1244 dw_offset_t offset = dwarf_cu->GetLineTableOffset();1245 if (offset == DW_INVALID_OFFSET)1246 return false;1247 1248 ElapsedTime elapsed(m_parse_time);1249 llvm::DWARFDebugLine line;1250 const llvm::DWARFDebugLine::LineTable *line_table =1251 ParseLLVMLineTable(m_context, line, offset, dwarf_cu->GetOffset());1252 1253 if (!line_table)1254 return false;1255 1256 // FIXME: Rather than parsing the whole line table and then copying it over1257 // into LLDB, we should explore using a callback to populate the line table1258 // while we parse to reduce memory usage.1259 std::vector<LineTable::Sequence> sequences;1260 // The Sequences view contains only valid line sequences. Don't iterate over1261 // the Rows directly.1262 for (const llvm::DWARFDebugLine::Sequence &seq : line_table->Sequences) {1263 // Ignore line sequences that do not start after the first code address.1264 // All addresses generated in a sequence are incremental so we only need1265 // to check the first one of the sequence. Check the comment at the1266 // m_first_code_address declaration for more details on this.1267 if (seq.LowPC < m_first_code_address)1268 continue;1269 LineTable::Sequence sequence;1270 for (unsigned idx = seq.FirstRowIndex; idx < seq.LastRowIndex; ++idx) {1271 const llvm::DWARFDebugLine::Row &row = line_table->Rows[idx];1272 LineTable::AppendLineEntryToSequence(1273 sequence, row.Address.Address, row.Line, row.Column, row.File,1274 row.IsStmt, row.BasicBlock, row.PrologueEnd, row.EpilogueBegin,1275 row.EndSequence);1276 }1277 sequences.push_back(std::move(sequence));1278 }1279 1280 std::unique_ptr<LineTable> line_table_up =1281 std::make_unique<LineTable>(&comp_unit, std::move(sequences));1282 1283 if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile()) {1284 // We have an object file that has a line table with addresses that are not1285 // linked. We need to link the line table and convert the addresses that1286 // are relative to the .o file into addresses for the main executable.1287 comp_unit.SetLineTable(1288 debug_map_symfile->LinkOSOLineTable(this, line_table_up.get()));1289 } else {1290 comp_unit.SetLineTable(line_table_up.release());1291 }1292 1293 return true;1294}1295 1296lldb_private::DebugMacrosSP1297SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) {1298 auto iter = m_debug_macros_map.find(*offset);1299 if (iter != m_debug_macros_map.end())1300 return iter->second;1301 1302 ElapsedTime elapsed(m_parse_time);1303 const DWARFDataExtractor &debug_macro_data = m_context.getOrLoadMacroData();1304 if (debug_macro_data.GetByteSize() == 0)1305 return DebugMacrosSP();1306 1307 lldb_private::DebugMacrosSP debug_macros_sp(new lldb_private::DebugMacros());1308 m_debug_macros_map[*offset] = debug_macros_sp;1309 1310 const DWARFDebugMacroHeader &header =1311 DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset);1312 DWARFDebugMacroEntry::ReadMacroEntries(1313 debug_macro_data, m_context.getOrLoadStrData(), header.OffsetIs64Bit(),1314 offset, this, debug_macros_sp);1315 1316 return debug_macros_sp;1317}1318 1319bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) {1320 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1321 1322 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);1323 if (dwarf_cu == nullptr)1324 return false;1325 1326 const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly();1327 if (!dwarf_cu_die)1328 return false;1329 1330 lldb::offset_t sect_offset =1331 dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_macros, DW_INVALID_OFFSET);1332 if (sect_offset == DW_INVALID_OFFSET)1333 sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_macros,1334 DW_INVALID_OFFSET);1335 if (sect_offset == DW_INVALID_OFFSET)1336 return false;1337 1338 comp_unit.SetDebugMacros(ParseDebugMacros(§_offset));1339 1340 return true;1341}1342 1343size_t SymbolFileDWARF::ParseBlocksRecursive(CompileUnit &comp_unit,1344 Block *parent_block, DWARFDIE die,1345 addr_t function_file_addr) {1346 size_t blocks_added = 0;1347 for (; die; die = die.GetSibling()) {1348 dw_tag_t tag = die.Tag();1349 1350 if (tag != DW_TAG_inlined_subroutine && tag != DW_TAG_lexical_block)1351 continue;1352 1353 Block *block = parent_block->CreateChild(die.GetID()).get();1354 llvm::DWARFAddressRangesVector ranges;1355 const char *name = nullptr;1356 const char *mangled_name = nullptr;1357 1358 std::optional<int> decl_file;1359 std::optional<int> decl_line;1360 std::optional<int> decl_column;1361 std::optional<int> call_file;1362 std::optional<int> call_line;1363 std::optional<int> call_column;1364 if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file,1365 decl_line, decl_column, call_file, call_line,1366 call_column, nullptr)) {1367 for (const llvm::DWARFAddressRange &range : ranges) {1368 if (range.valid() && range.LowPC >= m_first_code_address)1369 block->AddRange(Block::Range(range.LowPC - function_file_addr,1370 range.HighPC - range.LowPC));1371 }1372 block->FinalizeRanges();1373 1374 if (tag != DW_TAG_subprogram &&1375 (name != nullptr || mangled_name != nullptr)) {1376 std::unique_ptr<Declaration> decl_up;1377 if (decl_file || decl_line || decl_column)1378 decl_up = std::make_unique<Declaration>(1379 comp_unit.GetSupportFiles().GetFileSpecAtIndex(1380 decl_file.value_or(0)),1381 decl_line.value_or(0), decl_column.value_or(0));1382 1383 std::unique_ptr<Declaration> call_up;1384 if (call_file || call_line || call_column)1385 call_up = std::make_unique<Declaration>(1386 comp_unit.GetSupportFiles().GetFileSpecAtIndex(1387 call_file.value_or(0)),1388 call_line.value_or(0), call_column.value_or(0));1389 1390 block->SetInlinedFunctionInfo(name, mangled_name, decl_up.get(),1391 call_up.get());1392 }1393 1394 ++blocks_added;1395 1396 if (die.HasChildren()) {1397 blocks_added += ParseBlocksRecursive(1398 comp_unit, block, die.GetFirstChild(), function_file_addr);1399 }1400 }1401 }1402 return blocks_added;1403}1404 1405bool SymbolFileDWARF::ClassOrStructIsVirtual(const DWARFDIE &parent_die) {1406 if (parent_die) {1407 for (DWARFDIE die : parent_die.children()) {1408 dw_tag_t tag = die.Tag();1409 bool check_virtuality = false;1410 switch (tag) {1411 case DW_TAG_inheritance:1412 case DW_TAG_subprogram:1413 check_virtuality = true;1414 break;1415 default:1416 break;1417 }1418 if (check_virtuality) {1419 if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0)1420 return true;1421 }1422 }1423 }1424 return false;1425}1426 1427void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) {1428 auto *type_system = decl_ctx.GetTypeSystem();1429 if (type_system != nullptr)1430 type_system->GetDWARFParser()->EnsureAllDIEsInDeclContextHaveBeenParsed(1431 decl_ctx);1432}1433 1434DWARFDIE1435SymbolFileDWARF::GetDIE(lldb::user_id_t uid) { return GetDIE(DIERef(uid)); }1436 1437CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) {1438 // This method can be called without going through the symbol vendor so we1439 // need to lock the module.1440 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1441 // Anytime we have a lldb::user_id_t, we must get the DIE by calling1442 // SymbolFileDWARF::GetDIE(). See comments inside the1443 // SymbolFileDWARF::GetDIE() for details.1444 if (DWARFDIE die = GetDIE(type_uid))1445 return GetDecl(die);1446 return CompilerDecl();1447}1448 1449CompilerDeclContext1450SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) {1451 // This method can be called without going through the symbol vendor so we1452 // need to lock the module.1453 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1454 // Anytime we have a lldb::user_id_t, we must get the DIE by calling1455 // SymbolFileDWARF::GetDIE(). See comments inside the1456 // SymbolFileDWARF::GetDIE() for details.1457 if (DWARFDIE die = GetDIE(type_uid))1458 return GetDeclContext(die);1459 return CompilerDeclContext();1460}1461 1462CompilerDeclContext1463SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {1464 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1465 // Anytime we have a lldb::user_id_t, we must get the DIE by calling1466 // SymbolFileDWARF::GetDIE(). See comments inside the1467 // SymbolFileDWARF::GetDIE() for details.1468 if (DWARFDIE die = GetDIE(type_uid))1469 return GetContainingDeclContext(die);1470 return CompilerDeclContext();1471}1472 1473std::vector<CompilerContext>1474SymbolFileDWARF::GetCompilerContextForUID(lldb::user_id_t type_uid) {1475 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1476 // Anytime we have a lldb::user_id_t, we must get the DIE by calling1477 // SymbolFileDWARF::GetDIE(). See comments inside the1478 // SymbolFileDWARF::GetDIE() for details.1479 if (DWARFDIE die = GetDIE(type_uid))1480 return die.GetDeclContext();1481 return {};1482}1483 1484Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) {1485 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1486 // Anytime we have a lldb::user_id_t, we must get the DIE by calling1487 // SymbolFileDWARF::GetDIE(). See comments inside the1488 // SymbolFileDWARF::GetDIE() for details.1489 if (DWARFDIE type_die = GetDIE(type_uid))1490 return type_die.ResolveType();1491 else1492 return nullptr;1493}1494 1495std::optional<SymbolFile::ArrayInfo> SymbolFileDWARF::GetDynamicArrayInfoForUID(1496 lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {1497 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1498 if (DWARFDIE type_die = GetDIE(type_uid))1499 return DWARFASTParser::ParseChildArrayInfo(type_die, exe_ctx);1500 else1501 return std::nullopt;1502}1503 1504Type *SymbolFileDWARF::ResolveTypeUID(const DIERef &die_ref) {1505 return ResolveType(GetDIE(die_ref), true);1506}1507 1508Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die,1509 bool assert_not_being_parsed) {1510 if (die) {1511 Log *log = GetLog(DWARFLog::DebugInfo);1512 if (log)1513 GetObjectFile()->GetModule()->LogMessage(1514 log,1515 "SymbolFileDWARF::ResolveTypeUID (die = {0:x16}) {1} ({2}) '{3}'",1516 die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.Tag(),1517 die.GetName());1518 1519 // We might be coming in in the middle of a type tree (a class within a1520 // class, an enum within a class), so parse any needed parent DIEs before1521 // we get to this one...1522 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(die);1523 if (decl_ctx_die) {1524 if (log) {1525 switch (decl_ctx_die.Tag()) {1526 case DW_TAG_structure_type:1527 case DW_TAG_union_type:1528 case DW_TAG_class_type: {1529 // Get the type, which could be a forward declaration1530 if (log)1531 GetObjectFile()->GetModule()->LogMessage(1532 log,1533 "SymbolFileDWARF::ResolveTypeUID (die = {0:x16}) {1} ({2}) "1534 "'{3}' resolve parent forward type for {4:x16})",1535 die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.Tag(),1536 die.GetName(), decl_ctx_die.GetOffset());1537 } break;1538 1539 default:1540 break;1541 }1542 }1543 }1544 return ResolveType(die);1545 }1546 return nullptr;1547}1548 1549// This function is used when SymbolFileDWARFDebugMap owns a bunch of1550// SymbolFileDWARF objects to detect if this DWARF file is the one that can1551// resolve a compiler_type.1552bool SymbolFileDWARF::HasForwardDeclForCompilerType(1553 const CompilerType &compiler_type) {1554 CompilerType compiler_type_no_qualifiers =1555 ClangUtil::RemoveFastQualifiers(compiler_type);1556 if (GetForwardDeclCompilerTypeToDIE().count(1557 compiler_type_no_qualifiers.GetOpaqueQualType())) {1558 return true;1559 }1560 auto clang_type_system = compiler_type.GetTypeSystem<TypeSystemClang>();1561 if (!clang_type_system)1562 return false;1563 DWARFASTParserClang *ast_parser =1564 static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());1565 return ast_parser->GetClangASTImporter().CanImport(compiler_type);1566}1567 1568bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {1569 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1570 auto clang_type_system = compiler_type.GetTypeSystem<TypeSystemClang>();1571 if (clang_type_system) {1572 DWARFASTParserClang *ast_parser =1573 static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());1574 if (ast_parser &&1575 ast_parser->GetClangASTImporter().CanImport(compiler_type))1576 return ast_parser->GetClangASTImporter().CompleteType(compiler_type);1577 }1578 1579 // We have a struct/union/class/enum that needs to be fully resolved.1580 CompilerType compiler_type_no_qualifiers =1581 ClangUtil::RemoveFastQualifiers(compiler_type);1582 auto die_it = GetForwardDeclCompilerTypeToDIE().find(1583 compiler_type_no_qualifiers.GetOpaqueQualType());1584 if (die_it == GetForwardDeclCompilerTypeToDIE().end()) {1585 // We have already resolved this type...1586 return true;1587 }1588 1589 DWARFDIE decl_die = GetDIE(die_it->getSecond());1590 // Once we start resolving this type, remove it from the forward1591 // declaration map in case anyone's child members or other types require this1592 // type to get resolved.1593 GetForwardDeclCompilerTypeToDIE().erase(die_it);1594 DWARFDIE def_die = FindDefinitionDIE(decl_die);1595 if (!def_die) {1596 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();1597 if (debug_map_symfile) {1598 // We weren't able to find a full declaration in this DWARF, see1599 // if we have a declaration anywhere else...1600 def_die = debug_map_symfile->FindDefinitionDIE(decl_die);1601 }1602 }1603 if (!def_die) {1604 // If we don't have definition DIE, CompleteTypeFromDWARF will forcefully1605 // complete this type.1606 def_die = decl_die;1607 }1608 1609 DWARFASTParser *dwarf_ast = GetDWARFParser(*def_die.GetCU());1610 if (!dwarf_ast)1611 return false;1612 Type *type = GetDIEToType().lookup(decl_die.GetDIE());1613 assert(type);1614 1615 if (decl_die != def_die) {1616 GetDIEToType()[def_die.GetDIE()] = type;1617 DWARFASTParserClang *ast_parser =1618 static_cast<DWARFASTParserClang *>(dwarf_ast);1619 ast_parser->MapDeclDIEToDefDIE(decl_die, def_die);1620 }1621 1622 Log *log = GetLog(DWARFLog::DebugInfo | DWARFLog::TypeCompletion);1623 if (log)1624 GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(1625 log, "{0:x8}: {1} ({2}) '{3}' resolving forward declaration...",1626 def_die.GetID(), DW_TAG_value_to_name(def_die.Tag()), def_die.Tag(),1627 type->GetName().AsCString());1628 assert(compiler_type);1629 return dwarf_ast->CompleteTypeFromDWARF(def_die, type, compiler_type);1630}1631 1632Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die,1633 bool assert_not_being_parsed,1634 bool resolve_function_context) {1635 if (die) {1636 Type *type = GetTypeForDIE(die, resolve_function_context).get();1637 1638 if (assert_not_being_parsed) {1639 if (type != DIE_IS_BEING_PARSED)1640 return type;1641 1642 GetObjectFile()->GetModule()->ReportError(1643 "Parsing a die that is being parsed die: {0:x16}: {1} ({2}) {3}",1644 die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.Tag(),1645 die.GetName());1646 1647 } else1648 return type;1649 }1650 return nullptr;1651}1652 1653CompileUnit *1654SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu) {1655 1656 if (dwarf_cu.IsDWOUnit()) {1657 DWARFCompileUnit *non_dwo_cu = dwarf_cu.GetSkeletonUnit();1658 assert(non_dwo_cu);1659 return non_dwo_cu->GetSymbolFileDWARF().GetCompUnitForDWARFCompUnit(1660 *non_dwo_cu);1661 }1662 // Check if the symbol vendor already knows about this compile unit?1663 CompileUnit *lldb_cu = dwarf_cu.GetLLDBCompUnit();1664 if (lldb_cu)1665 return lldb_cu;1666 // The symbol vendor doesn't know about this compile unit, we need to parse1667 // and add it to the symbol vendor object.1668 return ParseCompileUnit(dwarf_cu).get();1669}1670 1671void SymbolFileDWARF::GetObjCMethods(1672 ConstString class_name,1673 llvm::function_ref<IterationAction(DWARFDIE die)> callback) {1674 m_index->GetObjCMethods(class_name, callback);1675}1676 1677bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) {1678 sc.Clear(false);1679 1680 if (die && llvm::isa<DWARFCompileUnit>(die.GetCU())) {1681 // Check if the symbol vendor already knows about this compile unit?1682 sc.comp_unit =1683 GetCompUnitForDWARFCompUnit(llvm::cast<DWARFCompileUnit>(*die.GetCU()));1684 1685 sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();1686 if (sc.function == nullptr)1687 sc.function = ParseFunction(*sc.comp_unit, die);1688 1689 if (sc.function) {1690 sc.module_sp = sc.function->CalculateSymbolContextModule();1691 return true;1692 }1693 }1694 1695 return false;1696}1697 1698lldb::ModuleSP SymbolFileDWARF::GetExternalModule(ConstString name) {1699 UpdateExternalModuleListIfNeeded();1700 const auto &pos = m_external_type_modules.find(name);1701 if (pos == m_external_type_modules.end())1702 return lldb::ModuleSP();1703 return pos->second;1704}1705 1706SymbolFileDWARF *SymbolFileDWARF::GetDIERefSymbolFile(const DIERef &die_ref) {1707 // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we1708 // must make sure we use the correct DWARF file when resolving things. On1709 // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple1710 // SymbolFileDWARF classes, one for each .o file. We can often end up with1711 // references to other DWARF objects and we must be ready to receive a1712 // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF1713 // instance.1714 1715 std::optional<uint32_t> file_index = die_ref.file_index();1716 1717 // If the file index matches, then we have the right SymbolFileDWARF already.1718 // This will work for both .dwo file and DWARF in .o files for mac. Also if1719 // both the file indexes are invalid, then we have a match.1720 if (GetFileIndex() == file_index)1721 return this;1722 1723 if (file_index) {1724 // We have a SymbolFileDWARFDebugMap, so let it find the right file1725 if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile())1726 return debug_map->GetSymbolFileByOSOIndex(*file_index);1727 1728 // Handle the .dwp file case correctly1729 if (*file_index == DIERef::k_file_index_mask)1730 return GetDwpSymbolFile().get(); // DWP case1731 1732 // Handle the .dwo file case correctly1733 return DebugInfo().GetUnitAtIndex(*die_ref.file_index())1734 ->GetDwoSymbolFile(); // DWO case1735 }1736 return this;1737}1738 1739DWARFDIE1740SymbolFileDWARF::GetDIE(const DIERef &die_ref) {1741 if (die_ref.die_offset() == DW_INVALID_OFFSET)1742 return DWARFDIE();1743 1744 // This method can be called without going through the symbol vendor so we1745 // need to lock the module.1746 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1747 SymbolFileDWARF *symbol_file = GetDIERefSymbolFile(die_ref);1748 if (symbol_file)1749 return symbol_file->DebugInfo().GetDIE(die_ref.section(),1750 die_ref.die_offset());1751 return DWARFDIE();1752}1753 1754/// Return the DW_AT_(GNU_)dwo_id.1755static std::optional<uint64_t> GetDWOId(DWARFCompileUnit &dwarf_cu,1756 const DWARFDebugInfoEntry &cu_die) {1757 std::optional<uint64_t> dwo_id =1758 cu_die.GetAttributeValueAsOptionalUnsigned(&dwarf_cu, DW_AT_GNU_dwo_id);1759 if (dwo_id)1760 return dwo_id;1761 return cu_die.GetAttributeValueAsOptionalUnsigned(&dwarf_cu, DW_AT_dwo_id);1762}1763 1764std::optional<uint64_t> SymbolFileDWARF::GetDWOId() {1765 if (GetNumCompileUnits() == 1) {1766 if (auto comp_unit = GetCompileUnitAtIndex(0))1767 if (DWARFCompileUnit *cu = GetDWARFCompileUnit(comp_unit.get()))1768 if (DWARFDebugInfoEntry *cu_die = cu->DIE().GetDIE())1769 return ::GetDWOId(*cu, *cu_die);1770 }1771 return {};1772}1773 1774DWARFUnit *SymbolFileDWARF::GetSkeletonUnit(DWARFUnit *dwo_unit) {1775 return DebugInfo().GetSkeletonUnit(dwo_unit);1776}1777 1778std::shared_ptr<SymbolFileDWARFDwo>1779SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(1780 DWARFUnit &unit, const DWARFDebugInfoEntry &cu_die) {1781 // If this is a Darwin-style debug map (non-.dSYM) symbol file,1782 // never attempt to load ELF-style DWO files since the -gmodules1783 // support uses the same DWO mechanism to specify full debug info1784 // files for modules. This is handled in1785 // UpdateExternalModuleListIfNeeded().1786 if (GetDebugMapSymfile())1787 return nullptr;1788 1789 DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(&unit);1790 // Only compile units can be split into two parts and we should only1791 // look for a DWO file if there is a valid DWO ID.1792 if (!dwarf_cu || !dwarf_cu->GetDWOId().has_value())1793 return nullptr;1794 1795 const char *dwo_name = GetDWOName(*dwarf_cu, cu_die);1796 if (!dwo_name) {1797 unit.SetDwoError(Status::FromErrorStringWithFormatv(1798 "missing DWO name in skeleton DIE {0:x16}", cu_die.GetOffset()));1799 return nullptr;1800 }1801 1802 if (std::shared_ptr<SymbolFileDWARFDwo> dwp_sp = GetDwpSymbolFile())1803 return dwp_sp;1804 1805 FileSpec dwo_file(dwo_name);1806 FileSystem::Instance().Resolve(dwo_file);1807 bool found = false;1808 1809 const FileSpecList &debug_file_search_paths =1810 Target::GetDefaultDebugFileSearchPaths();1811 size_t num_search_paths = debug_file_search_paths.GetSize();1812 1813 // It's relative, e.g. "foo.dwo", but we just to happen to be right next to1814 // it. Or it's absolute.1815 found = FileSystem::Instance().Exists(dwo_file);1816 1817 const char *comp_dir =1818 cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_comp_dir, nullptr);1819 if (!found) {1820 // It could be a relative path that also uses DW_AT_COMP_DIR.1821 if (comp_dir) {1822 dwo_file.SetFile(comp_dir, FileSpec::Style::native);1823 if (!dwo_file.IsRelative()) {1824 FileSystem::Instance().Resolve(dwo_file);1825 dwo_file.AppendPathComponent(dwo_name);1826 found = FileSystem::Instance().Exists(dwo_file);1827 } else {1828 FileSpecList dwo_paths;1829 1830 // if DW_AT_comp_dir is relative, it should be relative to the location1831 // of the executable, not to the location from which the debugger was1832 // launched.1833 FileSpec relative_to_binary = dwo_file;1834 relative_to_binary.PrependPathComponent(1835 m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef());1836 FileSystem::Instance().Resolve(relative_to_binary);1837 relative_to_binary.AppendPathComponent(dwo_name);1838 dwo_paths.Append(relative_to_binary);1839 1840 // Or it's relative to one of the user specified debug directories.1841 for (size_t idx = 0; idx < num_search_paths; ++idx) {1842 FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);1843 dirspec.AppendPathComponent(comp_dir);1844 FileSystem::Instance().Resolve(dirspec);1845 if (!FileSystem::Instance().IsDirectory(dirspec))1846 continue;1847 1848 dirspec.AppendPathComponent(dwo_name);1849 dwo_paths.Append(dirspec);1850 }1851 1852 size_t num_possible = dwo_paths.GetSize();1853 for (size_t idx = 0; idx < num_possible && !found; ++idx) {1854 FileSpec dwo_spec = dwo_paths.GetFileSpecAtIndex(idx);1855 if (FileSystem::Instance().Exists(dwo_spec)) {1856 dwo_file = dwo_spec;1857 found = true;1858 }1859 }1860 }1861 } else {1862 Log *log = GetLog(LLDBLog::Symbols);1863 LLDB_LOGF(log,1864 "unable to locate relative .dwo debug file \"%s\" for "1865 "skeleton DIE 0x%016" PRIx64 " without valid DW_AT_comp_dir "1866 "attribute",1867 dwo_name, cu_die.GetOffset());1868 }1869 }1870 1871 if (!found) {1872 // Try adding the DW_AT_dwo_name ( e.g. "c/d/main-main.dwo"), and just the1873 // filename ("main-main.dwo") to binary dir and search paths.1874 FileSpecList dwo_paths;1875 FileSpec dwo_name_spec(dwo_name);1876 llvm::StringRef filename_only = dwo_name_spec.GetFilename();1877 1878 FileSpec binary_directory(1879 m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef());1880 FileSystem::Instance().Resolve(binary_directory);1881 1882 if (dwo_name_spec.IsRelative()) {1883 FileSpec dwo_name_binary_directory(binary_directory);1884 dwo_name_binary_directory.AppendPathComponent(dwo_name);1885 dwo_paths.Append(dwo_name_binary_directory);1886 }1887 1888 FileSpec filename_binary_directory(binary_directory);1889 filename_binary_directory.AppendPathComponent(filename_only);1890 dwo_paths.Append(filename_binary_directory);1891 1892 for (size_t idx = 0; idx < num_search_paths; ++idx) {1893 FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);1894 FileSystem::Instance().Resolve(dirspec);1895 if (!FileSystem::Instance().IsDirectory(dirspec))1896 continue;1897 1898 FileSpec dwo_name_dirspec(dirspec);1899 dwo_name_dirspec.AppendPathComponent(dwo_name);1900 dwo_paths.Append(dwo_name_dirspec);1901 1902 FileSpec filename_dirspec(dirspec);1903 filename_dirspec.AppendPathComponent(filename_only);1904 dwo_paths.Append(filename_dirspec);1905 }1906 1907 size_t num_possible = dwo_paths.GetSize();1908 for (size_t idx = 0; idx < num_possible && !found; ++idx) {1909 FileSpec dwo_spec = dwo_paths.GetFileSpecAtIndex(idx);1910 if (FileSystem::Instance().Exists(dwo_spec)) {1911 dwo_file = dwo_spec;1912 found = true;1913 }1914 }1915 }1916 1917 if (!found) {1918 FileSpec error_dwo_path(dwo_name);1919 FileSystem::Instance().Resolve(error_dwo_path);1920 if (error_dwo_path.IsRelative() && comp_dir != nullptr) {1921 error_dwo_path.PrependPathComponent(comp_dir);1922 FileSystem::Instance().Resolve(error_dwo_path);1923 }1924 unit.SetDwoError(Status::FromErrorStringWithFormatv(1925 "unable to locate .dwo debug file \"{0}\" for skeleton DIE "1926 "{1:x16}",1927 error_dwo_path.GetPath().c_str(), cu_die.GetOffset()));1928 1929 if (m_dwo_warning_issued.test_and_set(std::memory_order_relaxed) == false) {1930 GetObjectFile()->GetModule()->ReportWarning(1931 "unable to locate separate debug file (dwo, dwp). Debugging will be "1932 "degraded.");1933 }1934 return nullptr;1935 }1936 1937 const lldb::offset_t file_offset = 0;1938 DataBufferSP dwo_file_data_sp;1939 lldb::offset_t dwo_file_data_offset = 0;1940 ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(1941 GetObjectFile()->GetModule(), &dwo_file, file_offset,1942 FileSystem::Instance().GetByteSize(dwo_file), dwo_file_data_sp,1943 dwo_file_data_offset);1944 if (dwo_obj_file == nullptr) {1945 unit.SetDwoError(Status::FromErrorStringWithFormatv(1946 "unable to load object file for .dwo debug file \"{0}\" for "1947 "unit DIE {1:x16}",1948 dwo_name, cu_die.GetOffset()));1949 return nullptr;1950 }1951 1952 return std::make_shared<SymbolFileDWARFDwo>(*this, dwo_obj_file,1953 dwarf_cu->GetID());1954}1955 1956void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {1957 if (m_fetched_external_modules)1958 return;1959 m_fetched_external_modules = true;1960 DWARFDebugInfo &debug_info = DebugInfo();1961 1962 // Follow DWO skeleton unit breadcrumbs.1963 const uint32_t num_compile_units = GetNumCompileUnits();1964 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {1965 auto *dwarf_cu =1966 llvm::dyn_cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(cu_idx));1967 if (!dwarf_cu)1968 continue;1969 1970 const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly();1971 if (!die || die.HasChildren() || !die.GetDIE())1972 continue;1973 1974 const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr);1975 if (!name)1976 continue;1977 1978 ConstString const_name(name);1979 ModuleSP &module_sp = m_external_type_modules[const_name];1980 if (module_sp)1981 continue;1982 1983 const char *dwo_path = GetDWOName(*dwarf_cu, *die.GetDIE());1984 if (!dwo_path)1985 continue;1986 1987 ModuleSpec dwo_module_spec;1988 dwo_module_spec.GetFileSpec().SetFile(dwo_path, FileSpec::Style::native);1989 if (dwo_module_spec.GetFileSpec().IsRelative()) {1990 const char *comp_dir =1991 die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr);1992 if (comp_dir) {1993 dwo_module_spec.GetFileSpec().SetFile(comp_dir,1994 FileSpec::Style::native);1995 FileSystem::Instance().Resolve(dwo_module_spec.GetFileSpec());1996 dwo_module_spec.GetFileSpec().AppendPathComponent(dwo_path);1997 }1998 }1999 dwo_module_spec.GetArchitecture() =2000 m_objfile_sp->GetModule()->GetArchitecture();2001 2002 // When LLDB loads "external" modules it looks at the presence of2003 // DW_AT_dwo_name. However, when the already created module2004 // (corresponding to .dwo itself) is being processed, it will see2005 // the presence of DW_AT_dwo_name (which contains the name of dwo2006 // file) and will try to call ModuleList::GetSharedModule2007 // again. In some cases (i.e., for empty files) Clang 4.02008 // generates a *.dwo file which has DW_AT_dwo_name, but no2009 // DW_AT_comp_dir. In this case the method2010 // ModuleList::GetSharedModule will fail and the warning will be2011 // printed. However, as one can notice in this case we don't2012 // actually need to try to load the already loaded module2013 // (corresponding to .dwo) so we simply skip it.2014 if (m_objfile_sp->GetFileSpec().GetFileNameExtension() == ".dwo" &&2015 llvm::StringRef(m_objfile_sp->GetFileSpec().GetPath())2016 .ends_with(dwo_module_spec.GetFileSpec().GetPath())) {2017 continue;2018 }2019 2020 Status error = ModuleList::GetSharedModule(dwo_module_spec, module_sp,2021 nullptr, nullptr);2022 if (!module_sp) {2023 // ReportWarning also rate-limits based on the warning string,2024 // but in a -gmodules build, each object file has a similar DAG2025 // of module dependencies that would all be listed here.2026 GetObjectFile()->GetModule()->ReportWarning(2027 "{0}", error.AsCString("unknown error"));2028 GetObjectFile()->GetModule()->ReportWarning(2029 "Unable to locate module needed for external types.\n"2030 "Debugging will be degraded due to missing types. Rebuilding the "2031 "project will regenerate the needed module files.");2032 continue;2033 }2034 2035 // Verify the DWO hash.2036 // FIXME: Technically "0" is a valid hash.2037 std::optional<uint64_t> dwo_id = ::GetDWOId(*dwarf_cu, *die.GetDIE());2038 if (!dwo_id)2039 continue;2040 2041 auto *dwo_symfile =2042 llvm::dyn_cast_or_null<SymbolFileDWARF>(module_sp->GetSymbolFile());2043 if (!dwo_symfile)2044 continue;2045 std::optional<uint64_t> dwo_dwo_id = dwo_symfile->GetDWOId();2046 if (!dwo_dwo_id)2047 continue;2048 2049 if (dwo_id != dwo_dwo_id) {2050 GetObjectFile()->GetModule()->ReportWarning(2051 "Module {0} is out-of-date (hash mismatch).\n"2052 "Type information from this module may be incomplete or inconsistent "2053 "with the rest of the program. Rebuilding the project will "2054 "regenerate the needed module files.",2055 dwo_module_spec.GetFileSpec().GetPath());2056 }2057 }2058}2059 2060SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {2061 if (!m_global_aranges_up) {2062 m_global_aranges_up = std::make_unique<GlobalVariableMap>();2063 2064 ModuleSP module_sp = GetObjectFile()->GetModule();2065 if (module_sp) {2066 const size_t num_cus = module_sp->GetNumCompileUnits();2067 for (size_t i = 0; i < num_cus; ++i) {2068 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);2069 if (cu_sp) {2070 VariableListSP globals_sp = cu_sp->GetVariableList(true);2071 if (globals_sp) {2072 const size_t num_globals = globals_sp->GetSize();2073 for (size_t g = 0; g < num_globals; ++g) {2074 VariableSP var_sp = globals_sp->GetVariableAtIndex(g);2075 if (var_sp && !var_sp->GetLocationIsConstantValueData()) {2076 const DWARFExpressionList &location =2077 var_sp->LocationExpressionList();2078 ExecutionContext exe_ctx;2079 llvm::Expected<Value> location_result = location.Evaluate(2080 &exe_ctx, nullptr, LLDB_INVALID_ADDRESS, nullptr, nullptr);2081 if (location_result) {2082 if (location_result->GetValueType() ==2083 Value::ValueType::FileAddress) {2084 lldb::addr_t file_addr =2085 location_result->GetScalar().ULongLong();2086 lldb::addr_t byte_size = 1;2087 if (var_sp->GetType())2088 byte_size = llvm::expectedToOptional(2089 var_sp->GetType()->GetByteSize(nullptr))2090 .value_or(0);2091 m_global_aranges_up->Append(GlobalVariableMap::Entry(2092 file_addr, byte_size, var_sp.get()));2093 }2094 } else {2095 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols),2096 location_result.takeError(),2097 "location expression failed to execute: {0}");2098 }2099 }2100 }2101 }2102 }2103 }2104 }2105 m_global_aranges_up->Sort();2106 }2107 return *m_global_aranges_up;2108}2109 2110void SymbolFileDWARF::ResolveFunctionAndBlock(lldb::addr_t file_vm_addr,2111 bool lookup_block,2112 SymbolContext &sc) {2113 assert(sc.comp_unit);2114 DWARFCompileUnit &cu =2115 GetDWARFCompileUnit(sc.comp_unit)->GetNonSkeletonUnit();2116 DWARFDIE function_die = cu.LookupAddress(file_vm_addr);2117 DWARFDIE block_die;2118 if (function_die) {2119 sc.function = sc.comp_unit->FindFunctionByUID(function_die.GetID()).get();2120 if (sc.function == nullptr)2121 sc.function = ParseFunction(*sc.comp_unit, function_die);2122 2123 if (sc.function && lookup_block)2124 block_die = function_die.LookupDeepestBlock(file_vm_addr);2125 }2126 2127 if (!sc.function || !lookup_block)2128 return;2129 2130 Block &block = sc.function->GetBlock(true);2131 if (block_die)2132 sc.block = block.FindBlockByID(block_die.GetID());2133 else2134 sc.block = block.FindBlockByID(function_die.GetID());2135}2136 2137uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,2138 SymbolContextItem resolve_scope,2139 SymbolContext &sc) {2140 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2141 LLDB_SCOPED_TIMERF("SymbolFileDWARF::"2142 "ResolveSymbolContext (so_addr = { "2143 "section = %p, offset = 0x%" PRIx642144 " }, resolve_scope = 0x%8.8x)",2145 static_cast<void *>(so_addr.GetSection().get()),2146 so_addr.GetOffset(), resolve_scope);2147 uint32_t resolved = 0;2148 if (resolve_scope &2149 (eSymbolContextCompUnit | eSymbolContextFunction | eSymbolContextBlock |2150 eSymbolContextLineEntry | eSymbolContextVariable)) {2151 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();2152 2153 DWARFDebugInfo &debug_info = DebugInfo();2154 const DWARFDebugAranges &aranges = debug_info.GetCompileUnitAranges();2155 const dw_offset_t cu_offset = aranges.FindAddress(file_vm_addr);2156 if (cu_offset == DW_INVALID_OFFSET) {2157 // Global variables are not in the compile unit address ranges. The only2158 // way to currently find global variables is to iterate over the2159 // .debug_pubnames or the __apple_names table and find all items in there2160 // that point to DW_TAG_variable DIEs and then find the address that2161 // matches.2162 if (resolve_scope & eSymbolContextVariable) {2163 GlobalVariableMap &map = GetGlobalAranges();2164 const GlobalVariableMap::Entry *entry =2165 map.FindEntryThatContains(file_vm_addr);2166 if (entry && entry->data) {2167 Variable *variable = entry->data;2168 SymbolContextScope *scc = variable->GetSymbolContextScope();2169 if (scc) {2170 scc->CalculateSymbolContext(&sc);2171 sc.variable = variable;2172 }2173 return sc.GetResolvedMask();2174 }2175 }2176 } else {2177 uint32_t cu_idx = DW_INVALID_INDEX;2178 if (auto *dwarf_cu = llvm::dyn_cast_or_null<DWARFCompileUnit>(2179 debug_info.GetUnitAtOffset(DIERef::Section::DebugInfo, cu_offset,2180 &cu_idx))) {2181 sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);2182 if (sc.comp_unit) {2183 resolved |= eSymbolContextCompUnit;2184 2185 bool force_check_line_table = false;2186 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) {2187 ResolveFunctionAndBlock(file_vm_addr,2188 resolve_scope & eSymbolContextBlock, sc);2189 if (sc.function)2190 resolved |= eSymbolContextFunction;2191 else {2192 // We might have had a compile unit that had discontiguous address2193 // ranges where the gaps are symbols that don't have any debug2194 // info. Discontiguous compile unit address ranges should only2195 // happen when there aren't other functions from other compile2196 // units in these gaps. This helps keep the size of the aranges2197 // down.2198 force_check_line_table = true;2199 }2200 if (sc.block)2201 resolved |= eSymbolContextBlock;2202 }2203 2204 if ((resolve_scope & eSymbolContextLineEntry) ||2205 force_check_line_table) {2206 LineTable *line_table = sc.comp_unit->GetLineTable();2207 if (line_table != nullptr) {2208 // And address that makes it into this function should be in terms2209 // of this debug file if there is no debug map, or it will be an2210 // address in the .o file which needs to be fixed up to be in2211 // terms of the debug map executable. Either way, calling2212 // FixupAddress() will work for us.2213 Address exe_so_addr(so_addr);2214 if (FixupAddress(exe_so_addr)) {2215 if (line_table->FindLineEntryByAddress(exe_so_addr,2216 sc.line_entry)) {2217 resolved |= eSymbolContextLineEntry;2218 }2219 }2220 }2221 }2222 2223 if (force_check_line_table && !(resolved & eSymbolContextLineEntry)) {2224 // We might have had a compile unit that had discontiguous address2225 // ranges where the gaps are symbols that don't have any debug info.2226 // Discontiguous compile unit address ranges should only happen when2227 // there aren't other functions from other compile units in these2228 // gaps. This helps keep the size of the aranges down.2229 sc.comp_unit = nullptr;2230 resolved &= ~eSymbolContextCompUnit;2231 }2232 } else {2233 GetObjectFile()->GetModule()->ReportWarning(2234 "{0:x16}: compile unit {1} failed to create a valid "2235 "lldb_private::CompileUnit class.",2236 cu_offset, cu_idx);2237 }2238 }2239 }2240 }2241 return resolved;2242}2243 2244uint32_t SymbolFileDWARF::ResolveSymbolContext(2245 const SourceLocationSpec &src_location_spec,2246 SymbolContextItem resolve_scope, SymbolContextList &sc_list) {2247 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2248 const bool check_inlines = src_location_spec.GetCheckInlines();2249 const uint32_t prev_size = sc_list.GetSize();2250 if (resolve_scope & eSymbolContextCompUnit) {2251 for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;2252 ++cu_idx) {2253 CompileUnit *dc_cu = ParseCompileUnitAtIndex(cu_idx).get();2254 if (!dc_cu)2255 continue;2256 2257 bool file_spec_matches_cu_file_spec = FileSpec::Match(2258 src_location_spec.GetFileSpec(), dc_cu->GetPrimaryFile());2259 if (check_inlines || file_spec_matches_cu_file_spec) {2260 dc_cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list);2261 if (!check_inlines)2262 break;2263 }2264 }2265 }2266 return sc_list.GetSize() - prev_size;2267}2268 2269void SymbolFileDWARF::PreloadSymbols() {2270 // Get the symbol table for the symbol file prior to taking the module lock2271 // so that it is available without needing to take the module lock. The DWARF2272 // indexing might end up needing to relocate items when DWARF sections are2273 // loaded as they might end up getting the section contents which can call2274 // ObjectFileELF::RelocateSection() which in turn will ask for the symbol2275 // table and can cause deadlocks.2276 GetSymtab();2277 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2278 m_index->Preload();2279}2280 2281std::recursive_mutex &SymbolFileDWARF::GetModuleMutex() const {2282 lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());2283 if (module_sp)2284 return module_sp->GetMutex();2285 return GetObjectFile()->GetModule()->GetMutex();2286}2287 2288bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(2289 const lldb_private::CompilerDeclContext &decl_ctx) {2290 if (!decl_ctx.IsValid()) {2291 // Invalid namespace decl which means we aren't matching only things in2292 // this symbol file, so return true to indicate it matches this symbol2293 // file.2294 return true;2295 }2296 2297 TypeSystem *decl_ctx_type_system = decl_ctx.GetTypeSystem();2298 auto type_system_or_err = GetTypeSystemForLanguage(2299 decl_ctx_type_system->GetMinimumLanguage(nullptr));2300 if (auto err = type_system_or_err.takeError()) {2301 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),2302 "Unable to match namespace decl using TypeSystem: {0}");2303 return false;2304 }2305 2306 if (decl_ctx_type_system == type_system_or_err->get())2307 return true; // The type systems match, return true2308 2309 // The namespace AST was valid, and it does not match...2310 Log *log = GetLog(DWARFLog::Lookups);2311 2312 if (log)2313 GetObjectFile()->GetModule()->LogMessage(2314 log, "Valid namespace does not match symbol file");2315 2316 return false;2317}2318 2319void SymbolFileDWARF::FindGlobalVariables(2320 ConstString name, const CompilerDeclContext &parent_decl_ctx,2321 uint32_t max_matches, VariableList &variables) {2322 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2323 Log *log = GetLog(DWARFLog::Lookups);2324 2325 if (log)2326 GetObjectFile()->GetModule()->LogMessage(2327 log,2328 "SymbolFileDWARF::FindGlobalVariables (name=\"{0}\", "2329 "parent_decl_ctx={1:p}, max_matches={2}, variables)",2330 name.GetCString(), static_cast<const void *>(&parent_decl_ctx),2331 max_matches);2332 2333 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))2334 return;2335 2336 // Remember how many variables are in the list before we search.2337 const uint32_t original_size = variables.GetSize();2338 2339 llvm::StringRef basename;2340 llvm::StringRef context;2341 bool name_is_mangled = Mangled::GetManglingScheme(name.GetStringRef()) !=2342 Mangled::eManglingSchemeNone;2343 2344 if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name.GetStringRef(),2345 context, basename))2346 basename = name.GetStringRef();2347 2348 // Loop invariant: Variables up to this index have been checked for context2349 // matches.2350 uint32_t pruned_idx = original_size;2351 2352 SymbolContext sc;2353 m_index->GetGlobalVariables(ConstString(basename), [&](DWARFDIE die) {2354 if (!sc.module_sp)2355 sc.module_sp = m_objfile_sp->GetModule();2356 assert(sc.module_sp);2357 2358 if (die.Tag() != DW_TAG_variable && die.Tag() != DW_TAG_member)2359 return IterationAction::Continue;2360 2361 auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());2362 if (!dwarf_cu)2363 return IterationAction::Continue;2364 sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);2365 2366 if (parent_decl_ctx) {2367 if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) {2368 CompilerDeclContext actual_parent_decl_ctx =2369 dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);2370 2371 /// If the actual namespace is inline (i.e., had a DW_AT_export_symbols)2372 /// and a child (possibly through other layers of inline namespaces)2373 /// of the namespace referred to by 'basename', allow the lookup to2374 /// succeed.2375 if (!actual_parent_decl_ctx ||2376 (actual_parent_decl_ctx != parent_decl_ctx &&2377 !parent_decl_ctx.IsContainedInLookup(actual_parent_decl_ctx)))2378 return IterationAction::Continue;2379 }2380 }2381 2382 ParseAndAppendGlobalVariable(sc, die, variables);2383 while (pruned_idx < variables.GetSize()) {2384 VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx);2385 if (name_is_mangled ||2386 var_sp->GetName().GetStringRef().contains(name.GetStringRef()))2387 ++pruned_idx;2388 else2389 variables.RemoveVariableAtIndex(pruned_idx);2390 }2391 2392 if (variables.GetSize() - original_size < max_matches)2393 return IterationAction::Continue;2394 2395 return IterationAction::Stop;2396 });2397 2398 // Return the number of variable that were appended to the list2399 const uint32_t num_matches = variables.GetSize() - original_size;2400 if (log && num_matches > 0) {2401 GetObjectFile()->GetModule()->LogMessage(2402 log,2403 "SymbolFileDWARF::FindGlobalVariables (name=\"{0}\", "2404 "parent_decl_ctx={1:p}, max_matches={2}, variables) => {3}",2405 name.GetCString(), static_cast<const void *>(&parent_decl_ctx),2406 max_matches, num_matches);2407 }2408}2409 2410void SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex,2411 uint32_t max_matches,2412 VariableList &variables) {2413 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2414 Log *log = GetLog(DWARFLog::Lookups);2415 2416 if (log) {2417 GetObjectFile()->GetModule()->LogMessage(2418 log,2419 "SymbolFileDWARF::FindGlobalVariables (regex=\"{0}\", "2420 "max_matches={1}, variables)",2421 regex.GetText().str().c_str(), max_matches);2422 }2423 2424 // Remember how many variables are in the list before we search.2425 const uint32_t original_size = variables.GetSize();2426 2427 SymbolContext sc;2428 m_index->GetGlobalVariables(regex, [&](DWARFDIE die) {2429 if (!sc.module_sp)2430 sc.module_sp = m_objfile_sp->GetModule();2431 assert(sc.module_sp);2432 2433 DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());2434 if (!dwarf_cu)2435 return IterationAction::Continue;2436 sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);2437 2438 ParseAndAppendGlobalVariable(sc, die, variables);2439 2440 if (variables.GetSize() - original_size < max_matches)2441 return IterationAction::Continue;2442 2443 return IterationAction::Stop;2444 });2445}2446 2447bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,2448 bool include_inlines,2449 SymbolContextList &sc_list) {2450 SymbolContext sc;2451 2452 if (!orig_die)2453 return false;2454 2455 // If we were passed a die that is not a function, just return false...2456 if (!(orig_die.Tag() == DW_TAG_subprogram ||2457 (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine)))2458 return false;2459 2460 DWARFDIE die = orig_die;2461 DWARFDIE inlined_die;2462 if (die.Tag() == DW_TAG_inlined_subroutine) {2463 inlined_die = die;2464 2465 while (true) {2466 die = die.GetParent();2467 2468 if (die) {2469 if (die.Tag() == DW_TAG_subprogram)2470 break;2471 } else2472 break;2473 }2474 }2475 assert(die && die.Tag() == DW_TAG_subprogram);2476 if (GetFunction(die, sc)) {2477 // Parse all blocks if needed2478 if (inlined_die) {2479 Block &function_block = sc.function->GetBlock(true);2480 sc.block = function_block.FindBlockByID(inlined_die.GetID());2481 if (sc.block == nullptr)2482 sc.block = function_block.FindBlockByID(inlined_die.GetOffset());2483 }2484 2485 sc_list.Append(sc);2486 return true;2487 }2488 2489 return false;2490}2491 2492static llvm::StringRef ClangToItaniumCtorKind(clang::CXXCtorType kind) {2493 switch (kind) {2494 case clang::CXXCtorType::Ctor_Complete:2495 return "C1";2496 case clang::CXXCtorType::Ctor_Base:2497 return "C2";2498 case clang::CXXCtorType::Ctor_Unified:2499 return "C4";2500 case clang::CXXCtorType::Ctor_CopyingClosure:2501 case clang::CXXCtorType::Ctor_DefaultClosure:2502 case clang::CXXCtorType::Ctor_Comdat:2503 llvm_unreachable("Unexpected constructor kind.");2504 }2505 llvm_unreachable("Fully covered switch above");2506}2507 2508static llvm::StringRef ClangToItaniumDtorKind(clang::CXXDtorType kind) {2509 switch (kind) {2510 case clang::CXXDtorType::Dtor_Deleting:2511 return "D0";2512 case clang::CXXDtorType::Dtor_Complete:2513 return "D1";2514 case clang::CXXDtorType::Dtor_Base:2515 return "D2";2516 case clang::CXXDtorType::Dtor_Unified:2517 return "D4";2518 case clang::CXXDtorType::Dtor_Comdat:2519 llvm_unreachable("Unexpected destructor kind.");2520 }2521 llvm_unreachable("Fully covered switch above");2522}2523 2524static llvm::StringRef2525GetItaniumCtorDtorVariant(llvm::StringRef discriminator) {2526 const bool is_ctor = discriminator.consume_front("C");2527 if (!is_ctor && !discriminator.consume_front("D"))2528 return {};2529 2530 uint64_t structor_kind;2531 if (!llvm::to_integer(discriminator, structor_kind))2532 return {};2533 2534 if (is_ctor) {2535 if (structor_kind > clang::CXXCtorType::Ctor_Unified)2536 return {};2537 2538 return ClangToItaniumCtorKind(2539 static_cast<clang::CXXCtorType>(structor_kind));2540 }2541 2542 if (structor_kind > clang::CXXDtorType::Dtor_Unified)2543 return {};2544 2545 return ClangToItaniumDtorKind(static_cast<clang::CXXDtorType>(structor_kind));2546}2547 2548llvm::Expected<DWARFDIE>2549SymbolFileDWARF::FindFunctionDefinition(const FunctionCallLabel &label,2550 const DWARFDIE &declaration) {2551 auto do_lookup = [this](llvm::StringRef lookup_name) -> DWARFDIE {2552 DWARFDIE found;2553 Module::LookupInfo info(ConstString(lookup_name),2554 lldb::eFunctionNameTypeFull,2555 lldb::eLanguageTypeUnknown);2556 2557 m_index->GetFunctions(info, *this, {}, [&](DWARFDIE entry) {2558 if (entry.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_declaration, 0))2559 return IterationAction::Continue;2560 2561 found = entry;2562 return IterationAction::Stop;2563 });2564 2565 return found;2566 };2567 2568 DWARFDIE definition = do_lookup(label.lookup_name);2569 if (definition.IsValid())2570 return definition;2571 2572 // This is not a structor lookup. Nothing else to be done here.2573 if (label.discriminator.empty())2574 return llvm::createStringError(2575 "no definition DIE found in this SymbolFile");2576 2577 // We're doing a structor lookup. Maybe we didn't find the structor variant2578 // because the complete object structor was aliased to the base object2579 // structor. Try finding the alias instead.2580 //2581 // TODO: there are other reasons for why a subprogram definition might be2582 // missing. Ideally DWARF would tell us more details about which structor2583 // variant a DIE corresponds to and whether it's an alias.2584 auto subst_or_err =2585 CPlusPlusLanguage::SubstituteStructorAliases_ItaniumMangle(2586 label.lookup_name);2587 if (!subst_or_err)2588 return subst_or_err.takeError();2589 2590 definition = do_lookup(*subst_or_err);2591 2592 if (!definition.IsValid())2593 return llvm::createStringError(2594 "failed to find definition DIE for structor alias in fallback lookup");2595 2596 return definition;2597}2598 2599llvm::Expected<SymbolContext>2600SymbolFileDWARF::ResolveFunctionCallLabel(FunctionCallLabel &label) {2601 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2602 2603 if (!label.discriminator.empty()) {2604 llvm::StringRef from = label.discriminator[0] == 'C' ? "C4" : "D4";2605 2606 llvm::StringRef variant = GetItaniumCtorDtorVariant(label.discriminator);2607 if (variant.empty())2608 return llvm::createStringError(2609 "failed to get Itanium variant for discriminator");2610 2611 if (from == variant)2612 return llvm::createStringError(2613 "tried substituting unified structor variant into label");2614 2615 // If we failed to substitute unified mangled name, don't try to do a lookup2616 // using the unified name because there may be multiple definitions for it2617 // in the index, and we wouldn't know which one to choose.2618 auto subst_or_err = CPlusPlusLanguage::SubstituteStructor_ItaniumMangle(2619 label.lookup_name, from, variant);2620 if (!subst_or_err)2621 return llvm::joinErrors(2622 llvm::createStringError(llvm::formatv(2623 "failed to substitute {0} for {1} in mangled name {2}:", from,2624 variant, label.lookup_name)),2625 subst_or_err.takeError());2626 2627 if (!*subst_or_err)2628 return llvm::createStringError(2629 llvm::formatv("got invalid substituted mangled named (substituted "2630 "{0} for {1} in mangled name {2})",2631 from, variant, label.lookup_name));2632 2633 label.lookup_name = subst_or_err->GetStringRef();2634 }2635 2636 DWARFDIE die = GetDIE(label.symbol_id);2637 if (!die.IsValid())2638 return llvm::createStringError(2639 llvm::formatv("invalid DIE ID in {0}", label));2640 2641 // Label was created using a declaration DIE. Need to fetch the definition2642 // to resolve the function call.2643 if (die.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_declaration, 0)) {2644 auto die_or_err = FindFunctionDefinition(label, die);2645 if (!die_or_err)2646 return llvm::joinErrors(2647 llvm::createStringError("failed to find definition DIE:"),2648 die_or_err.takeError());2649 2650 die = std::move(*die_or_err);2651 }2652 2653 SymbolContextList sc_list;2654 if (!ResolveFunction(die, /*include_inlines=*/false, sc_list))2655 return llvm::createStringError("failed to resolve function");2656 2657 if (sc_list.IsEmpty())2658 return llvm::createStringError("failed to find function");2659 2660 assert(sc_list.GetSize() == 1);2661 2662 return sc_list[0];2663}2664 2665bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext &decl_ctx,2666 const DWARFDIE &die,2667 bool only_root_namespaces) {2668 // If we have no parent decl context to match this DIE matches, and if the2669 // parent decl context isn't valid, we aren't trying to look for any2670 // particular decl context so any die matches.2671 if (!decl_ctx.IsValid()) {2672 // ...But if we are only checking root decl contexts, confirm that the2673 // 'die' is a top-level context.2674 if (only_root_namespaces)2675 return die.GetParent().Tag() == llvm::dwarf::DW_TAG_compile_unit;2676 2677 return true;2678 }2679 2680 if (die) {2681 if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) {2682 if (CompilerDeclContext actual_decl_ctx =2683 dwarf_ast->GetDeclContextContainingUIDFromDWARF(die))2684 return decl_ctx.IsContainedInLookup(actual_decl_ctx);2685 }2686 }2687 return false;2688}2689 2690void SymbolFileDWARF::FindFunctions(const Module::LookupInfo &lookup_info,2691 const CompilerDeclContext &parent_decl_ctx,2692 bool include_inlines,2693 SymbolContextList &sc_list) {2694 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2695 ConstString name = lookup_info.GetLookupName();2696 FunctionNameType name_type_mask = lookup_info.GetNameTypeMask();2697 2698 // eFunctionNameTypeAuto should be pre-resolved by a call to2699 // Module::LookupInfo::LookupInfo()2700 assert((name_type_mask & eFunctionNameTypeAuto) == 0);2701 2702 Log *log = GetLog(DWARFLog::Lookups);2703 2704 if (log) {2705 GetObjectFile()->GetModule()->LogMessage(2706 log,2707 "SymbolFileDWARF::FindFunctions (name=\"{0}\", name_type_mask={1:x}, "2708 "sc_list)",2709 name.GetCString(), name_type_mask);2710 }2711 2712 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))2713 return;2714 2715 // If name is empty then we won't find anything.2716 if (name.IsEmpty())2717 return;2718 2719 // Remember how many sc_list are in the list before we search in case we are2720 // appending the results to a variable list.2721 2722 const uint32_t original_size = sc_list.GetSize();2723 2724 llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;2725 2726 m_index->GetFunctions(lookup_info, *this, parent_decl_ctx, [&](DWARFDIE die) {2727 if (resolved_dies.insert(die.GetDIE()).second)2728 ResolveFunction(die, include_inlines, sc_list);2729 return IterationAction::Continue;2730 });2731 // With -gsimple-template-names, a templated type's DW_AT_name will not2732 // contain the template parameters. Try again stripping '<' and anything2733 // after, filtering out entries with template parameters that don't match.2734 {2735 const llvm::StringRef name_ref = name.GetStringRef();2736 auto it = name_ref.find('<');2737 if (it != llvm::StringRef::npos) {2738 const llvm::StringRef name_no_template_params = name_ref.slice(0, it);2739 2740 Module::LookupInfo no_tp_lookup_info(lookup_info);2741 no_tp_lookup_info.SetLookupName(ConstString(name_no_template_params));2742 m_index->GetFunctions(no_tp_lookup_info, *this, parent_decl_ctx,2743 [&](DWARFDIE die) {2744 if (resolved_dies.insert(die.GetDIE()).second)2745 ResolveFunction(die, include_inlines, sc_list);2746 return IterationAction::Continue;2747 });2748 }2749 }2750 2751 // Return the number of variable that were appended to the list2752 const uint32_t num_matches = sc_list.GetSize() - original_size;2753 2754 if (log && num_matches > 0) {2755 GetObjectFile()->GetModule()->LogMessage(2756 log,2757 "SymbolFileDWARF::FindFunctions (name=\"{0}\", "2758 "name_type_mask={1:x}, include_inlines={2:d}, sc_list) => {3}",2759 name.GetCString(), name_type_mask, include_inlines, num_matches);2760 }2761}2762 2763void SymbolFileDWARF::FindFunctions(const RegularExpression ®ex,2764 bool include_inlines,2765 SymbolContextList &sc_list) {2766 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2767 LLDB_SCOPED_TIMERF("SymbolFileDWARF::FindFunctions (regex = '%s')",2768 regex.GetText().str().c_str());2769 2770 Log *log = GetLog(DWARFLog::Lookups);2771 2772 if (log) {2773 GetObjectFile()->GetModule()->LogMessage(2774 log, "SymbolFileDWARF::FindFunctions (regex=\"{0}\", sc_list)",2775 regex.GetText().str().c_str());2776 }2777 2778 llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;2779 m_index->GetFunctions(regex, [&](DWARFDIE die) {2780 if (resolved_dies.insert(die.GetDIE()).second)2781 ResolveFunction(die, include_inlines, sc_list);2782 return IterationAction::Continue;2783 });2784}2785 2786void SymbolFileDWARF::GetMangledNamesForFunction(2787 const std::string &scope_qualified_name,2788 std::vector<ConstString> &mangled_names) {2789 DWARFDebugInfo &info = DebugInfo();2790 uint32_t num_comp_units = info.GetNumUnits();2791 for (uint32_t i = 0; i < num_comp_units; i++) {2792 DWARFUnit *cu = info.GetUnitAtIndex(i);2793 if (cu == nullptr)2794 continue;2795 2796 SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile();2797 if (dwo)2798 dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names);2799 }2800 2801 for (DIERef die_ref :2802 m_function_scope_qualified_name_map.lookup(scope_qualified_name)) {2803 DWARFDIE die = GetDIE(die_ref);2804 mangled_names.push_back(ConstString(die.GetMangledName()));2805 }2806}2807 2808/// Split a name up into a basename and template parameters.2809static bool SplitTemplateParams(llvm::StringRef fullname,2810 llvm::StringRef &basename,2811 llvm::StringRef &template_params) {2812 auto it = fullname.find('<');2813 if (it == llvm::StringRef::npos) {2814 basename = fullname;2815 template_params = llvm::StringRef();2816 return false;2817 }2818 basename = fullname.slice(0, it);2819 template_params = fullname.slice(it, fullname.size());2820 return true;2821}2822 2823static bool UpdateCompilerContextForSimpleTemplateNames(TypeQuery &match) {2824 // We need to find any names in the context that have template parameters2825 // and strip them so the context can be matched when -gsimple-template-names2826 // is being used. Returns true if any of the context items were updated.2827 bool any_context_updated = false;2828 for (auto &context : match.GetContextRef()) {2829 llvm::StringRef basename, params;2830 if (SplitTemplateParams(context.name.GetStringRef(), basename, params)) {2831 context.name = ConstString(basename);2832 any_context_updated = true;2833 }2834 }2835 return any_context_updated;2836}2837 2838uint64_t SymbolFileDWARF::GetDebugInfoSize(bool load_all_debug_info) {2839 DWARFDebugInfo &info = DebugInfo();2840 uint32_t num_comp_units = info.GetNumUnits();2841 2842 uint64_t debug_info_size = SymbolFileCommon::GetDebugInfoSize();2843 // In dwp scenario, debug info == skeleton debug info + dwp debug info.2844 if (std::shared_ptr<SymbolFileDWARFDwo> dwp_sp = GetDwpSymbolFile())2845 return debug_info_size + dwp_sp->GetDebugInfoSize();2846 2847 // In dwo scenario, debug info == skeleton debug info + all dwo debug info.2848 for (uint32_t i = 0; i < num_comp_units; i++) {2849 DWARFUnit *cu = info.GetUnitAtIndex(i);2850 if (cu == nullptr)2851 continue;2852 2853 SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile(load_all_debug_info);2854 if (dwo)2855 debug_info_size += dwo->GetDebugInfoSize();2856 }2857 return debug_info_size;2858}2859 2860void SymbolFileDWARF::FindTypes(const TypeQuery &query, TypeResults &results) {2861 2862 // Make sure we haven't already searched this SymbolFile before.2863 if (results.AlreadySearched(this))2864 return;2865 2866 auto type_basename = query.GetTypeBasename();2867 2868 Log *log = GetLog(DWARFLog::Lookups);2869 if (log) {2870 GetObjectFile()->GetModule()->LogMessage(2871 log, "SymbolFileDWARF::FindTypes(type_basename=\"{0}\")",2872 type_basename);2873 }2874 2875 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2876 2877 TypeQuery query_full(query);2878 bool have_index_match = false;2879 m_index->GetTypesWithQuery(query_full, [&](DWARFDIE die) {2880 if (Type *matching_type = ResolveType(die, true, true)) {2881 if (!query.GetSearchByMangledName() && matching_type->IsTemplateType()) {2882 // We have to watch out for case where we lookup a type by basename and2883 // it matches a template with simple template names. Like looking up2884 // "Foo" and if we have simple template names then we will match2885 // "Foo<int>" and "Foo<double>" because all the DWARF has is "Foo" in2886 // the accelerator tables. The main case we see this in is when the2887 // expression parser is trying to parse "Foo<int>" and it will first do2888 // a lookup on just "Foo". We verify the type basename matches before2889 // inserting the type in the results.2890 auto CompilerTypeBasename =2891 matching_type->GetForwardCompilerType().GetTypeName(true);2892 if (CompilerTypeBasename != query.GetTypeBasename())2893 return IterationAction::Continue;2894 }2895 have_index_match = true;2896 results.InsertUnique(matching_type->shared_from_this());2897 }2898 if (!results.Done(query))2899 return IterationAction::Continue;2900 2901 return IterationAction::Stop;2902 });2903 2904 if (results.Done(query)) {2905 if (log) {2906 GetObjectFile()->GetModule()->LogMessage(2907 log, "SymbolFileDWARF::FindTypes(type_basename=\"{0}\") => {1}",2908 type_basename, results.GetTypeMap().GetSize());2909 }2910 return;2911 }2912 2913 // With -gsimple-template-names, a templated type's DW_AT_name will not2914 // contain the template parameters. Try again stripping '<' and anything2915 // after, filtering out entries with template parameters that don't match.2916 if (!have_index_match && !query.GetSearchByMangledName()) {2917 // Create a type matcher with a compiler context that is tuned for2918 // -gsimple-template-names. We will use this for the index lookup and the2919 // context matching, but will use the original "match" to insert matches2920 // into if things match. The "match_simple" has a compiler context with2921 // all template parameters removed to allow the names and context to match.2922 // The UpdateCompilerContextForSimpleTemplateNames(...) will return true if2923 // it trims any context items down by removing template parameter names.2924 TypeQuery query_simple(query);2925 if (UpdateCompilerContextForSimpleTemplateNames(query_simple)) {2926 auto type_basename_simple = query_simple.GetTypeBasename();2927 // Copy our match's context and update the basename we are looking for2928 // so we can use this only to compare the context correctly.2929 m_index->GetTypesWithQuery(query_simple, [&](DWARFDIE die) {2930 std::vector<CompilerContext> qualified_context =2931 query.GetModuleSearch()2932 ? die.GetDeclContext(/*derive_template_names=*/true)2933 : die.GetTypeLookupContext(/*derive_template_names=*/true);2934 if (query.ContextMatches(qualified_context))2935 if (Type *matching_type = ResolveType(die, true, true))2936 results.InsertUnique(matching_type->shared_from_this());2937 if (!results.Done(query))2938 return IterationAction::Continue;2939 2940 return IterationAction::Stop;2941 });2942 if (results.Done(query)) {2943 if (log) {2944 GetObjectFile()->GetModule()->LogMessage(2945 log,2946 "SymbolFileDWARF::FindTypes(type_basename=\"{0}\") => {1} "2947 "(simplified as \"{2}\")",2948 type_basename, results.GetTypeMap().GetSize(),2949 type_basename_simple);2950 }2951 return;2952 }2953 }2954 }2955 2956 // Next search through the reachable Clang modules. This only applies for2957 // DWARF objects compiled with -gmodules that haven't been processed by2958 // dsymutil.2959 UpdateExternalModuleListIfNeeded();2960 2961 for (const auto &pair : m_external_type_modules) {2962 if (ModuleSP external_module_sp = pair.second) {2963 external_module_sp->FindTypes(query, results);2964 if (results.Done(query)) {2965 // We don't log the results here as they are already logged in the2966 // nested FindTypes call2967 return;2968 }2969 }2970 }2971}2972 2973CompilerDeclContext2974SymbolFileDWARF::FindNamespace(ConstString name,2975 const CompilerDeclContext &parent_decl_ctx,2976 bool only_root_namespaces) {2977 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2978 Log *log = GetLog(DWARFLog::Lookups);2979 2980 if (log) {2981 GetObjectFile()->GetModule()->LogMessage(2982 log, "SymbolFileDWARF::FindNamespace (sc, name=\"{0}\")",2983 name.GetCString());2984 }2985 2986 CompilerDeclContext namespace_decl_ctx;2987 2988 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))2989 return namespace_decl_ctx;2990 2991 m_index->GetNamespacesWithParents(name, parent_decl_ctx, [&](DWARFDIE die) {2992 if (!DIEInDeclContext(parent_decl_ctx, die, only_root_namespaces))2993 return IterationAction::Continue;2994 2995 DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU());2996 if (!dwarf_ast)2997 return IterationAction::Continue;2998 2999 namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die);3000 if (namespace_decl_ctx.IsValid())3001 return IterationAction::Stop;3002 3003 return IterationAction::Continue;3004 });3005 3006 if (log && namespace_decl_ctx) {3007 GetObjectFile()->GetModule()->LogMessage(3008 log,3009 "SymbolFileDWARF::FindNamespace (sc, name=\"{0}\") => "3010 "CompilerDeclContext({1:p}/{2:p}) \"{3}\"",3011 name.GetCString(),3012 static_cast<const void *>(namespace_decl_ctx.GetTypeSystem()),3013 static_cast<const void *>(namespace_decl_ctx.GetOpaqueDeclContext()),3014 namespace_decl_ctx.GetName().AsCString("<NULL>"));3015 }3016 3017 return namespace_decl_ctx;3018}3019 3020TypeSP SymbolFileDWARF::GetTypeForDIE(const DWARFDIE &die,3021 bool resolve_function_context) {3022 TypeSP type_sp;3023 if (die) {3024 Type *type_ptr = GetDIEToType().lookup(die.GetDIE());3025 if (type_ptr == nullptr) {3026 SymbolContextScope *scope;3027 if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU()))3028 scope = GetCompUnitForDWARFCompUnit(*dwarf_cu);3029 else3030 scope = GetObjectFile()->GetModule().get();3031 assert(scope);3032 SymbolContext sc(scope);3033 const DWARFDebugInfoEntry *parent_die = die.GetParent().GetDIE();3034 while (parent_die != nullptr) {3035 if (parent_die->Tag() == DW_TAG_subprogram)3036 break;3037 parent_die = parent_die->GetParent();3038 }3039 SymbolContext sc_backup = sc;3040 if (resolve_function_context && parent_die != nullptr &&3041 !GetFunction(DWARFDIE(die.GetCU(), parent_die), sc))3042 sc = sc_backup;3043 3044 type_sp = ParseType(sc, die, nullptr);3045 } else if (type_ptr != DIE_IS_BEING_PARSED) {3046 // Get the original shared pointer for this type3047 type_sp = type_ptr->shared_from_this();3048 }3049 }3050 return type_sp;3051}3052 3053DWARFDIE3054SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE &orig_die) {3055 if (orig_die) {3056 DWARFDIE die = orig_die;3057 3058 while (die) {3059 // If this is the original DIE that we are searching for a declaration3060 // for, then don't look in the cache as we don't want our own decl3061 // context to be our decl context...3062 if (orig_die != die) {3063 switch (die.Tag()) {3064 case DW_TAG_compile_unit:3065 case DW_TAG_partial_unit:3066 case DW_TAG_namespace:3067 case DW_TAG_structure_type:3068 case DW_TAG_union_type:3069 case DW_TAG_class_type:3070 case DW_TAG_lexical_block:3071 case DW_TAG_subprogram:3072 return die;3073 case DW_TAG_inlined_subroutine: {3074 DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);3075 if (abs_die) {3076 return abs_die;3077 }3078 break;3079 }3080 default:3081 break;3082 }3083 }3084 3085 DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification);3086 if (spec_die) {3087 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die);3088 if (decl_ctx_die)3089 return decl_ctx_die;3090 }3091 3092 DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);3093 if (abs_die) {3094 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die);3095 if (decl_ctx_die)3096 return decl_ctx_die;3097 }3098 3099 die = die.GetParent();3100 }3101 }3102 return DWARFDIE();3103}3104 3105Symbol *SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) {3106 Symbol *objc_class_symbol = nullptr;3107 if (m_objfile_sp) {3108 Symtab *symtab = m_objfile_sp->GetSymtab();3109 if (symtab) {3110 objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(3111 objc_class_name, eSymbolTypeObjCClass, Symtab::eDebugNo,3112 Symtab::eVisibilityAny);3113 }3114 }3115 return objc_class_symbol;3116}3117 3118// This function can be used when a DIE is found that is a forward declaration3119// DIE and we want to try and find a type that has the complete definition.3120TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(3121 const DWARFDIE &die, ConstString type_name, bool must_be_implementation) {3122 3123 TypeSP type_sp;3124 3125 if (!type_name || (must_be_implementation && !GetObjCClassSymbol(type_name)))3126 return type_sp;3127 3128 m_index->GetCompleteObjCClass(3129 type_name, must_be_implementation, [&](DWARFDIE type_die) {3130 // Don't try and resolve the DIE we are looking for with the DIE3131 // itself!3132 if (type_die == die || !IsStructOrClassTag(type_die.Tag()))3133 return IterationAction::Continue;3134 3135 if (must_be_implementation) {3136 const bool try_resolving_type = type_die.GetAttributeValueAsUnsigned(3137 DW_AT_APPLE_objc_complete_type, 0);3138 if (!try_resolving_type)3139 return IterationAction::Continue;3140 }3141 3142 Type *resolved_type = ResolveType(type_die, false, true);3143 if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED)3144 return IterationAction::Continue;3145 3146 DEBUG_PRINTF(3147 "resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx643148 " (cu 0x%8.8" PRIx64 ")\n",3149 die.GetID(),3150 m_objfile_sp->GetFileSpec().GetFilename().AsCString("<Unknown>"),3151 type_die.GetID(), type_cu->GetID());3152 3153 if (die)3154 GetDIEToType()[die.GetDIE()] = resolved_type;3155 type_sp = resolved_type->shared_from_this();3156 return IterationAction::Stop;3157 });3158 return type_sp;3159}3160 3161DWARFDIE3162SymbolFileDWARF::FindDefinitionDIE(const DWARFDIE &die) {3163 const char *name = die.GetName();3164 if (!name)3165 return {};3166 if (!die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0))3167 return die;3168 3169 Progress progress(llvm::formatv(3170 "Searching definition DIE in {0}: '{1}'",3171 GetObjectFile()->GetFileSpec().GetFilename().GetString(), name));3172 3173 const dw_tag_t tag = die.Tag();3174 3175 Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);3176 if (log) {3177 GetObjectFile()->GetModule()->LogMessage(3178 log,3179 "SymbolFileDWARF::FindDefinitionDIE(tag={0} "3180 "({1}), name='{2}')",3181 DW_TAG_value_to_name(tag), tag, name);3182 }3183 3184 // Get the type system that we are looking to find a type for. We will3185 // use this to ensure any matches we find are in a language that this3186 // type system supports3187 const LanguageType language = GetLanguage(*die.GetCU());3188 TypeSystemSP type_system = nullptr;3189 if (language != eLanguageTypeUnknown) {3190 auto type_system_or_err = GetTypeSystemForLanguage(language);3191 if (auto err = type_system_or_err.takeError()) {3192 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),3193 "Cannot get TypeSystem for language {1}: {0}",3194 Language::GetNameForLanguageType(language));3195 } else {3196 type_system = *type_system_or_err;3197 }3198 }3199 3200 // See comments below about -gsimple-template-names for why we attempt to3201 // compute missing template parameter names.3202 std::vector<std::string> template_params;3203 DWARFDeclContext die_dwarf_decl_ctx;3204 DWARFASTParser *dwarf_ast =3205 type_system ? type_system->GetDWARFParser() : nullptr;3206 for (DWARFDIE ctx_die = die; ctx_die && !isUnitType(ctx_die.Tag());3207 ctx_die = ctx_die.GetParentDeclContextDIE()) {3208 die_dwarf_decl_ctx.AppendDeclContext(ctx_die.Tag(), ctx_die.GetName());3209 template_params.push_back(3210 (ctx_die.IsStructUnionOrClass() && dwarf_ast)3211 ? dwarf_ast->GetDIEClassTemplateParams(ctx_die)3212 : "");3213 }3214 const bool any_template_params = llvm::any_of(3215 template_params, [](llvm::StringRef p) { return !p.empty(); });3216 3217 auto die_matches = [&](DWARFDIE type_die) {3218 // Resolve the type if both have the same tag or {class, struct} tags.3219 const bool tag_matches =3220 type_die.Tag() == tag ||3221 (IsStructOrClassTag(type_die.Tag()) && IsStructOrClassTag(tag));3222 if (!tag_matches)3223 return false;3224 if (any_template_params) {3225 size_t pos = 0;3226 for (DWARFDIE ctx_die = type_die; ctx_die && !isUnitType(ctx_die.Tag()) &&3227 pos < template_params.size();3228 ctx_die = ctx_die.GetParentDeclContextDIE(), ++pos) {3229 if (template_params[pos].empty())3230 continue;3231 if (template_params[pos] !=3232 dwarf_ast->GetDIEClassTemplateParams(ctx_die))3233 return false;3234 }3235 if (pos != template_params.size())3236 return false;3237 }3238 return true;3239 };3240 DWARFDIE result;3241 m_index->GetFullyQualifiedType(die_dwarf_decl_ctx, [&](DWARFDIE type_die) {3242 // Make sure type_die's language matches the type system we are3243 // looking for. We don't want to find a "Foo" type from Java if we3244 // are looking for a "Foo" type for C, C++, ObjC, or ObjC++.3245 if (type_system &&3246 !type_system->SupportsLanguage(GetLanguage(*type_die.GetCU())))3247 return IterationAction::Continue;3248 3249 if (!die_matches(type_die)) {3250 if (log) {3251 GetObjectFile()->GetModule()->LogMessage(3252 log,3253 "SymbolFileDWARF::FindDefinitionDIE(tag={0} ({1}), "3254 "name='{2}') ignoring die={3:x16} ({4})",3255 DW_TAG_value_to_name(tag), tag, name, type_die.GetOffset(),3256 type_die.GetName());3257 }3258 return IterationAction::Continue;3259 }3260 3261 if (log) {3262 DWARFDeclContext type_dwarf_decl_ctx = type_die.GetDWARFDeclContext();3263 GetObjectFile()->GetModule()->LogMessage(3264 log,3265 "SymbolFileDWARF::FindDefinitionTypeDIE(tag={0} ({1}), name='{2}') "3266 "trying die={3:x16} ({4})",3267 DW_TAG_value_to_name(tag), tag, name, type_die.GetOffset(),3268 type_dwarf_decl_ctx.GetQualifiedName());3269 }3270 3271 result = type_die;3272 return IterationAction::Stop;3273 });3274 return result;3275}3276 3277TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die,3278 bool *type_is_new_ptr) {3279 if (!die)3280 return {};3281 3282 auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));3283 if (auto err = type_system_or_err.takeError()) {3284 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),3285 "Unable to parse type: {0}");3286 return {};3287 }3288 auto ts = *type_system_or_err;3289 if (!ts)3290 return {};3291 3292 DWARFASTParser *dwarf_ast = ts->GetDWARFParser();3293 if (!dwarf_ast)3294 return {};3295 3296 TypeSP type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, type_is_new_ptr);3297 if (type_sp) {3298 if (die.Tag() == DW_TAG_subprogram) {3299 std::string scope_qualified_name(GetDeclContextForUID(die.GetID())3300 .GetScopeQualifiedName()3301 .AsCString(""));3302 if (scope_qualified_name.size()) {3303 m_function_scope_qualified_name_map[scope_qualified_name].insert(3304 *die.GetDIERef());3305 }3306 }3307 }3308 3309 return type_sp;3310}3311 3312size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc,3313 const DWARFDIE &orig_die,3314 bool parse_siblings, bool parse_children) {3315 size_t types_added = 0;3316 DWARFDIE die = orig_die;3317 3318 while (die) {3319 const dw_tag_t tag = die.Tag();3320 bool type_is_new = false;3321 3322 Tag dwarf_tag = static_cast<Tag>(tag);3323 3324 // TODO: Currently ParseTypeFromDWARF(...) which is called by ParseType(...)3325 // does not handle DW_TAG_subrange_type. It is not clear if this is a bug or3326 // not.3327 if (isType(dwarf_tag) && tag != DW_TAG_subrange_type)3328 ParseType(sc, die, &type_is_new);3329 3330 if (type_is_new)3331 ++types_added;3332 3333 if (parse_children && die.HasChildren()) {3334 if (die.Tag() == DW_TAG_subprogram) {3335 SymbolContext child_sc(sc);3336 child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();3337 types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true);3338 } else3339 types_added += ParseTypes(sc, die.GetFirstChild(), true, true);3340 }3341 3342 if (parse_siblings)3343 die = die.GetSibling();3344 else3345 die.Clear();3346 }3347 return types_added;3348}3349 3350size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {3351 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());3352 CompileUnit *comp_unit = func.GetCompileUnit();3353 lldbassert(comp_unit);3354 3355 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(comp_unit);3356 if (!dwarf_cu)3357 return 0;3358 3359 size_t functions_added = 0;3360 const dw_offset_t function_die_offset = DIERef(func.GetID()).die_offset();3361 DWARFDIE function_die =3362 dwarf_cu->GetNonSkeletonUnit().GetDIE(function_die_offset);3363 if (function_die) {3364 // We can't use the file address from the Function object as (in the OSO3365 // case) it will already be remapped to the main module.3366 if (llvm::Expected<llvm::DWARFAddressRangesVector> ranges =3367 function_die.GetDIE()->GetAttributeAddressRanges(3368 function_die.GetCU(),3369 /*check_hi_lo_pc=*/true)) {3370 if (ranges->empty())3371 return 0;3372 dw_addr_t function_file_addr = ranges->begin()->LowPC;3373 if (function_file_addr != LLDB_INVALID_ADDRESS)3374 ParseBlocksRecursive(*comp_unit, &func.GetBlock(false),3375 function_die.GetFirstChild(), function_file_addr);3376 } else {3377 LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), ranges.takeError(),3378 "{1:x}: {0}", dwarf_cu->GetOffset());3379 }3380 }3381 3382 return functions_added;3383}3384 3385size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) {3386 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());3387 size_t types_added = 0;3388 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);3389 if (dwarf_cu) {3390 DWARFDIE dwarf_cu_die = dwarf_cu->DIE();3391 if (dwarf_cu_die && dwarf_cu_die.HasChildren()) {3392 SymbolContext sc;3393 sc.comp_unit = &comp_unit;3394 types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true);3395 }3396 }3397 3398 return types_added;3399}3400 3401size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {3402 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());3403 if (sc.comp_unit != nullptr) {3404 if (sc.function) {3405 DWARFDIE function_die = GetDIE(sc.function->GetID());3406 3407 dw_addr_t func_lo_pc = LLDB_INVALID_ADDRESS;3408 if (llvm::Expected<llvm::DWARFAddressRangesVector> ranges =3409 function_die.GetDIE()->GetAttributeAddressRanges(3410 function_die.GetCU(), /*check_hi_lo_pc=*/true)) {3411 if (!ranges->empty())3412 func_lo_pc = ranges->begin()->LowPC;3413 } else {3414 LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), ranges.takeError(),3415 "DIE({1:x}): {0}", function_die.GetID());3416 }3417 if (func_lo_pc != LLDB_INVALID_ADDRESS) {3418 const size_t num_variables =3419 ParseVariablesInFunctionContext(sc, function_die, func_lo_pc);3420 3421 // Let all blocks know they have parse all their variables3422 sc.function->GetBlock(false).SetDidParseVariables(true, true);3423 return num_variables;3424 }3425 } else if (sc.comp_unit) {3426 DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(sc.comp_unit->GetID());3427 3428 if (dwarf_cu == nullptr)3429 return 0;3430 3431 uint32_t vars_added = 0;3432 VariableListSP variables(sc.comp_unit->GetVariableList(false));3433 3434 if (variables.get() == nullptr) {3435 variables = std::make_shared<VariableList>();3436 sc.comp_unit->SetVariableList(variables);3437 3438 m_index->GetGlobalVariables(*dwarf_cu, [&](DWARFDIE die) {3439 VariableSP var_sp(ParseVariableDIECached(sc, die));3440 if (var_sp) {3441 variables->AddVariableIfUnique(var_sp);3442 ++vars_added;3443 }3444 return IterationAction::Continue;3445 });3446 }3447 return vars_added;3448 }3449 }3450 return 0;3451}3452 3453VariableSP SymbolFileDWARF::ParseVariableDIECached(const SymbolContext &sc,3454 const DWARFDIE &die) {3455 if (!die)3456 return nullptr;3457 3458 DIEToVariableSP &die_to_variable = die.GetDWARF()->GetDIEToVariable();3459 3460 VariableSP var_sp = die_to_variable[die.GetDIE()];3461 if (var_sp)3462 return var_sp;3463 3464 var_sp = ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS);3465 if (var_sp) {3466 die_to_variable[die.GetDIE()] = var_sp;3467 if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification))3468 die_to_variable[spec_die.GetDIE()] = var_sp;3469 }3470 return var_sp;3471}3472 3473/// Creates a DWARFExpressionList from an DW_AT_location form_value.3474static DWARFExpressionList GetExprListFromAtLocation(DWARFFormValue form_value,3475 ModuleSP module,3476 const DWARFDIE &die,3477 const addr_t func_low_pc) {3478 if (DWARFFormValue::IsBlockForm(form_value.Form())) {3479 const DWARFDataExtractor &data = die.GetData();3480 3481 uint64_t block_offset = form_value.BlockData() - data.GetDataStart();3482 uint64_t block_length = form_value.Unsigned();3483 return DWARFExpressionList(3484 module, DataExtractor(data, block_offset, block_length), die.GetCU());3485 }3486 3487 DWARFExpressionList location_list(module, DWARFExpression(), die.GetCU());3488 DataExtractor data = die.GetCU()->GetLocationData();3489 dw_offset_t offset = form_value.Unsigned();3490 if (form_value.Form() == DW_FORM_loclistx)3491 offset = die.GetCU()->GetLoclistOffset(offset).value_or(-1);3492 if (data.ValidOffset(offset)) {3493 data = DataExtractor(data, offset, data.GetByteSize() - offset);3494 const DWARFUnit *dwarf_cu = form_value.GetUnit();3495 if (dwarf_cu->ParseDWARFLocationList(data, location_list))3496 location_list.SetFuncFileAddress(func_low_pc);3497 }3498 3499 return location_list;3500}3501 3502/// Creates a DWARFExpressionList from an DW_AT_const_value. This is either a3503/// block form, or a string, or a data form. For data forms, this returns an3504/// empty list, as we cannot initialize it properly without a SymbolFileType.3505static DWARFExpressionList3506GetExprListFromAtConstValue(DWARFFormValue form_value, ModuleSP module,3507 const DWARFDIE &die) {3508 const DWARFDataExtractor &debug_info_data = die.GetData();3509 if (DWARFFormValue::IsBlockForm(form_value.Form())) {3510 // Retrieve the value as a block expression.3511 uint64_t block_offset =3512 form_value.BlockData() - debug_info_data.GetDataStart();3513 uint64_t block_length = form_value.Unsigned();3514 return DWARFExpressionList(3515 module, DataExtractor(debug_info_data, block_offset, block_length),3516 die.GetCU());3517 }3518 if (const char *str = form_value.AsCString())3519 return DWARFExpressionList(module,3520 DataExtractor(str, strlen(str) + 1,3521 die.GetCU()->GetByteOrder(),3522 die.GetCU()->GetAddressByteSize()),3523 die.GetCU());3524 return DWARFExpressionList(module, DWARFExpression(), die.GetCU());3525}3526 3527/// Global variables that are not initialized may have their address set to3528/// zero. Since multiple variables may have this address, we cannot apply the3529/// OSO relink address approach we normally use.3530/// However, the executable will have a matching symbol with a good address;3531/// this function attempts to find the correct address by looking into the3532/// executable's symbol table. If it succeeds, the expr_list is updated with3533/// the new address and the executable's symbol is returned.3534static Symbol *fixupExternalAddrZeroVariable(3535 SymbolFileDWARFDebugMap &debug_map_symfile, llvm::StringRef name,3536 DWARFExpressionList &expr_list, const DWARFDIE &die) {3537 ObjectFile *debug_map_objfile = debug_map_symfile.GetObjectFile();3538 if (!debug_map_objfile)3539 return nullptr;3540 3541 Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();3542 if (!debug_map_symtab)3543 return nullptr;3544 Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType(3545 ConstString(name), eSymbolTypeData, Symtab::eDebugYes,3546 Symtab::eVisibilityExtern);3547 if (!exe_symbol || !exe_symbol->ValueIsAddress())3548 return nullptr;3549 const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress();3550 if (exe_file_addr == LLDB_INVALID_ADDRESS)3551 return nullptr;3552 3553 DWARFExpression *location = expr_list.GetMutableExpressionAtAddress();3554 if (location->Update_DW_OP_addr(die.GetCU(), exe_file_addr))3555 return exe_symbol;3556 return nullptr;3557}3558 3559VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,3560 const DWARFDIE &die,3561 const lldb::addr_t func_low_pc) {3562 if (die.GetDWARF() != this)3563 return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc);3564 3565 if (!die)3566 return nullptr;3567 3568 const dw_tag_t tag = die.Tag();3569 ModuleSP module = GetObjectFile()->GetModule();3570 3571 if (tag != DW_TAG_variable && tag != DW_TAG_constant &&3572 tag != DW_TAG_member && (tag != DW_TAG_formal_parameter || !sc.function))3573 return nullptr;3574 3575 DWARFAttributes attributes = die.GetAttributes();3576 const char *name = nullptr;3577 const char *mangled = nullptr;3578 Declaration decl;3579 DWARFFormValue type_die_form;3580 bool is_external = false;3581 bool is_artificial = false;3582 DWARFFormValue const_value_form, location_form;3583 Variable::RangeList scope_ranges;3584 3585 for (size_t i = 0; i < attributes.Size(); ++i) {3586 dw_attr_t attr = attributes.AttributeAtIndex(i);3587 DWARFFormValue form_value;3588 3589 if (!attributes.ExtractFormValueAtIndex(i, form_value))3590 continue;3591 switch (attr) {3592 case DW_AT_decl_file:3593 decl.SetFile(3594 attributes.CompileUnitAtIndex(i)->GetFile(form_value.Unsigned()));3595 break;3596 case DW_AT_decl_line:3597 decl.SetLine(form_value.Unsigned());3598 break;3599 case DW_AT_decl_column:3600 decl.SetColumn(form_value.Unsigned());3601 break;3602 case DW_AT_name:3603 name = form_value.AsCString();3604 break;3605 case DW_AT_linkage_name:3606 case DW_AT_MIPS_linkage_name:3607 mangled = form_value.AsCString();3608 break;3609 case DW_AT_type:3610 // DW_AT_type on declaration may be less accurate than3611 // that of definition, so don't overwrite it.3612 if (!type_die_form.IsValid())3613 type_die_form = form_value;3614 break;3615 case DW_AT_external:3616 is_external = form_value.Boolean();3617 break;3618 case DW_AT_const_value:3619 const_value_form = form_value;3620 break;3621 case DW_AT_location:3622 location_form = form_value;3623 break;3624 case DW_AT_start_scope:3625 // TODO: Implement this.3626 break;3627 case DW_AT_artificial:3628 is_artificial = form_value.Boolean();3629 break;3630 case DW_AT_declaration:3631 case DW_AT_description:3632 case DW_AT_endianity:3633 case DW_AT_segment:3634 case DW_AT_specification:3635 case DW_AT_visibility:3636 default:3637 case DW_AT_abstract_origin:3638 case DW_AT_sibling:3639 break;3640 }3641 }3642 3643 // Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g.3644 // for static constexpr member variables -- DW_AT_const_value and3645 // DW_AT_location will both be present in the DIE defining the member.3646 bool location_is_const_value_data =3647 const_value_form.IsValid() && !location_form.IsValid();3648 3649 DWARFExpressionList location_list = [&] {3650 if (location_form.IsValid())3651 return GetExprListFromAtLocation(location_form, module, die, func_low_pc);3652 if (const_value_form.IsValid())3653 return GetExprListFromAtConstValue(const_value_form, module, die);3654 return DWARFExpressionList(module, DWARFExpression(), die.GetCU());3655 }();3656 3657 const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);3658 const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);3659 const dw_tag_t parent_tag = sc_parent_die.Tag();3660 bool is_static_member = (parent_tag == DW_TAG_compile_unit ||3661 parent_tag == DW_TAG_partial_unit) &&3662 (parent_context_die.Tag() == DW_TAG_class_type ||3663 parent_context_die.Tag() == DW_TAG_structure_type);3664 3665 ValueType scope = eValueTypeInvalid;3666 SymbolContextScope *symbol_context_scope = nullptr;3667 3668 bool has_explicit_mangled = mangled != nullptr;3669 if (!mangled) {3670 // LLDB relies on the mangled name (DW_TAG_linkage_name or3671 // DW_AT_MIPS_linkage_name) to generate fully qualified names3672 // of global variables with commands like "frame var j". For3673 // example, if j were an int variable holding a value 4 and3674 // declared in a namespace B which in turn is contained in a3675 // namespace A, the command "frame var j" returns3676 // "(int) A::B::j = 4".3677 // If the compiler does not emit a linkage name, we should be3678 // able to generate a fully qualified name from the3679 // declaration context.3680 if ((parent_tag == DW_TAG_compile_unit ||3681 parent_tag == DW_TAG_partial_unit) &&3682 Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU())))3683 mangled = die.GetDWARFDeclContext()3684 .GetQualifiedNameAsConstString()3685 .GetCString();3686 }3687 3688 if (tag == DW_TAG_formal_parameter)3689 scope = eValueTypeVariableArgument;3690 else {3691 // DWARF doesn't specify if a DW_TAG_variable is a local, global3692 // or static variable, so we have to do a little digging:3693 // 1) DW_AT_linkage_name implies static lifetime (but may be missing)3694 // 2) An empty DW_AT_location is an (optimized-out) static lifetime var.3695 // 3) DW_AT_location containing a DW_OP_addr implies static lifetime.3696 // Clang likes to combine small global variables into the same symbol3697 // with locations like: DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus3698 // so we need to look through the whole expression.3699 bool has_explicit_location = location_form.IsValid();3700 bool is_static_lifetime =3701 has_explicit_mangled ||3702 (has_explicit_location && !location_list.IsValid());3703 // Check if the location has a DW_OP_addr with any address value...3704 lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;3705 if (!location_is_const_value_data) {3706 if (const DWARFExpression *location =3707 location_list.GetAlwaysValidExpr()) {3708 if (auto maybe_location_DW_OP_addr =3709 location->GetLocation_DW_OP_addr(location_form.GetUnit())) {3710 location_DW_OP_addr = *maybe_location_DW_OP_addr;3711 } else {3712 StreamString strm;3713 location->DumpLocation(&strm, eDescriptionLevelFull, nullptr);3714 GetObjectFile()->GetModule()->ReportError(3715 "{0:x16}: {1} ({2}) has an invalid location: {3}: {4}",3716 die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.Tag(),3717 llvm::fmt_consume(maybe_location_DW_OP_addr.takeError()),3718 strm.GetData());3719 }3720 }3721 if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)3722 is_static_lifetime = true;3723 }3724 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();3725 if (debug_map_symfile)3726 // Set the module of the expression to the linked module3727 // instead of the object file so the relocated address can be3728 // found there.3729 location_list.SetModule(debug_map_symfile->GetObjectFile()->GetModule());3730 3731 if (is_static_lifetime) {3732 if (is_external)3733 scope = eValueTypeVariableGlobal;3734 else3735 scope = eValueTypeVariableStatic;3736 3737 if (debug_map_symfile) {3738 bool linked_oso_file_addr = false;3739 3740 if (is_external && location_DW_OP_addr == 0) {3741 if (Symbol *exe_symbol = fixupExternalAddrZeroVariable(3742 *debug_map_symfile, mangled ? mangled : name, location_list,3743 die)) {3744 linked_oso_file_addr = true;3745 symbol_context_scope = exe_symbol;3746 }3747 }3748 3749 if (!linked_oso_file_addr) {3750 // The DW_OP_addr is not zero, but it contains a .o file address3751 // which needs to be linked up correctly.3752 const lldb::addr_t exe_file_addr =3753 debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);3754 if (exe_file_addr != LLDB_INVALID_ADDRESS) {3755 // Update the file address for this variable3756 DWARFExpression *location =3757 location_list.GetMutableExpressionAtAddress();3758 location->Update_DW_OP_addr(die.GetCU(), exe_file_addr);3759 } else {3760 // Variable didn't make it into the final executable3761 return nullptr;3762 }3763 }3764 }3765 } else {3766 if (location_is_const_value_data &&3767 die.GetDIE()->IsGlobalOrStaticScopeVariable())3768 scope = eValueTypeVariableStatic;3769 else {3770 scope = eValueTypeVariableLocal;3771 if (debug_map_symfile) {3772 // We need to check for TLS addresses that we need to fixup3773 if (location_list.ContainsThreadLocalStorage()) {3774 location_list.LinkThreadLocalStorage(3775 debug_map_symfile->GetObjectFile()->GetModule(),3776 [this, debug_map_symfile](3777 lldb::addr_t unlinked_file_addr) -> lldb::addr_t {3778 return debug_map_symfile->LinkOSOFileAddress(3779 this, unlinked_file_addr);3780 });3781 scope = eValueTypeVariableThreadLocal;3782 }3783 }3784 }3785 }3786 }3787 3788 if (symbol_context_scope == nullptr) {3789 switch (parent_tag) {3790 case DW_TAG_subprogram:3791 case DW_TAG_inlined_subroutine:3792 case DW_TAG_lexical_block:3793 if (sc.function) {3794 symbol_context_scope =3795 sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());3796 if (symbol_context_scope == nullptr)3797 symbol_context_scope = sc.function;3798 }3799 break;3800 3801 default:3802 symbol_context_scope = sc.comp_unit;3803 break;3804 }3805 }3806 3807 if (!symbol_context_scope) {3808 // Not ready to parse this variable yet. It might be a global or static3809 // variable that is in a function scope and the function in the symbol3810 // context wasn't filled in yet3811 return nullptr;3812 }3813 3814 auto type_sp = std::make_shared<SymbolFileType>(3815 *this, type_die_form.Reference().GetID());3816 3817 bool use_type_size_for_value =3818 location_is_const_value_data &&3819 DWARFFormValue::IsDataForm(const_value_form.Form());3820 if (use_type_size_for_value && type_sp->GetType()) {3821 DWARFExpression *location = location_list.GetMutableExpressionAtAddress();3822 location->UpdateValue(3823 const_value_form.Unsigned(),3824 llvm::expectedToOptional(type_sp->GetType()->GetByteSize(nullptr))3825 .value_or(0),3826 die.GetCU()->GetAddressByteSize());3827 }3828 3829 return std::make_shared<Variable>(3830 die.GetID(), name, mangled, type_sp, scope, symbol_context_scope,3831 scope_ranges, &decl, location_list, is_external, is_artificial,3832 location_is_const_value_data, is_static_member);3833}3834 3835DWARFDIE3836SymbolFileDWARF::FindBlockContainingSpecification(3837 const DIERef &func_die_ref, dw_offset_t spec_block_die_offset) {3838 // Give the concrete function die specified by "func_die_offset", find the3839 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points3840 // to "spec_block_die_offset"3841 return FindBlockContainingSpecification(GetDIE(func_die_ref),3842 spec_block_die_offset);3843}3844 3845DWARFDIE3846SymbolFileDWARF::FindBlockContainingSpecification(3847 const DWARFDIE &die, dw_offset_t spec_block_die_offset) {3848 if (die) {3849 switch (die.Tag()) {3850 case DW_TAG_subprogram:3851 case DW_TAG_inlined_subroutine:3852 case DW_TAG_lexical_block: {3853 if (die.GetReferencedDIE(DW_AT_specification).GetOffset() ==3854 spec_block_die_offset)3855 return die;3856 3857 if (die.GetReferencedDIE(DW_AT_abstract_origin).GetOffset() ==3858 spec_block_die_offset)3859 return die;3860 } break;3861 default:3862 break;3863 }3864 3865 // Give the concrete function die specified by "func_die_offset", find the3866 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points3867 // to "spec_block_die_offset"3868 for (DWARFDIE child_die : die.children()) {3869 DWARFDIE result_die =3870 FindBlockContainingSpecification(child_die, spec_block_die_offset);3871 if (result_die)3872 return result_die;3873 }3874 }3875 3876 return DWARFDIE();3877}3878 3879void SymbolFileDWARF::ParseAndAppendGlobalVariable(3880 const SymbolContext &sc, const DWARFDIE &die,3881 VariableList &cc_variable_list) {3882 if (!die)3883 return;3884 3885 dw_tag_t tag = die.Tag();3886 if (tag != DW_TAG_variable && tag != DW_TAG_constant && tag != DW_TAG_member)3887 return;3888 3889 // Check to see if we have already parsed this variable or constant?3890 VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];3891 if (var_sp) {3892 cc_variable_list.AddVariableIfUnique(var_sp);3893 return;3894 }3895 3896 // We haven't parsed the variable yet, lets do that now. Also, let us include3897 // the variable in the relevant compilation unit's variable list, if it3898 // exists.3899 VariableListSP variable_list_sp;3900 DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);3901 dw_tag_t parent_tag = sc_parent_die.Tag();3902 switch (parent_tag) {3903 case DW_TAG_compile_unit:3904 case DW_TAG_partial_unit:3905 if (sc.comp_unit != nullptr) {3906 variable_list_sp = sc.comp_unit->GetVariableList(false);3907 } else {3908 GetObjectFile()->GetModule()->ReportError(3909 "parent {0:x8} {1} ({2}) with no valid compile unit in "3910 "symbol context for {3:x8} {4} ({5}).\n",3911 sc_parent_die.GetID(), DW_TAG_value_to_name(sc_parent_die.Tag()),3912 sc_parent_die.Tag(), die.GetID(), DW_TAG_value_to_name(die.Tag()),3913 die.Tag());3914 return;3915 }3916 break;3917 3918 default:3919 LLDB_LOG(GetLog(DWARFLog::Lookups),3920 "{0} '{1}' ({2:x8}) is not a global variable - ignoring", tag,3921 die.GetName(), die.GetID());3922 return;3923 }3924 3925 var_sp = ParseVariableDIECached(sc, die);3926 if (!var_sp)3927 return;3928 3929 cc_variable_list.AddVariableIfUnique(var_sp);3930 if (variable_list_sp)3931 variable_list_sp->AddVariableIfUnique(var_sp);3932}3933 3934DIEArray3935SymbolFileDWARF::MergeBlockAbstractParameters(const DWARFDIE &block_die,3936 DIEArray &&variable_dies) {3937 // DW_TAG_inline_subroutine objects may omit DW_TAG_formal_parameter in3938 // instances of the function when they are unused (i.e., the parameter's3939 // location list would be empty). The current DW_TAG_inline_subroutine may3940 // refer to another DW_TAG_subprogram that might actually have the definitions3941 // of the parameters and we need to include these so they show up in the3942 // variables for this function (for example, in a stack trace). Let us try to3943 // find the abstract subprogram that might contain the parameter definitions3944 // and merge with the concrete parameters.3945 3946 // Nothing to merge if the block is not an inlined function.3947 if (block_die.Tag() != DW_TAG_inlined_subroutine) {3948 return std::move(variable_dies);3949 }3950 3951 // Nothing to merge if the block does not have abstract parameters.3952 DWARFDIE abs_die = block_die.GetReferencedDIE(DW_AT_abstract_origin);3953 if (!abs_die || abs_die.Tag() != DW_TAG_subprogram ||3954 !abs_die.HasChildren()) {3955 return std::move(variable_dies);3956 }3957 3958 // For each abstract parameter, if we have its concrete counterpart, insert3959 // it. Otherwise, insert the abstract parameter.3960 DIEArray::iterator concrete_it = variable_dies.begin();3961 DWARFDIE abstract_child = abs_die.GetFirstChild();3962 DIEArray merged;3963 bool did_merge_abstract = false;3964 for (; abstract_child; abstract_child = abstract_child.GetSibling()) {3965 if (abstract_child.Tag() == DW_TAG_formal_parameter) {3966 if (concrete_it == variable_dies.end() ||3967 GetDIE(*concrete_it).Tag() != DW_TAG_formal_parameter) {3968 // We arrived at the end of the concrete parameter list, so all3969 // the remaining abstract parameters must have been omitted.3970 // Let us insert them to the merged list here.3971 merged.push_back(*abstract_child.GetDIERef());3972 did_merge_abstract = true;3973 continue;3974 }3975 3976 DWARFDIE origin_of_concrete =3977 GetDIE(*concrete_it).GetReferencedDIE(DW_AT_abstract_origin);3978 if (origin_of_concrete == abstract_child) {3979 // The current abstract parameter is the origin of the current3980 // concrete parameter, just push the concrete parameter.3981 merged.push_back(*concrete_it);3982 ++concrete_it;3983 } else {3984 // Otherwise, the parameter must have been omitted from the concrete3985 // function, so insert the abstract one.3986 merged.push_back(*abstract_child.GetDIERef());3987 did_merge_abstract = true;3988 }3989 }3990 }3991 3992 // Shortcut if no merging happened.3993 if (!did_merge_abstract)3994 return std::move(variable_dies);3995 3996 // We inserted all the abstract parameters (or their concrete counterparts).3997 // Let us insert all the remaining concrete variables to the merged list.3998 // During the insertion, let us check there are no remaining concrete3999 // formal parameters. If that's the case, then just bailout from the merge -4000 // the variable list is malformed.4001 for (; concrete_it != variable_dies.end(); ++concrete_it) {4002 if (GetDIE(*concrete_it).Tag() == DW_TAG_formal_parameter) {4003 return std::move(variable_dies);4004 }4005 merged.push_back(*concrete_it);4006 }4007 return merged;4008}4009 4010size_t SymbolFileDWARF::ParseVariablesInFunctionContext(4011 const SymbolContext &sc, const DWARFDIE &die,4012 const lldb::addr_t func_low_pc) {4013 if (!die || !sc.function)4014 return 0;4015 4016 DIEArray dummy_block_variables; // The recursive call should not add anything4017 // to this vector because |die| should be a4018 // subprogram, so all variables will be added4019 // to the subprogram's list.4020 return ParseVariablesInFunctionContextRecursive(sc, die, func_low_pc,4021 dummy_block_variables);4022}4023 4024// This method parses all the variables in the blocks in the subtree of |die|,4025// and inserts them to the variable list for all the nested blocks.4026// The uninserted variables for the current block are accumulated in4027// |accumulator|.4028size_t SymbolFileDWARF::ParseVariablesInFunctionContextRecursive(4029 const lldb_private::SymbolContext &sc, const DWARFDIE &die,4030 lldb::addr_t func_low_pc, DIEArray &accumulator) {4031 size_t vars_added = 0;4032 dw_tag_t tag = die.Tag();4033 4034 if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||4035 (tag == DW_TAG_formal_parameter)) {4036 accumulator.push_back(*die.GetDIERef());4037 }4038 4039 switch (tag) {4040 case DW_TAG_subprogram:4041 case DW_TAG_inlined_subroutine:4042 case DW_TAG_lexical_block: {4043 // If we start a new block, compute a new block variable list and recurse.4044 Block *block =4045 sc.function->GetBlock(/*can_create=*/true).FindBlockByID(die.GetID());4046 if (block == nullptr) {4047 // This must be a specification or abstract origin with a4048 // concrete block counterpart in the current function. We need4049 // to find the concrete block so we can correctly add the4050 // variable to it.4051 const DWARFDIE concrete_block_die = FindBlockContainingSpecification(4052 GetDIE(sc.function->GetID()), die.GetOffset());4053 if (concrete_block_die)4054 block = sc.function->GetBlock(/*can_create=*/true)4055 .FindBlockByID(concrete_block_die.GetID());4056 }4057 4058 if (block == nullptr)4059 return 0;4060 4061 const bool can_create = false;4062 VariableListSP block_variable_list_sp =4063 block->GetBlockVariableList(can_create);4064 if (block_variable_list_sp.get() == nullptr) {4065 block_variable_list_sp = std::make_shared<VariableList>();4066 block->SetVariableList(block_variable_list_sp);4067 }4068 4069 DIEArray block_variables;4070 for (DWARFDIE child = die.GetFirstChild(); child;4071 child = child.GetSibling()) {4072 vars_added += ParseVariablesInFunctionContextRecursive(4073 sc, child, func_low_pc, block_variables);4074 }4075 block_variables =4076 MergeBlockAbstractParameters(die, std::move(block_variables));4077 vars_added += PopulateBlockVariableList(*block_variable_list_sp, sc,4078 block_variables, func_low_pc);4079 break;4080 }4081 4082 default:4083 // Recurse to children with the same variable accumulator.4084 for (DWARFDIE child = die.GetFirstChild(); child;4085 child = child.GetSibling()) {4086 vars_added += ParseVariablesInFunctionContextRecursive(4087 sc, child, func_low_pc, accumulator);4088 }4089 break;4090 }4091 4092 return vars_added;4093}4094 4095size_t SymbolFileDWARF::PopulateBlockVariableList(4096 VariableList &variable_list, const lldb_private::SymbolContext &sc,4097 llvm::ArrayRef<DIERef> variable_dies, lldb::addr_t func_low_pc) {4098 // Parse the variable DIEs and insert them to the list.4099 for (auto &die : variable_dies) {4100 if (VariableSP var_sp = ParseVariableDIE(sc, GetDIE(die), func_low_pc)) {4101 variable_list.AddVariableIfUnique(var_sp);4102 }4103 }4104 return variable_dies.size();4105}4106 4107/// Collect call site parameters in a DW_TAG_call_site DIE.4108static CallSiteParameterArray4109CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {4110 CallSiteParameterArray parameters;4111 for (DWARFDIE child : call_site_die.children()) {4112 if (child.Tag() != DW_TAG_call_site_parameter &&4113 child.Tag() != DW_TAG_GNU_call_site_parameter)4114 continue;4115 4116 std::optional<DWARFExpressionList> LocationInCallee;4117 std::optional<DWARFExpressionList> LocationInCaller;4118 4119 DWARFAttributes attributes = child.GetAttributes();4120 4121 // Parse the location at index \p attr_index within this call site parameter4122 // DIE, or return std::nullopt on failure.4123 auto parse_simple_location =4124 [&](int attr_index) -> std::optional<DWARFExpressionList> {4125 DWARFFormValue form_value;4126 if (!attributes.ExtractFormValueAtIndex(attr_index, form_value))4127 return {};4128 if (!DWARFFormValue::IsBlockForm(form_value.Form()))4129 return {};4130 auto data = child.GetData();4131 uint64_t block_offset = form_value.BlockData() - data.GetDataStart();4132 uint64_t block_length = form_value.Unsigned();4133 return DWARFExpressionList(4134 module, DataExtractor(data, block_offset, block_length),4135 child.GetCU());4136 };4137 4138 for (size_t i = 0; i < attributes.Size(); ++i) {4139 dw_attr_t attr = attributes.AttributeAtIndex(i);4140 if (attr == DW_AT_location)4141 LocationInCallee = parse_simple_location(i);4142 if (attr == DW_AT_call_value || attr == DW_AT_GNU_call_site_value)4143 LocationInCaller = parse_simple_location(i);4144 }4145 4146 if (LocationInCallee && LocationInCaller) {4147 CallSiteParameter param = {*LocationInCallee, *LocationInCaller};4148 parameters.push_back(param);4149 }4150 }4151 return parameters;4152}4153 4154/// Collect call graph edges present in a function DIE.4155std::vector<std::unique_ptr<lldb_private::CallEdge>>4156SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {4157 // Check if the function has a supported call site-related attribute.4158 // TODO: In the future it may be worthwhile to support call_all_source_calls.4159 bool has_call_edges =4160 function_die.GetAttributeValueAsUnsigned(DW_AT_call_all_calls, 0) ||4161 function_die.GetAttributeValueAsUnsigned(DW_AT_GNU_all_call_sites, 0);4162 if (!has_call_edges)4163 return {};4164 4165 Log *log = GetLog(LLDBLog::Step);4166 LLDB_LOG(log, "CollectCallEdges: Found call site info in {0}",4167 function_die.GetPubname());4168 4169 // Scan the DIE for TAG_call_site entries.4170 // TODO: A recursive scan of all blocks in the subprogram is needed in order4171 // to be DWARF5-compliant. This may need to be done lazily to be performant.4172 // For now, assume that all entries are nested directly under the subprogram4173 // (this is the kind of DWARF LLVM produces) and parse them eagerly.4174 std::vector<std::unique_ptr<CallEdge>> call_edges;4175 for (DWARFDIE child : function_die.children()) {4176 if (child.Tag() != DW_TAG_call_site && child.Tag() != DW_TAG_GNU_call_site)4177 continue;4178 4179 std::optional<DWARFDIE> call_origin;4180 std::optional<DWARFExpressionList> call_target;4181 addr_t return_pc = LLDB_INVALID_ADDRESS;4182 addr_t call_inst_pc = LLDB_INVALID_ADDRESS;4183 addr_t low_pc = LLDB_INVALID_ADDRESS;4184 bool tail_call = false;4185 4186 // Second DW_AT_low_pc may come from DW_TAG_subprogram referenced by4187 // DW_TAG_GNU_call_site's DW_AT_abstract_origin overwriting our 'low_pc'.4188 // So do not inherit attributes from DW_AT_abstract_origin.4189 DWARFAttributes attributes = child.GetAttributes(DWARFDIE::Recurse::no);4190 for (size_t i = 0; i < attributes.Size(); ++i) {4191 DWARFFormValue form_value;4192 if (!attributes.ExtractFormValueAtIndex(i, form_value)) {4193 LLDB_LOG(log, "CollectCallEdges: Could not extract TAG_call_site form");4194 break;4195 }4196 4197 dw_attr_t attr = attributes.AttributeAtIndex(i);4198 4199 if (attr == DW_AT_call_tail_call || attr == DW_AT_GNU_tail_call)4200 tail_call = form_value.Boolean();4201 4202 // Extract DW_AT_call_origin (the call target's DIE).4203 if (attr == DW_AT_call_origin || attr == DW_AT_abstract_origin) {4204 call_origin = form_value.Reference();4205 if (!call_origin->IsValid()) {4206 LLDB_LOG(log, "CollectCallEdges: Invalid call origin in {0}",4207 function_die.GetPubname());4208 break;4209 }4210 }4211 4212 if (attr == DW_AT_low_pc)4213 low_pc = form_value.Address();4214 4215 // Extract DW_AT_call_return_pc (the PC the call returns to) if it's4216 // available. It should only ever be unavailable for tail call edges, in4217 // which case use LLDB_INVALID_ADDRESS.4218 if (attr == DW_AT_call_return_pc)4219 return_pc = form_value.Address();4220 4221 // Extract DW_AT_call_pc (the PC at the call/branch instruction). It4222 // should only ever be unavailable for non-tail calls, in which case use4223 // LLDB_INVALID_ADDRESS.4224 if (attr == DW_AT_call_pc)4225 call_inst_pc = form_value.Address();4226 4227 // Extract DW_AT_call_target (the location of the address of the indirect4228 // call).4229 if (attr == DW_AT_call_target || attr == DW_AT_GNU_call_site_target) {4230 if (!DWARFFormValue::IsBlockForm(form_value.Form())) {4231 LLDB_LOG(log,4232 "CollectCallEdges: AT_call_target does not have block form");4233 break;4234 }4235 4236 auto data = child.GetData();4237 uint64_t block_offset = form_value.BlockData() - data.GetDataStart();4238 uint64_t block_length = form_value.Unsigned();4239 call_target = DWARFExpressionList(4240 module, DataExtractor(data, block_offset, block_length),4241 child.GetCU());4242 }4243 }4244 if (!call_origin && !call_target) {4245 LLDB_LOG(log, "CollectCallEdges: call site without any call target");4246 continue;4247 }4248 4249 addr_t caller_address;4250 CallEdge::AddrType caller_address_type;4251 if (return_pc != LLDB_INVALID_ADDRESS) {4252 caller_address = return_pc;4253 caller_address_type = CallEdge::AddrType::AfterCall;4254 } else if (low_pc != LLDB_INVALID_ADDRESS) {4255 caller_address = low_pc;4256 caller_address_type = CallEdge::AddrType::AfterCall;4257 } else if (call_inst_pc != LLDB_INVALID_ADDRESS) {4258 caller_address = call_inst_pc;4259 caller_address_type = CallEdge::AddrType::Call;4260 } else {4261 LLDB_LOG(log, "CollectCallEdges: No caller address");4262 continue;4263 }4264 // Adjust any PC forms. It needs to be fixed up if the main executable4265 // contains a debug map (i.e. pointers to object files), because we need a4266 // file address relative to the executable's text section.4267 caller_address = FixupAddress(caller_address);4268 4269 // Extract call site parameters.4270 CallSiteParameterArray parameters =4271 CollectCallSiteParameters(module, child);4272 4273 std::unique_ptr<CallEdge> edge;4274 if (call_origin) {4275 LLDB_LOG(log,4276 "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x}) "4277 "(call-PC: {2:x})",4278 call_origin->GetPubname(), return_pc, call_inst_pc);4279 edge = std::make_unique<DirectCallEdge>(4280 call_origin->GetMangledName(), caller_address_type, caller_address,4281 tail_call, std::move(parameters));4282 } else {4283 if (log) {4284 StreamString call_target_desc;4285 call_target->GetDescription(&call_target_desc, eDescriptionLevelBrief,4286 nullptr);4287 LLDB_LOG(log, "CollectCallEdges: Found indirect call target: {0}",4288 call_target_desc.GetString());4289 }4290 edge = std::make_unique<IndirectCallEdge>(4291 *call_target, caller_address_type, caller_address, tail_call,4292 std::move(parameters));4293 }4294 4295 if (log && parameters.size()) {4296 for (const CallSiteParameter ¶m : parameters) {4297 StreamString callee_loc_desc, caller_loc_desc;4298 param.LocationInCallee.GetDescription(&callee_loc_desc,4299 eDescriptionLevelBrief, nullptr);4300 param.LocationInCaller.GetDescription(&caller_loc_desc,4301 eDescriptionLevelBrief, nullptr);4302 LLDB_LOG(log, "CollectCallEdges: \tparam: {0} => {1}",4303 callee_loc_desc.GetString(), caller_loc_desc.GetString());4304 }4305 }4306 4307 call_edges.push_back(std::move(edge));4308 }4309 return call_edges;4310}4311 4312std::vector<std::unique_ptr<lldb_private::CallEdge>>4313SymbolFileDWARF::ParseCallEdgesInFunction(lldb_private::UserID func_id) {4314 // ParseCallEdgesInFunction must be called at the behest of an exclusively4315 // locked lldb::Function instance. Storage for parsed call edges is owned by4316 // the lldb::Function instance: locking at the SymbolFile level would be too4317 // late, because the act of storing results from ParseCallEdgesInFunction4318 // would be racy.4319 DWARFDIE func_die = GetDIE(func_id.GetID());4320 if (func_die.IsValid())4321 return CollectCallEdges(GetObjectFile()->GetModule(), func_die);4322 return {};4323}4324 4325void SymbolFileDWARF::Dump(lldb_private::Stream &s) {4326 SymbolFileCommon::Dump(s);4327 m_index->Dump(s);4328}4329 4330void SymbolFileDWARF::DumpClangAST(Stream &s, llvm::StringRef filter,4331 bool show_color) {4332 auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);4333 if (!ts_or_err)4334 return;4335 auto ts = *ts_or_err;4336 TypeSystemClang *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());4337 if (!clang)4338 return;4339 clang->Dump(s.AsRawOstream(), filter, show_color);4340}4341 4342bool SymbolFileDWARF::GetSeparateDebugInfo(StructuredData::Dictionary &d,4343 bool errors_only,4344 bool load_all_debug_info) {4345 StructuredData::Array separate_debug_info_files;4346 DWARFDebugInfo &info = DebugInfo();4347 const size_t num_cus = info.GetNumUnits();4348 for (size_t cu_idx = 0; cu_idx < num_cus; cu_idx++) {4349 DWARFUnit *unit = info.GetUnitAtIndex(cu_idx);4350 DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(unit);4351 if (dwarf_cu == nullptr)4352 continue;4353 4354 // Check if this is a DWO unit by checking if it has a DWO ID.4355 // NOTE: it seems that `DWARFUnit::IsDWOUnit` is always false?4356 if (!dwarf_cu->GetDWOId().has_value())4357 continue;4358 4359 StructuredData::DictionarySP dwo_data =4360 std::make_shared<StructuredData::Dictionary>();4361 const uint64_t dwo_id = dwarf_cu->GetDWOId().value();4362 dwo_data->AddIntegerItem("dwo_id", dwo_id);4363 4364 if (const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly()) {4365 const char *dwo_name = GetDWOName(*dwarf_cu, *die.GetDIE());4366 if (dwo_name) {4367 dwo_data->AddStringItem("dwo_name", dwo_name);4368 } else {4369 dwo_data->AddStringItem("error", "missing dwo name");4370 }4371 4372 const char *comp_dir = die.GetDIE()->GetAttributeValueAsString(4373 dwarf_cu, DW_AT_comp_dir, nullptr);4374 if (comp_dir) {4375 dwo_data->AddStringItem("comp_dir", comp_dir);4376 }4377 } else {4378 dwo_data->AddStringItem(4379 "error",4380 llvm::formatv("unable to get unit DIE for DWARFUnit at {0:x}",4381 dwarf_cu->GetOffset())4382 .str());4383 }4384 4385 // If we have a DWO symbol file, that means we were able to successfully4386 // load it.4387 SymbolFile *dwo_symfile = dwarf_cu->GetDwoSymbolFile(load_all_debug_info);4388 if (dwo_symfile) {4389 dwo_data->AddStringItem(4390 "resolved_dwo_path",4391 dwo_symfile->GetObjectFile()->GetFileSpec().GetPath());4392 } else {4393 dwo_data->AddStringItem("error",4394 dwarf_cu->GetDwoError().AsCString("unknown"));4395 }4396 dwo_data->AddBooleanItem("loaded", dwo_symfile != nullptr);4397 if (!errors_only || dwo_data->HasKey("error"))4398 separate_debug_info_files.AddItem(dwo_data);4399 }4400 4401 d.AddStringItem("type", "dwo");4402 d.AddStringItem("symfile", GetMainObjectFile()->GetFileSpec().GetPath());4403 d.AddItem("separate-debug-info-files",4404 std::make_shared<StructuredData::Array>(4405 std::move(separate_debug_info_files)));4406 return true;4407}4408 4409SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {4410 if (m_debug_map_symfile == nullptr) {4411 lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());4412 if (module_sp) {4413 m_debug_map_symfile = llvm::cast<SymbolFileDWARFDebugMap>(4414 module_sp->GetSymbolFile()->GetBackingSymbolFile());4415 }4416 }4417 return m_debug_map_symfile;4418}4419 4420const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {4421 llvm::call_once(m_dwp_symfile_once_flag, [this]() {4422 if (m_objfile_sp->GetArchitecture().GetTriple().isAppleMachO())4423 return;4424 4425 // Create a list of files to try and append .dwp to.4426 FileSpecList symfiles;4427 // Append the module's object file path.4428 const FileSpec module_fspec = m_objfile_sp->GetModule()->GetFileSpec();4429 symfiles.Append(module_fspec);4430 // Append the object file for this SymbolFile only if it is different from4431 // the module's file path. Our main module could be "a.out", our symbol file4432 // could be "a.debug" and our ".dwp" file might be "a.debug.dwp" instead of4433 // "a.out.dwp".4434 const FileSpec symfile_fspec(m_objfile_sp->GetFileSpec());4435 if (symfile_fspec != module_fspec) {4436 symfiles.Append(symfile_fspec);4437 } else {4438 // If we don't have a separate debug info file, then try stripping the4439 // extension. The main module could be "a.debug" and the .dwp file could4440 // be "a.dwp" instead of "a.debug.dwp".4441 ConstString filename_no_ext =4442 module_fspec.GetFileNameStrippingExtension();4443 if (filename_no_ext != module_fspec.GetFilename()) {4444 FileSpec module_spec_no_ext(module_fspec);4445 module_spec_no_ext.SetFilename(filename_no_ext);4446 symfiles.Append(module_spec_no_ext);4447 }4448 }4449 Log *log = GetLog(DWARFLog::SplitDwarf);4450 FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();4451 ModuleSpec module_spec;4452 module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec();4453 FileSpec dwp_filespec;4454 for (const auto &symfile : symfiles.files()) {4455 module_spec.GetSymbolFileSpec() =4456 FileSpec(symfile.GetPath() + ".dwp", symfile.GetPathStyle());4457 LLDB_LOG(log, "Searching for DWP using: \"{0}\"",4458 module_spec.GetSymbolFileSpec());4459 dwp_filespec = PluginManager::LocateExecutableSymbolFile(4460 module_spec, search_paths,4461 m_objfile_sp->GetModule()->GetSymbolLocatorStatistics());4462 if (FileSystem::Instance().Exists(dwp_filespec)) {4463 break;4464 }4465 }4466 if (!FileSystem::Instance().Exists(dwp_filespec)) {4467 LLDB_LOG(log, "No DWP file found locally");4468 // Fill in the UUID for the module we're trying to match for, so we can4469 // find the correct DWP file, as the Debuginfod plugin uses *only* this4470 // data to correctly match the DWP file with the binary.4471 module_spec.GetUUID() = m_objfile_sp->GetUUID();4472 dwp_filespec = PluginManager::LocateExecutableSymbolFile(4473 module_spec, search_paths,4474 m_objfile_sp->GetModule()->GetSymbolLocatorStatistics());4475 }4476 if (FileSystem::Instance().Exists(dwp_filespec)) {4477 LLDB_LOG(log, "Found DWP file: \"{0}\"", dwp_filespec);4478 DataBufferSP dwp_file_data_sp;4479 lldb::offset_t dwp_file_data_offset = 0;4480 ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin(4481 GetObjectFile()->GetModule(), &dwp_filespec, 0,4482 FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp,4483 dwp_file_data_offset);4484 if (dwp_obj_file) {4485 m_dwp_symfile = std::make_shared<SymbolFileDWARFDwo>(4486 *this, dwp_obj_file, DIERef::k_file_index_mask);4487 }4488 }4489 if (!m_dwp_symfile) {4490 LLDB_LOG(log, "Unable to locate for DWP file for: \"{0}\"",4491 m_objfile_sp->GetModule()->GetFileSpec());4492 }4493 });4494 return m_dwp_symfile;4495}4496 4497llvm::Expected<lldb::TypeSystemSP>4498SymbolFileDWARF::GetTypeSystem(DWARFUnit &unit) {4499 return unit.GetSymbolFileDWARF().GetTypeSystemForLanguage(GetLanguage(unit));4500}4501 4502DWARFASTParser *SymbolFileDWARF::GetDWARFParser(DWARFUnit &unit) {4503 auto type_system_or_err = GetTypeSystem(unit);4504 if (auto err = type_system_or_err.takeError()) {4505 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),4506 "Unable to get DWARFASTParser: {0}");4507 return nullptr;4508 }4509 if (auto ts = *type_system_or_err)4510 return ts->GetDWARFParser();4511 return nullptr;4512}4513 4514CompilerDecl SymbolFileDWARF::GetDecl(const DWARFDIE &die) {4515 if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()))4516 return dwarf_ast->GetDeclForUIDFromDWARF(die);4517 return CompilerDecl();4518}4519 4520CompilerDeclContext SymbolFileDWARF::GetDeclContext(const DWARFDIE &die) {4521 if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()))4522 return dwarf_ast->GetDeclContextForUIDFromDWARF(die);4523 return CompilerDeclContext();4524}4525 4526CompilerDeclContext4527SymbolFileDWARF::GetContainingDeclContext(const DWARFDIE &die) {4528 if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()))4529 return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);4530 return CompilerDeclContext();4531}4532 4533LanguageType SymbolFileDWARF::LanguageTypeFromDWARF(uint64_t val) {4534 if (val <= eLanguageTypeLastStandardLanguage)4535 return static_cast<LanguageType>(val);4536 4537 // Note: user languages between lo_user and hi_user must be handled4538 // explicitly here.4539 switch (val) {4540 case DW_LANG_Mips_Assembler:4541 return eLanguageTypeMipsAssembler;4542 default:4543 return eLanguageTypeUnknown;4544 }4545}4546 4547LanguageType SymbolFileDWARF::GetLanguage(DWARFUnit &unit) {4548 return LanguageTypeFromDWARF(unit.GetDWARFLanguageType());4549}4550 4551LanguageType SymbolFileDWARF::GetLanguageFamily(DWARFUnit &unit) {4552 auto lang = (llvm::dwarf::SourceLanguage)unit.GetDWARFLanguageType();4553 if (llvm::dwarf::isCPlusPlus(lang))4554 lang = DW_LANG_C_plus_plus;4555 return LanguageTypeFromDWARF(lang);4556}4557 4558StatsDuration::Duration SymbolFileDWARF::GetDebugInfoIndexTime() {4559 if (m_index)4560 return m_index->GetIndexTime();4561 return {};4562}4563 4564void SymbolFileDWARF::ResetStatistics() {4565 m_parse_time.reset();4566 if (m_index)4567 return m_index->ResetStatistics();4568}4569 4570Status SymbolFileDWARF::CalculateFrameVariableError(StackFrame &frame) {4571 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());4572 CompileUnit *cu = frame.GetSymbolContext(eSymbolContextCompUnit).comp_unit;4573 if (!cu)4574 return Status();4575 4576 DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(cu);4577 if (!dwarf_cu)4578 return Status();4579 4580 // Check if we have a skeleton compile unit that had issues trying to load4581 // its .dwo/.dwp file. First pares the Unit DIE to make sure we see any .dwo4582 // related errors.4583 dwarf_cu->ExtractUnitDIEIfNeeded();4584 const Status &dwo_error = dwarf_cu->GetDwoError();4585 if (dwo_error.Fail())4586 return dwo_error.Clone();4587 4588 // Don't return an error for assembly files as they typically don't have4589 // varaible information.4590 if (dwarf_cu->GetDWARFLanguageType() == DW_LANG_Mips_Assembler)4591 return Status();4592 4593 // Check if this compile unit has any variable DIEs. If it doesn't then there4594 // is not variable information for the entire compile unit.4595 if (dwarf_cu->HasAny({DW_TAG_variable, DW_TAG_formal_parameter}))4596 return Status();4597 4598 return Status::FromErrorString(4599 "no variable information is available in debug info for this "4600 "compile unit");4601}4602 4603void SymbolFileDWARF::GetCompileOptions(4604 std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) {4605 4606 const uint32_t num_compile_units = GetNumCompileUnits();4607 4608 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {4609 lldb::CompUnitSP comp_unit = GetCompileUnitAtIndex(cu_idx);4610 if (!comp_unit)4611 continue;4612 4613 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(comp_unit.get());4614 if (!dwarf_cu)4615 continue;4616 4617 const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly();4618 if (!die)4619 continue;4620 4621 const char *flags = die.GetAttributeValueAsString(DW_AT_APPLE_flags, NULL);4622 4623 if (!flags)4624 continue;4625 args.insert({comp_unit, Args(flags)});4626 }4627}4628 4629DWOStats SymbolFileDWARF::GetDwoStats() {4630 DWOStats stats;4631 4632 DWARFDebugInfo &info = DebugInfo();4633 const size_t num_cus = info.GetNumUnits();4634 for (size_t cu_idx = 0; cu_idx < num_cus; cu_idx++) {4635 DWARFUnit *dwarf_cu = info.GetUnitAtIndex(cu_idx);4636 if (dwarf_cu == nullptr)4637 continue;4638 4639 // Check if this is a DWO unit by checking if it has a DWO ID.4640 if (!dwarf_cu->GetDWOId().has_value())4641 continue;4642 4643 stats.dwo_file_count++;4644 4645 // If we have a DWO symbol file, that means we were able to successfully4646 // load it.4647 SymbolFile *dwo_symfile =4648 dwarf_cu->GetDwoSymbolFile(/*load_all_debug_info=*/false);4649 if (dwo_symfile) {4650 stats.loaded_dwo_file_count++;4651 }4652 4653 // Check if this unit has a DWO load error, false by default.4654 const Status &dwo_error = dwarf_cu->GetDwoError();4655 if (dwo_error.Fail())4656 stats.dwo_error_count++;4657 }4658 4659 return stats;4660}4661