brintos

brintos / llvm-project-archived public Read only

0
0
Text · 167.9 KiB · ca8e743 Raw
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 &section_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 = &section->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(&sect_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 &regex,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 &regex,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 &param : 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