10#include "llvm/ADT/STLExtras.h"
11#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
12#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
13#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
14#include "llvm/Support/Casting.h"
15#include "llvm/Support/FileUtilities.h"
16#include "llvm/Support/Format.h"
17#include "llvm/Support/FormatAdapters.h"
18#include "llvm/Support/Threading.h"
79#include "llvm/DebugInfo/DWARF/DWARFContext.h"
80#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
81#include "llvm/Support/FileSystem.h"
82#include "llvm/Support/FormatVariadic.h"
94#ifdef ENABLE_DEBUG_PRINTF
96#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
98#define DEBUG_PRINTF(fmt, ...)
112#define LLDB_PROPERTIES_symbolfiledwarf
113#include "SymbolFileDWARFProperties.inc"
116#define LLDB_PROPERTIES_symbolfiledwarf
117#include "SymbolFileDWARFPropertiesEnum.inc"
122 static llvm::StringRef GetSettingName() {
127 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
128 m_collection_sp->Initialize(g_symbolfiledwarf_properties);
131 bool IgnoreFileIndexes()
const {
132 return GetPropertyAtIndexAs<bool>(ePropertyIgnoreIndexes,
false);
139 return Tag == llvm::dwarf::Tag::DW_TAG_class_type ||
140 Tag == llvm::dwarf::Tag::DW_TAG_structure_type;
144 static PluginProperties g_settings;
148static const llvm::DWARFDebugLine::LineTable *
154 llvm::DWARFContext &ctx = context.
GetAsLLVM();
155 llvm::Expected<const llvm::DWARFDebugLine::LineTable *> line_table =
156 line.getOrParseLineTable(
157 data, line_offset, ctx,
nullptr, [&](llvm::Error e) {
160 "SymbolFileDWARF::ParseLineTable failed to parse: {0}");
165 "SymbolFileDWARF::ParseLineTable failed to parse: {0}");
172 llvm::DWARFDebugLine::Prologue &prologue,
178 llvm::DWARFContext &ctx = context.
GetAsLLVM();
179 uint64_t offset = line_offset;
180 llvm::Error
error = prologue.parse(
185 "SymbolFileDWARF::ParseSupportFiles failed to parse "
186 "line table prologue: {0}");
191 "SymbolFileDWARF::ParseSupportFiles failed to parse line "
192 "table prologue: {0}");
198static std::optional<std::string>
202 std::string abs_path;
203 auto absolute = llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath;
204 if (prologue.getFileNameByIndex(idx, compile_dir, absolute, abs_path, style))
205 return std::move(abs_path);
208 std::string rel_path;
209 auto relative = llvm::DILineInfoSpecifier::FileLineInfoKind::RawValue;
210 if (!prologue.getFileNameByIndex(idx, compile_dir, relative, rel_path, style))
212 return std::move(rel_path);
218 llvm::StringRef compile_dir = {}) {
221 if (prologue.FileNames.empty())
225 const bool is_one_based = prologue.getVersion() < 5;
226 const size_t file_names = prologue.FileNames.size();
227 const size_t first_file_idx = is_one_based ? 1 : 0;
228 const size_t last_file_idx = is_one_based ? file_names : file_names - 1;
235 for (
size_t idx = first_file_idx; idx <= last_file_idx; ++idx) {
236 std::string remapped_file;
237 if (
auto file_path =
GetFileByIndex(prologue, idx, compile_dir, style)) {
238 auto entry = prologue.getFileNameEntry(idx);
239 auto source = entry.Source.getAsCString();
241 consumeError(source.takeError());
243 llvm::StringRef source_ref(*source);
244 if (!source_ref.empty()) {
248 LazyDWARFSourceFile(
const FileSpec &fs, llvm::StringRef source,
253 llvm::StringRef source;
255 std::unique_ptr<llvm::FileRemover> remover;
262 llvm::SmallString<0> name;
265 auto ec = llvm::sys::fs::createTemporaryFile(
266 "", llvm::sys::path::filename(orig_name, style), fd, name);
269 "Could not create temporary file");
272 remover = std::make_unique<llvm::FileRemover>(name);
274 size_t num_bytes = source.size();
275 file.Write(source.data(), num_bytes);
280 support_files.
Append(std::make_unique<LazyDWARFSourceFile>(
281 FileSpec(*file_path), *source, style));
285 if (
auto remapped = module->RemapSourceFile(llvm::StringRef(*file_path)))
286 remapped_file = *remapped;
288 remapped_file = std::move(*file_path);
292 if (prologue.ContentTypes.HasMD5) {
293 const llvm::DWARFDebugLine::FileNameEntry &file_name_entry =
294 prologue.getFileNameEntry(idx);
295 checksum = file_name_entry.
Checksum;
313 debugger, PluginProperties::GetSettingName())) {
314 const bool is_global_setting =
true;
317 "Properties for the dwarf symbol-file plug-in.", is_global_setting);
328 return "DWARF and DWARF3 debug symbol file reader.";
339 return debug_map_symfile->GetTypeList();
348 if (die_offset >= max_die_offset)
351 if (die_offset >= min_die_offset) {
354 bool add_type =
false;
357 case DW_TAG_array_type:
358 add_type = (type_mask & eTypeClassArray) != 0;
360 case DW_TAG_unspecified_type:
361 case DW_TAG_base_type:
362 add_type = (type_mask & eTypeClassBuiltin) != 0;
364 case DW_TAG_class_type:
365 add_type = (type_mask & eTypeClassClass) != 0;
367 case DW_TAG_structure_type:
368 add_type = (type_mask & eTypeClassStruct) != 0;
370 case DW_TAG_union_type:
371 add_type = (type_mask & eTypeClassUnion) != 0;
373 case DW_TAG_enumeration_type:
374 add_type = (type_mask & eTypeClassEnumeration) != 0;
376 case DW_TAG_subroutine_type:
377 case DW_TAG_subprogram:
378 case DW_TAG_inlined_subroutine:
379 add_type = (type_mask & eTypeClassFunction) != 0;
381 case DW_TAG_pointer_type:
382 add_type = (type_mask & eTypeClassPointer) != 0;
384 case DW_TAG_rvalue_reference_type:
385 case DW_TAG_reference_type:
386 add_type = (type_mask & eTypeClassReference) != 0;
389 add_type = (type_mask & eTypeClassTypedef) != 0;
391 case DW_TAG_ptr_to_member_type:
392 add_type = (type_mask & eTypeClassMemberPointer) != 0;
399 const bool assert_not_being_parsed =
true;
402 type_set.insert(type);
407 GetTypes(child_die, min_die_offset, max_die_offset, type_mask, type_set);
413 TypeClass type_mask,
TypeList &type_list)
426 unit = &unit->GetNonSkeletonUnit();
427 GetTypes(unit->DIE(), unit->GetOffset(), unit->GetNextUnitOffset(),
428 type_mask, type_set);
435 for (
size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx)
439 std::set<CompilerType> compiler_type_set;
440 for (
Type *type : type_set) {
441 CompilerType compiler_type = type->GetForwardCompilerType();
442 if (compiler_type_set.find(compiler_type) == compiler_type_set.end()) {
443 compiler_type_set.insert(compiler_type);
444 type_list.
Insert(type->shared_from_this());
458 case DW_TAG_compile_unit:
459 case DW_TAG_partial_unit:
460 case DW_TAG_subprogram:
461 case DW_TAG_inlined_subroutine:
462 case DW_TAG_lexical_block:
474 m_debug_map_symfile(nullptr),
475 m_context(m_objfile_sp->GetModule()->GetSectionList(), dwo_section_list),
476 m_fetched_external_modules(false) {}
481 static ConstString g_dwarf_section_name(
"__DWARF");
482 return g_dwarf_section_name;
485llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> &
488 return debug_map_symfile->GetDIEToType();
492llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> &
495 return debug_map_symfile->GetForwardDeclCompilerTypeToDIE();
501 if (debug_map_symfile)
507llvm::Expected<lldb::TypeSystemSP>
510 return debug_map_symfile->GetTypeSystemForLanguage(language);
512 auto type_system_or_err =
513 m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
514 if (type_system_or_err)
515 if (
auto ts = *type_system_or_err)
516 ts->SetSymbolFile(
this);
517 return type_system_or_err;
538 *
GetObjectFile()->GetModule(), apple_names, apple_namespaces,
549 llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or =
554 m_index = std::move(*index_or);
558 "Unable to read .debug_names data: {0}");
563 std::make_unique<ManualDWARFIndex>(*
GetObjectFile()->GetModule(), *
this);
575 for (
SectionSP section_sp : section_list) {
576 if (section_sp->GetChildren().GetSize() > 0) {
586 return version >= 2 && version <= 5;
589static std::set<dw_form_t>
594 std::set<dw_form_t> unsupported_forms;
595 for (
const auto &[_, decl_set] : *debug_abbrev)
596 for (
const auto &decl : decl_set)
597 for (
const auto &attr : decl.attributes())
599 unsupported_forms.insert(attr.Form);
601 return unsupported_forms;
605 uint32_t abilities = 0;
607 const Section *section =
nullptr;
609 if (section_list ==
nullptr)
612 uint64_t debug_abbrev_file_size = 0;
613 uint64_t debug_info_file_size = 0;
614 uint64_t debug_line_file_size = 0;
623 if (section !=
nullptr) {
634 if (!unsupported_forms.empty()) {
636 error.Printf(
"unsupported DW_FORM value%s:",
637 unsupported_forms.size() > 1 ?
"s" :
"");
638 for (
auto form : unsupported_forms)
639 error.Printf(
" %#x", form);
650 llvm::StringRef symfile_dir =
651 m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef();
652 if (symfile_dir.contains_insensitive(
".dsym")) {
663 "empty dSYM file detected, dSYM was created with an "
664 "executable with no debug info.");
671 if (debug_info_file_size >= MaxDebugInfoSize) {
673 "SymbolFileDWARF can't load this DWARF. It's larger then {0:x+16}",
678 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
682 if (debug_line_file_size > 0)
691 const SectionList *section_list = module_sp->GetSectionList();
713 std::make_unique<llvm::DWARFDebugAbbrev>(debug_abbrev_data.
GetAsLLVM());
714 llvm::Error
error = abbr->parse();
718 "Unable to read .debug_abbrev section: {0}");
745 return llvm::cast_or_null<DWARFCompileUnit>(dwarf_cu);
759 if (
auto remapped_file = module_sp->RemapSourceFile(file_spec.
GetPath()))
760 file_spec.
SetFile(*remapped_file, FileSpec::Style::native);
766 const char *dwo_name =
779 cu_sp = comp_unit->shared_from_this();
792 cu_sp = std::make_shared<CompileUnit>(
793 module_sp, &dwarf_cu, support_file_sp,
802 auto lazy_initialize_cu = [&]() {
824 if (support_files.
GetSize() == 0)
831 if (!lazy_initialize_cu()) {
845 initialize_cu(std::make_shared<SupportFile>(cu_file_spec),
864 for (uint32_t i = 0, num = info.
GetNumUnits(); i < num; ++i) {
865 if (
auto *cu = llvm::dyn_cast<DWARFCompileUnit>(info.
GetUnitAtIndex(i))) {
890 if (
auto *dwarf_cu = llvm::cast_or_null<DWARFCompileUnit>(
905 if (
auto err = type_system_or_err.takeError()) {
906 LLDB_LOG_ERROR(log, std::move(err),
"Unable to parse function: {0}");
909 auto ts = *type_system_or_err;
918 if (llvm::Expected<llvm::DWARFAddressRangesVector> die_ranges =
919 die.
GetDIE()->GetAttributeAddressRanges(die.
GetCU(),
921 for (
const auto &range : *die_ranges) {
924 if (
Address base_addr(range.LowPC, module_sp->GetSectionList());
926 ranges.emplace_back(std::move(base_addr), range.HighPC - range.LowPC);
945 if (
auto err = type_system_or_err.takeError()) {
947 "Unable to construct demangled name for function: {0}");
951 auto ts = *type_system_or_err;
965 if (debug_map_symfile)
972 if (debug_map_symfile) {
998 const char *sysroot =
1006 module_sp->RegisterXcodeSDK(sdk, sysroot);
1009 if (local_module_sp && local_module_sp != module_sp)
1010 local_module_sp->RegisterXcodeSDK(sdk, sysroot);
1022 size_t functions_added = 0;
1025 if (entry.Tag() != DW_TAG_subprogram)
1035 return functions_added;
1040 llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files,
1041 llvm::function_ref<
bool(
Module &)> lambda) {
1043 if (!visited_symbol_files.insert(
this).second)
1053 if (lambda(*module))
1056 for (std::size_t i = 0; i < module->GetNumCompileUnits(); ++i) {
1057 auto cu = module->GetCompileUnitAtIndex(i);
1058 bool early_exit = cu->ForEachExternalModule(visited_symbol_files, lambda);
1088 llvm::DWARFDebugLine::Prologue prologue;
1100 if (
auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(&unit)) {
1102 return lldb_cu->GetSupportFiles().GetFileSpecAtIndex(file_idx);
1106 auto &tu = llvm::cast<DWARFTypeUnit>(unit);
1118 offset == llvm::DenseMapInfo<dw_offset_t>::getEmptyKey() ||
1119 offset == llvm::DenseMapInfo<dw_offset_t>::getTombstoneKey())
1125 std::unique_ptr<SupportFileList> &list = iter_bool.first->second;
1126 if (iter_bool.second) {
1127 list = std::make_unique<SupportFileList>();
1128 uint64_t line_table_offset = offset;
1129 llvm::DWARFDataExtractor data =
1132 llvm::DWARFDebugLine::Prologue prologue;
1133 auto report = [](llvm::Error
error) {
1136 "SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse "
1137 "the line table prologue: {0}");
1140 llvm::Error
error = prologue.parse(data, &line_table_offset, report, ctx);
1142 report(std::move(
error));
1160 std::vector<SourceModule> &imported_modules) {
1176 if (child_die.Tag() != DW_TAG_imported_declaration)
1180 if (module_die.
Tag() != DW_TAG_module)
1183 if (
const char *name =
1189 while ((parent_die = parent_die.
GetParent())) {
1190 if (parent_die.
Tag() != DW_TAG_module)
1192 if (
const char *name =
1196 std::reverse(module.
path.begin(), module.
path.end());
1198 DW_AT_LLVM_include_path,
nullptr)) {
1205 DW_AT_LLVM_sysroot,
nullptr))
1207 imported_modules.push_back(module);
1227 llvm::DWARFDebugLine line;
1228 const llvm::DWARFDebugLine::LineTable *line_table =
1237 std::vector<std::unique_ptr<LineSequence>> sequences;
1240 for (
const llvm::DWARFDebugLine::Sequence &seq : line_table->Sequences) {
1247 std::unique_ptr<LineSequence> sequence =
1249 for (
unsigned idx = seq.FirstRowIndex; idx < seq.LastRowIndex; ++idx) {
1250 const llvm::DWARFDebugLine::Row &row = line_table->Rows[idx];
1252 sequence.get(), row.Address.Address, row.Line, row.Column, row.File,
1253 row.IsStmt, row.BasicBlock, row.PrologueEnd, row.EpilogueBegin,
1256 sequences.push_back(std::move(sequence));
1259 std::unique_ptr<LineTable> line_table_up =
1260 std::make_unique<LineTable>(&comp_unit, std::move(sequences));
1267 debug_map_symfile->LinkOSOLineTable(
this, line_table_up.get()));
1279 return iter->second;
1293 offset,
this, debug_macros_sp);
1295 return debug_macros_sp;
1302 if (dwarf_cu ==
nullptr)
1324 addr_t subprogram_low_pc) {
1325 size_t blocks_added = 0;
1329 if (tag != DW_TAG_inlined_subroutine && tag != DW_TAG_lexical_block)
1333 llvm::DWARFAddressRangesVector ranges;
1334 const char *name =
nullptr;
1335 const char *mangled_name =
nullptr;
1337 std::optional<int> decl_file;
1338 std::optional<int> decl_line;
1339 std::optional<int> decl_column;
1340 std::optional<int> call_file;
1341 std::optional<int> call_line;
1342 std::optional<int> call_column;
1344 decl_line, decl_column, call_file, call_line,
1345 call_column,
nullptr)) {
1346 for (
const llvm::DWARFAddressRange &range : ranges) {
1349 if (range.LowPC >= subprogram_low_pc)
1351 range.HighPC - range.LowPC));
1354 "{0:x8}: adding range [{1:x16}-{2:x16}) which has a base "
1355 "that is less than the function's low PC {3:x16}. Please file "
1356 "a bug and attach the file at the "
1357 "start of this error message",
1358 block->
GetID(), range.LowPC, range.HighPC, subprogram_low_pc);
1363 if (tag != DW_TAG_subprogram &&
1364 (name !=
nullptr || mangled_name !=
nullptr)) {
1365 std::unique_ptr<Declaration> decl_up;
1366 if (decl_file || decl_line || decl_column)
1367 decl_up = std::make_unique<Declaration>(
1369 decl_file ? *decl_file : 0),
1370 decl_line ? *decl_line : 0, decl_column ? *decl_column : 0);
1372 std::unique_ptr<Declaration> call_up;
1373 if (call_file || call_line || call_column)
1374 call_up = std::make_unique<Declaration>(
1376 call_file ? *call_file : 0),
1377 call_line ? *call_line : 0, call_column ? *call_column : 0);
1391 return blocks_added;
1398 bool check_virtuality =
false;
1400 case DW_TAG_inheritance:
1401 case DW_TAG_subprogram:
1402 check_virtuality =
true;
1407 if (check_virtuality) {
1408 if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0)
1418 if (type_system !=
nullptr)
1462std::vector<CompilerContext>
1469 return die.GetDeclContext();
1479 return type_die.ResolveType();
1490 return std::nullopt;
1498 bool assert_not_being_parsed) {
1504 "SymbolFileDWARF::ResolveTypeUID (die = {0:x16}) {1} ({2}) '{3}'",
1514 switch (decl_ctx_die.
Tag()) {
1515 case DW_TAG_structure_type:
1516 case DW_TAG_union_type:
1517 case DW_TAG_class_type: {
1522 "SymbolFileDWARF::ResolveTypeUID (die = {0:x16}) {1} ({2}) "
1523 "'{3}' resolve parent forward type for {4:x16})",
1551 if (!clang_type_system)
1560 auto clang_type_system =
1562 if (clang_type_system) {
1588 if (debug_map_symfile) {
1606 if (decl_die != def_die) {
1616 log,
"{0:x8}: {1} ({2}) '{3}' resolving forward declaration...",
1619 assert(compiler_type);
1624 bool assert_not_being_parsed,
1625 bool resolve_function_context) {
1629 if (assert_not_being_parsed) {
1634 "Parsing a die that is being parsed die: {0:x16}: {1} ({2}) {3}",
1664 m_index->GetObjCMethods(class_name, callback);
1670 if (die && llvm::isa<DWARFCompileUnit>(die.
GetCU())) {
1705 std::optional<uint32_t> file_index = die_ref.
file_index();
1716 return debug_map->GetSymbolFileByOSOIndex(*file_index);
1747 std::optional<uint64_t> dwo_id =
1759 return ::GetDWOId(*cu, *cu_die);
1768std::shared_ptr<SymbolFileDWARFDwo>
1782 if (!dwarf_cu || !dwarf_cu->
GetDWOId().has_value())
1785 const char *dwo_name =
GetDWOName(*dwarf_cu, cu_die);
1788 "missing DWO name in skeleton DIE {0:x16}", cu_die.
GetOffset()));
1801 size_t num_search_paths = debug_file_search_paths.
GetSize();
1807 const char *comp_dir =
1812 dwo_file.
SetFile(comp_dir, FileSpec::Style::native);
1823 FileSpec relative_to_binary = dwo_file;
1825 m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef());
1828 dwo_paths.
Append(relative_to_binary);
1831 for (
size_t idx = 0; idx < num_search_paths; ++idx) {
1839 dwo_paths.
Append(dirspec);
1842 size_t num_possible = dwo_paths.
GetSize();
1843 for (
size_t idx = 0; idx < num_possible && !found; ++idx) {
1846 dwo_file = dwo_spec;
1854 "unable to locate relative .dwo debug file \"%s\" for "
1855 "skeleton DIE 0x%016" PRIx64
" without valid DW_AT_comp_dir "
1866 llvm::StringRef filename_only = dwo_name_spec.
GetFilename();
1869 m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef());
1873 FileSpec dwo_name_binary_directory(binary_directory);
1875 dwo_paths.
Append(dwo_name_binary_directory);
1878 FileSpec filename_binary_directory(binary_directory);
1880 dwo_paths.
Append(filename_binary_directory);
1882 for (
size_t idx = 0; idx < num_search_paths; ++idx) {
1888 FileSpec dwo_name_dirspec(dirspec);
1890 dwo_paths.
Append(dwo_name_dirspec);
1892 FileSpec filename_dirspec(dirspec);
1894 dwo_paths.
Append(filename_dirspec);
1897 size_t num_possible = dwo_paths.
GetSize();
1898 for (
size_t idx = 0; idx < num_possible && !found; ++idx) {
1901 dwo_file = dwo_spec;
1910 if (error_dwo_path.
IsRelative() && comp_dir !=
nullptr) {
1915 "unable to locate .dwo debug file \"{0}\" for skeleton DIE "
1921 "unable to locate separate debug file (dwo, dwp). Debugging will be "
1933 dwo_file_data_offset);
1934 if (dwo_obj_file ==
nullptr) {
1936 "unable to load object file for .dwo debug file \"{0}\" for "
1942 return std::make_shared<SymbolFileDWARFDwo>(*
this, dwo_obj_file,
1954 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
1956 llvm::dyn_cast<DWARFCompileUnit>(debug_info.
GetUnitAtIndex(cu_idx));
1980 const char *comp_dir =
1984 FileSpec::Style::native);
2004 if (
m_objfile_sp->GetFileSpec().GetFileNameExtension() ==
".dwo" &&
2011 nullptr,
nullptr,
nullptr);
2017 "{0}",
error.AsCString(
"unknown error"));
2019 "Unable to locate module needed for external types.\n"
2020 "Debugging will be degraded due to missing types. Rebuilding the "
2021 "project will regenerate the needed module files.");
2032 llvm::dyn_cast_or_null<SymbolFileDWARF>(module_sp->GetSymbolFile());
2035 std::optional<uint64_t> dwo_dwo_id = dwo_symfile->GetDWOId();
2039 if (dwo_id != dwo_dwo_id) {
2041 "Module {0} is out-of-date (hash mismatch).\n"
2042 "Type information from this module may be incomplete or inconsistent "
2043 "with the rest of the program. Rebuilding the project will "
2044 "regenerate the needed module files.",
2056 const size_t num_cus = module_sp->GetNumCompileUnits();
2057 for (
size_t i = 0; i < num_cus; ++i) {
2058 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
2062 const size_t num_globals = globals_sp->GetSize();
2063 for (
size_t g = 0; g < num_globals; ++g) {
2064 VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
2065 if (var_sp && !var_sp->GetLocationIsConstantValueData()) {
2067 var_sp->LocationExpressionList();
2069 llvm::Expected<Value> location_result = location.
Evaluate(
2071 if (location_result) {
2072 if (location_result->GetValueType() ==
2075 location_result->GetScalar().ULongLong();
2077 if (var_sp->GetType())
2079 var_sp->GetType()->GetByteSize(
nullptr).value_or(0);
2081 file_addr, byte_size, var_sp.get()));
2085 location_result.takeError(),
2086 "location expression failed to execute: {0}");
2127 SymbolContextItem resolve_scope,
2131 "ResolveSymbolContext (so_addr = { "
2132 "section = %p, offset = 0x%" PRIx64
2133 " }, resolve_scope = 0x%8.8x)",
2134 static_cast<void *
>(so_addr.
GetSection().get()),
2136 uint32_t resolved = 0;
2138 (eSymbolContextCompUnit | eSymbolContextFunction | eSymbolContextBlock |
2139 eSymbolContextLineEntry | eSymbolContextVariable)) {
2151 if (resolve_scope & eSymbolContextVariable) {
2154 map.FindEntryThatContains(file_vm_addr);
2155 if (entry && entry->data) {
2167 if (
auto *dwarf_cu = llvm::dyn_cast_or_null<DWARFCompileUnit>(
2172 resolved |= eSymbolContextCompUnit;
2174 bool force_check_line_table =
false;
2175 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) {
2177 resolve_scope & eSymbolContextBlock, sc);
2179 resolved |= eSymbolContextFunction;
2187 force_check_line_table =
true;
2190 resolved |= eSymbolContextBlock;
2193 if ((resolve_scope & eSymbolContextLineEntry) ||
2194 force_check_line_table) {
2196 if (line_table !=
nullptr) {
2206 resolved |= eSymbolContextLineEntry;
2212 if (force_check_line_table && !(resolved & eSymbolContextLineEntry)) {
2219 resolved &= ~eSymbolContextCompUnit;
2223 "{0:x16}: compile unit {1} failed to create a valid "
2224 "lldb_private::CompileUnit class.",
2238 const uint32_t prev_size = sc_list.
GetSize();
2239 if (resolve_scope & eSymbolContextCompUnit) {
2248 if (check_inlines || file_spec_matches_cu_file_spec) {
2255 return sc_list.
GetSize() - prev_size;
2273 return module_sp->GetMutex();
2289 if (
auto err = type_system_or_err.takeError()) {
2291 "Unable to match namespace decl using TypeSystem: {0}");
2295 if (decl_ctx_type_system == type_system_or_err->get())
2303 log,
"Valid namespace does not match symbol file");
2317 "SymbolFileDWARF::FindGlobalVariables (name=\"{0}\", "
2318 "parent_decl_ctx={1:p}, max_matches={2}, variables)",
2319 name.
GetCString(),
static_cast<const void *
>(&parent_decl_ctx),
2326 const uint32_t original_size = variables.
GetSize();
2328 llvm::StringRef basename;
2329 llvm::StringRef context;
2339 uint32_t pruned_idx = original_size;
2347 if (die.
Tag() != DW_TAG_variable && die.
Tag() != DW_TAG_member)
2350 auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.
GetCU());
2355 if (parent_decl_ctx) {
2358 dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
2364 if (!actual_parent_decl_ctx ||
2365 (actual_parent_decl_ctx != parent_decl_ctx &&
2372 while (pruned_idx < variables.
GetSize()) {
2374 if (name_is_mangled ||
2375 var_sp->GetName().GetStringRef().contains(name.
GetStringRef()))
2381 return variables.
GetSize() - original_size < max_matches;
2385 const uint32_t num_matches = variables.
GetSize() - original_size;
2386 if (log && num_matches > 0) {
2389 "SymbolFileDWARF::FindGlobalVariables (name=\"{0}\", "
2390 "parent_decl_ctx={1:p}, max_matches={2}, variables) => {3}",
2391 name.
GetCString(),
static_cast<const void *
>(&parent_decl_ctx),
2392 max_matches, num_matches);
2397 uint32_t max_matches,
2405 "SymbolFileDWARF::FindGlobalVariables (regex=\"{0}\", "
2406 "max_matches={1}, variables)",
2407 regex.
GetText().str().c_str(), max_matches);
2411 const uint32_t original_size = variables.
GetSize();
2426 return variables.
GetSize() - original_size < max_matches;
2431 bool include_inlines,
2439 if (!(orig_die.
Tag() == DW_TAG_subprogram ||
2440 (include_inlines && orig_die.
Tag() == DW_TAG_inlined_subroutine)))
2445 if (die.
Tag() == DW_TAG_inlined_subroutine) {
2452 if (die.
Tag() == DW_TAG_subprogram)
2458 assert(die && die.
Tag() == DW_TAG_subprogram);
2465 if (sc.
block ==
nullptr)
2483 bool only_root_namespaces) {
2490 if (only_root_namespaces)
2491 return die.
GetParent().
Tag() == llvm::dwarf::DW_TAG_compile_unit;
2499 dwarf_ast->GetDeclContextContainingUIDFromDWARF(die))
2508 bool include_inlines,
2516 assert((name_type_mask & eFunctionNameTypeAuto) == 0);
2523 "SymbolFileDWARF::FindFunctions (name=\"{0}\", name_type_mask={1:x}, "
2538 const uint32_t original_size = sc_list.
GetSize();
2540 llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
2542 m_index->GetFunctions(lookup_info, *
this, parent_decl_ctx, [&](
DWARFDIE die) {
2543 if (resolved_dies.insert(die.
GetDIE()).second)
2552 auto it = name_ref.find(
'<');
2553 if (it != llvm::StringRef::npos) {
2554 const llvm::StringRef name_no_template_params = name_ref.slice(0, it);
2558 m_index->GetFunctions(no_tp_lookup_info, *
this, parent_decl_ctx,
2560 if (resolved_dies.insert(die.
GetDIE()).second)
2568 const uint32_t num_matches = sc_list.
GetSize() - original_size;
2570 if (log && num_matches > 0) {
2573 "SymbolFileDWARF::FindFunctions (name=\"{0}\", "
2574 "name_type_mask={1:x}, include_inlines={2:d}, sc_list) => {3}",
2575 name.
GetCString(), name_type_mask, include_inlines, num_matches);
2580 bool include_inlines,
2584 regex.
GetText().str().c_str());
2590 log,
"SymbolFileDWARF::FindFunctions (regex=\"{0}\", sc_list)",
2591 regex.
GetText().str().c_str());
2594 llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
2596 if (resolved_dies.insert(die.
GetDIE()).second)
2603 const std::string &scope_qualified_name,
2604 std::vector<ConstString> &mangled_names) {
2607 for (uint32_t i = 0; i < num_comp_units; i++) {
2626 llvm::StringRef &basename,
2627 llvm::StringRef &template_params) {
2628 auto it = fullname.find(
'<');
2629 if (it == llvm::StringRef::npos) {
2630 basename = fullname;
2631 template_params = llvm::StringRef();
2634 basename = fullname.slice(0, it);
2635 template_params = fullname.slice(it, fullname.size());
2643 bool any_context_updated =
false;
2645 llvm::StringRef basename, params;
2648 any_context_updated =
true;
2651 return any_context_updated;
2661 return debug_info_size + dwp_sp->GetDebugInfoSize();
2664 for (uint32_t i = 0; i < num_comp_units; i++) {
2673 return debug_info_size;
2687 log,
"SymbolFileDWARF::FindTypes(type_basename=\"{0}\")",
2694 bool have_index_match =
false;
2706 auto CompilerTypeBasename =
2707 matching_type->GetForwardCompilerType().GetTypeName(true);
2708 if (CompilerTypeBasename != query.GetTypeBasename())
2711 have_index_match =
true;
2712 results.
InsertUnique(matching_type->shared_from_this());
2714 return !results.
Done(query);
2717 if (results.
Done(query)) {
2720 log,
"SymbolFileDWARF::FindTypes(type_basename=\"{0}\") => {1}",
2745 if (!query.LanguageMatches(GetLanguageFamily(*die.GetCU())))
2749 std::string qualified_name;
2750 llvm::raw_string_ostream os(qualified_name);
2751 llvm::DWARFTypePrinter<DWARFDIE> type_printer(os);
2752 type_printer.appendQualifiedName(die);
2753 TypeQuery die_query(qualified_name, e_exact_match);
2756 results.
InsertUnique(matching_type->shared_from_this());
2757 return !results.
Done(query);
2759 if (results.
Done(query)) {
2763 "SymbolFileDWARF::FindTypes(type_basename=\"{0}\") => {1} "
2764 "(simplified as \"{2}\")",
2766 type_basename_simple);
2779 if (
ModuleSP external_module_sp = pair.second) {
2780 external_module_sp->FindTypes(query, results);
2781 if (results.
Done(query)) {
2793 bool only_root_namespaces) {
2799 log,
"SymbolFileDWARF::FindNamespace (sc, name=\"{0}\")",
2806 return namespace_decl_ctx;
2808 m_index->GetNamespacesWithParents(name, parent_decl_ctx, [&](
DWARFDIE die) {
2817 return !namespace_decl_ctx.
IsValid();
2820 if (log && namespace_decl_ctx) {
2823 "SymbolFileDWARF::FindNamespace (sc, name=\"{0}\") => "
2824 "CompilerDeclContext({1:p}/{2:p}) \"{3}\"",
2826 static_cast<const void *
>(namespace_decl_ctx.
GetTypeSystem()),
2831 return namespace_decl_ctx;
2835 bool resolve_function_context) {
2839 if (type_ptr ==
nullptr) {
2841 if (
auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.
GetCU()))
2848 while (parent_die !=
nullptr) {
2849 if (parent_die->
Tag() == DW_TAG_subprogram)
2854 if (resolve_function_context && parent_die !=
nullptr &&
2861 type_sp = type_ptr->shared_from_this();
2876 if (orig_die != die) {
2877 switch (die.
Tag()) {
2878 case DW_TAG_compile_unit:
2879 case DW_TAG_partial_unit:
2880 case DW_TAG_namespace:
2881 case DW_TAG_structure_type:
2882 case DW_TAG_union_type:
2883 case DW_TAG_class_type:
2884 case DW_TAG_lexical_block:
2885 case DW_TAG_subprogram:
2887 case DW_TAG_inlined_subroutine: {
2903 return decl_ctx_die;
2910 return decl_ctx_die;
2920 Symbol *objc_class_symbol =
nullptr;
2929 return objc_class_symbol;
2942 m_index->GetCompleteObjCClass(
2943 type_name, must_be_implementation, [&](
DWARFDIE type_die) {
2949 if (must_be_implementation) {
2951 DW_AT_APPLE_objc_complete_type, 0);
2952 if (!try_resolving_type)
2961 "resolved 0x%8.8" PRIx64
" from %s to 0x%8.8" PRIx64
2962 " (cu 0x%8.8" PRIx64
")\n",
2964 m_objfile_sp->GetFileSpec().GetFilename().AsCString(
"<Unknown>"),
2965 type_die.
GetID(), type_cu->GetID());
2969 type_sp = resolved_type->shared_from_this();
2977 const char *name = die.
GetName();
2984 "Searching definition DIE in {0}: '{1}'",
2985 GetObjectFile()->GetFileSpec().GetFilename().GetString(), name));
2993 "SymbolFileDWARF::FindDefinitionDIE(tag={0} "
2994 "({1}), name='{2}')",
3005 if (
auto err = type_system_or_err.takeError()) {
3007 "Cannot get TypeSystem for language {1}: {0}",
3010 type_system = *type_system_or_err;
3016 std::vector<std::string> template_params;
3019 type_system ? type_system->GetDWARFParser() :
nullptr;
3020 for (
DWARFDIE ctx_die = die; ctx_die && !isUnitType(ctx_die.Tag());
3021 ctx_die = ctx_die.GetParentDeclContextDIE()) {
3023 template_params.push_back(
3024 (ctx_die.IsStructUnionOrClass() && dwarf_ast)
3028 const bool any_template_params = llvm::any_of(
3029 template_params, [](llvm::StringRef p) {
return !p.empty(); });
3031 auto die_matches = [&](
DWARFDIE type_die) {
3033 const bool tag_matches =
3034 type_die.Tag() == tag ||
3038 if (any_template_params) {
3040 for (
DWARFDIE ctx_die = type_die; ctx_die && !isUnitType(ctx_die.Tag()) &&
3041 pos < template_params.size();
3043 if (template_params[pos].empty())
3045 if (template_params[pos] !=
3049 if (pos != template_params.size())
3055 m_index->GetFullyQualifiedType(die_dwarf_decl_ctx, [&](
DWARFDIE type_die) {
3063 if (!die_matches(type_die)) {
3067 "SymbolFileDWARF::FindDefinitionDIE(tag={0} ({1}), "
3068 "name='{2}') ignoring die={3:x16} ({4})",
3079 "SymbolFileDWARF::FindDefinitionTypeDIE(tag={0} ({1}), name='{2}') "
3080 "trying die={3:x16} ({4})",
3092 bool *type_is_new_ptr) {
3097 if (
auto err = type_system_or_err.takeError()) {
3099 "Unable to parse type: {0}");
3102 auto ts = *type_system_or_err;
3112 if (die.
Tag() == DW_TAG_subprogram) {
3116 if (scope_qualified_name.size()) {
3128 bool parse_siblings,
bool parse_children) {
3129 size_t types_added = 0;
3134 bool type_is_new =
false;
3136 Tag dwarf_tag =
static_cast<Tag
>(tag);
3141 if (isType(dwarf_tag) && tag != DW_TAG_subrange_type)
3148 if (die.
Tag() == DW_TAG_subprogram) {
3173 size_t functions_added = 0;
3180 if (llvm::Expected<llvm::DWARFAddressRangesVector> ranges =
3181 function_die.
GetDIE()->GetAttributeAddressRanges(
3182 function_die.
GetCU(),
3184 if (ranges->empty())
3187 dw_addr_t function_file_addr = llvm::min_element(*ranges)->LowPC;
3197 return functions_added;
3202 size_t types_added = 0;
3223 if (llvm::Expected<llvm::DWARFAddressRangesVector> ranges =
3224 function_die.
GetDIE()->GetAttributeAddressRanges(
3225 function_die.
GetCU(),
true)) {
3227 if (!ranges->empty())
3228 func_lo_pc = llvm::min_element(*ranges)->LowPC;
3231 "DIE({1:x}): {0}", function_die.
GetID());
3234 const size_t num_variables =
3239 return num_variables;
3244 if (dwarf_cu ==
nullptr)
3247 uint32_t vars_added = 0;
3250 if (variables.get() ==
nullptr) {
3251 variables = std::make_shared<VariableList>();
3257 variables->AddVariableIfUnique(var_sp);
3282 die_to_variable[die.
GetDIE()] = var_sp;
3284 die_to_variable[spec_die.GetDIE()] = var_sp;
3293 const addr_t func_low_pc) {
3298 uint64_t block_length = form_value.
Unsigned();
3306 if (form_value.
Form() == DW_FORM_loclistx)
3315 return location_list;
3327 uint64_t block_offset =
3329 uint64_t block_length = form_value.
Unsigned();
3331 module,
DataExtractor(debug_info_data, block_offset, block_length),
3334 if (
const char *str = form_value.
AsCString())
3354 if (!debug_map_objfile)
3358 if (!debug_map_symtab)
3387 if (tag != DW_TAG_variable && tag != DW_TAG_constant &&
3388 tag != DW_TAG_member && (tag != DW_TAG_formal_parameter || !sc.
function))
3392 const char *name =
nullptr;
3393 const char *mangled =
nullptr;
3396 bool is_external =
false;
3397 bool is_artificial =
false;
3401 for (
size_t i = 0; i < attributes.
Size(); ++i) {
3408 case DW_AT_decl_file:
3412 case DW_AT_decl_line:
3415 case DW_AT_decl_column:
3421 case DW_AT_linkage_name:
3422 case DW_AT_MIPS_linkage_name:
3426 type_die_form = form_value;
3428 case DW_AT_external:
3429 is_external = form_value.
Boolean();
3431 case DW_AT_const_value:
3432 const_value_form = form_value;
3434 case DW_AT_location:
3435 location_form = form_value;
3437 case DW_AT_start_scope:
3440 case DW_AT_artificial:
3441 is_artificial = form_value.
Boolean();
3443 case DW_AT_declaration:
3444 case DW_AT_description:
3445 case DW_AT_endianity:
3447 case DW_AT_specification:
3448 case DW_AT_visibility:
3450 case DW_AT_abstract_origin:
3459 bool location_is_const_value_data =
3465 if (const_value_form.
IsValid())
3473 bool is_static_member = (parent_tag == DW_TAG_compile_unit ||
3474 parent_tag == DW_TAG_partial_unit) &&
3475 (parent_context_die.
Tag() == DW_TAG_class_type ||
3476 parent_context_die.
Tag() == DW_TAG_structure_type);
3481 bool has_explicit_mangled = mangled !=
nullptr;
3493 if ((parent_tag == DW_TAG_compile_unit ||
3494 parent_tag == DW_TAG_partial_unit) &&
3501 if (tag == DW_TAG_formal_parameter)
3512 bool has_explicit_location = location_form.
IsValid();
3513 bool is_static_lifetime =
3514 has_explicit_mangled ||
3515 (has_explicit_location && !location_list.
IsValid());
3518 if (!location_is_const_value_data) {
3521 if (
auto maybe_location_DW_OP_addr =
3522 location->GetLocation_DW_OP_addr(location_form.
GetUnit())) {
3523 location_DW_OP_addr = *maybe_location_DW_OP_addr;
3528 "{0:x16}: {1} ({2}) has an invalid location: {3}: {4}",
3530 llvm::fmt_consume(maybe_location_DW_OP_addr.takeError()),
3535 is_static_lifetime =
true;
3538 if (debug_map_symfile)
3544 if (is_static_lifetime) {
3550 if (debug_map_symfile) {
3551 bool linked_oso_file_addr =
false;
3553 if (is_external && location_DW_OP_addr == 0) {
3555 *debug_map_symfile, mangled ? mangled : name, location_list,
3557 linked_oso_file_addr =
true;
3558 symbol_context_scope = exe_symbol;
3562 if (!linked_oso_file_addr) {
3579 if (location_is_const_value_data &&
3580 die.
GetDIE()->IsGlobalOrStaticScopeVariable())
3584 if (debug_map_symfile) {
3589 [
this, debug_map_symfile](
3591 return debug_map_symfile->LinkOSOFileAddress(
3592 this, unlinked_file_addr);
3601 if (symbol_context_scope ==
nullptr) {
3602 switch (parent_tag) {
3603 case DW_TAG_subprogram:
3604 case DW_TAG_inlined_subroutine:
3605 case DW_TAG_lexical_block:
3607 symbol_context_scope =
3609 if (symbol_context_scope ==
nullptr)
3610 symbol_context_scope = sc.
function;
3620 if (!symbol_context_scope) {
3627 auto type_sp = std::make_shared<SymbolFileType>(
3630 bool use_type_size_for_value =
3631 location_is_const_value_data &&
3633 if (use_type_size_for_value && type_sp->GetType()) {
3636 type_sp->GetType()->GetByteSize(
nullptr).value_or(0),
3640 return std::make_shared<Variable>(
3641 die.
GetID(), name, mangled, type_sp, scope, symbol_context_scope,
3642 scope_ranges, &decl, location_list, is_external, is_artificial,
3643 location_is_const_value_data, is_static_member);
3653 spec_block_die_offset);
3660 switch (die.
Tag()) {
3661 case DW_TAG_subprogram:
3662 case DW_TAG_inlined_subroutine:
3663 case DW_TAG_lexical_block: {
3665 spec_block_die_offset)
3669 spec_block_die_offset)
3697 if (tag != DW_TAG_variable && tag != DW_TAG_constant && tag != DW_TAG_member)
3713 switch (parent_tag) {
3714 case DW_TAG_compile_unit:
3715 case DW_TAG_partial_unit:
3720 "parent {0:x8} {1} ({2}) with no valid compile unit in "
3721 "symbol context for {3:x8} {4} ({5}).\n",
3731 "{0} '{1}' ({2:x8}) is not a global variable - ignoring", tag,
3741 if (variable_list_sp)
3742 variable_list_sp->AddVariableIfUnique(var_sp);
3758 if (block_die.
Tag() != DW_TAG_inlined_subroutine) {
3759 return std::move(variable_dies);
3764 if (!abs_die || abs_die.
Tag() != DW_TAG_subprogram ||
3766 return std::move(variable_dies);
3771 DIEArray::iterator concrete_it = variable_dies.begin();
3774 bool did_merge_abstract =
false;
3775 for (; abstract_child; abstract_child = abstract_child.
GetSibling()) {
3776 if (abstract_child.
Tag() == DW_TAG_formal_parameter) {
3777 if (concrete_it == variable_dies.end() ||
3778 GetDIE(*concrete_it).
Tag() != DW_TAG_formal_parameter) {
3782 merged.push_back(*abstract_child.
GetDIERef());
3783 did_merge_abstract =
true;
3789 if (origin_of_concrete == abstract_child) {
3792 merged.push_back(*concrete_it);
3797 merged.push_back(*abstract_child.
GetDIERef());
3798 did_merge_abstract =
true;
3804 if (!did_merge_abstract)
3805 return std::move(variable_dies);
3812 for (; concrete_it != variable_dies.end(); ++concrete_it) {
3813 if (
GetDIE(*concrete_it).
Tag() == DW_TAG_formal_parameter) {
3814 return std::move(variable_dies);
3816 merged.push_back(*concrete_it);
3832 dummy_block_variables);
3842 size_t vars_added = 0;
3845 if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
3846 (tag == DW_TAG_formal_parameter)) {
3847 accumulator.push_back(*die.
GetDIERef());
3851 case DW_TAG_subprogram:
3852 case DW_TAG_inlined_subroutine:
3853 case DW_TAG_lexical_block: {
3857 if (block ==
nullptr) {
3864 if (concrete_block_die)
3869 if (block ==
nullptr)
3872 const bool can_create =
false;
3875 if (block_variable_list_sp.get() ==
nullptr) {
3876 block_variable_list_sp = std::make_shared<VariableList>();
3884 sc, child, func_low_pc, block_variables);
3889 block_variables, func_low_pc);
3898 sc, child, func_low_pc, accumulator);
3908 llvm::ArrayRef<DIERef> variable_dies,
lldb::addr_t func_low_pc) {
3910 for (
auto &die : variable_dies) {
3915 return variable_dies.size();
3923 if (child.Tag() != DW_TAG_call_site_parameter &&
3924 child.Tag() != DW_TAG_GNU_call_site_parameter)
3927 std::optional<DWARFExpressionList> LocationInCallee;
3928 std::optional<DWARFExpressionList> LocationInCaller;
3934 auto parse_simple_location =
3935 [&](
int attr_index) -> std::optional<DWARFExpressionList> {
3941 auto data = child.GetData();
3942 uint64_t block_offset = form_value.
BlockData() - data.GetDataStart();
3943 uint64_t block_length = form_value.
Unsigned();
3949 for (
size_t i = 0; i < attributes.
Size(); ++i) {
3951 if (attr == DW_AT_location)
3952 LocationInCallee = parse_simple_location(i);
3953 if (attr == DW_AT_call_value || attr == DW_AT_GNU_call_site_value)
3954 LocationInCaller = parse_simple_location(i);
3957 if (LocationInCallee && LocationInCaller) {
3959 parameters.push_back(param);
3966std::vector<std::unique_ptr<lldb_private::CallEdge>>
3970 bool has_call_edges =
3973 if (!has_call_edges)
3977 LLDB_LOG(log,
"CollectCallEdges: Found call site info in {0}",
3985 std::vector<std::unique_ptr<CallEdge>> call_edges;
3987 if (child.Tag() != DW_TAG_call_site && child.Tag() != DW_TAG_GNU_call_site)
3990 std::optional<DWARFDIE> call_origin;
3991 std::optional<DWARFExpressionList> call_target;
3995 bool tail_call =
false;
4001 for (
size_t i = 0; i < attributes.
Size(); ++i) {
4004 LLDB_LOG(log,
"CollectCallEdges: Could not extract TAG_call_site form");
4010 if (attr == DW_AT_call_tail_call || attr == DW_AT_GNU_tail_call)
4011 tail_call = form_value.
Boolean();
4014 if (attr == DW_AT_call_origin || attr == DW_AT_abstract_origin) {
4016 if (!call_origin->IsValid()) {
4017 LLDB_LOG(log,
"CollectCallEdges: Invalid call origin in {0}",
4023 if (attr == DW_AT_low_pc)
4024 low_pc = form_value.
Address();
4029 if (attr == DW_AT_call_return_pc)
4030 return_pc = form_value.
Address();
4035 if (attr == DW_AT_call_pc)
4036 call_inst_pc = form_value.
Address();
4040 if (attr == DW_AT_call_target || attr == DW_AT_GNU_call_site_target) {
4043 "CollectCallEdges: AT_call_target does not have block form");
4047 auto data = child.GetData();
4048 uint64_t block_offset = form_value.
BlockData() - data.GetDataStart();
4049 uint64_t block_length = form_value.
Unsigned();
4055 if (!call_origin && !call_target) {
4056 LLDB_LOG(log,
"CollectCallEdges: call site without any call target");
4063 caller_address = return_pc;
4066 caller_address = low_pc;
4069 caller_address = call_inst_pc;
4072 LLDB_LOG(log,
"CollectCallEdges: No caller address");
4084 std::unique_ptr<CallEdge> edge;
4087 "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x}) "
4089 call_origin->GetPubname(), return_pc, call_inst_pc);
4090 edge = std::make_unique<DirectCallEdge>(
4091 call_origin->GetMangledName(), caller_address_type, caller_address,
4092 tail_call, std::move(parameters));
4098 LLDB_LOG(log,
"CollectCallEdges: Found indirect call target: {0}",
4101 edge = std::make_unique<IndirectCallEdge>(
4102 *call_target, caller_address_type, caller_address, tail_call,
4103 std::move(parameters));
4106 if (log && parameters.size()) {
4109 param.LocationInCallee.GetDescription(&callee_loc_desc,
4111 param.LocationInCaller.GetDescription(&caller_loc_desc,
4113 LLDB_LOG(log,
"CollectCallEdges: \tparam: {0} => {1}",
4118 call_edges.push_back(std::move(edge));
4123std::vector<std::unique_ptr<lldb_private::CallEdge>>
4145 auto ts = *ts_or_err;
4157 for (
size_t cu_idx = 0; cu_idx < num_cus; cu_idx++) {
4160 if (dwarf_cu ==
nullptr)
4165 if (!dwarf_cu->
GetDWOId().has_value())
4169 std::make_shared<StructuredData::Dictionary>();
4170 const uint64_t dwo_id = dwarf_cu->
GetDWOId().value();
4171 dwo_data->AddIntegerItem(
"dwo_id", dwo_id);
4176 dwo_data->AddStringItem(
"dwo_name", dwo_name);
4178 dwo_data->AddStringItem(
"error",
"missing dwo name");
4181 const char *comp_dir = die.GetDIE()->GetAttributeValueAsString(
4182 dwarf_cu, DW_AT_comp_dir,
nullptr);
4184 dwo_data->AddStringItem(
"comp_dir", comp_dir);
4187 dwo_data->AddStringItem(
4189 llvm::formatv(
"unable to get unit DIE for DWARFUnit at {0:x}",
4198 dwo_data->AddStringItem(
4199 "resolved_dwo_path",
4202 dwo_data->AddStringItem(
"error",
4205 dwo_data->AddBooleanItem(
"loaded", dwo_symfile !=
nullptr);
4206 if (!errors_only || dwo_data->HasKey(
"error"))
4207 separate_debug_info_files.
AddItem(dwo_data);
4212 d.
AddItem(
"separate-debug-info-files",
4213 std::make_shared<StructuredData::Array>(
4214 std::move(separate_debug_info_files)));
4223 module_sp->GetSymbolFile()->GetBackingSymbolFile());
4235 symfiles.
Append(module_fspec);
4241 if (symfile_fspec != module_fspec) {
4242 symfiles.
Append(symfile_fspec);
4249 if (filename_no_ext != module_fspec.
GetFilename()) {
4250 FileSpec module_spec_no_ext(module_fspec);
4252 symfiles.
Append(module_spec_no_ext);
4260 for (
const auto &symfile : symfiles.
files()) {
4262 FileSpec(symfile.GetPath() +
".dwp", symfile.GetPathStyle());
4263 LLDB_LOG(log,
"Searching for DWP using: \"{0}\"",
4272 LLDB_LOG(log,
"No DWP file found locally");
4281 LLDB_LOG(log,
"Found DWP file: \"{0}\"", dwp_filespec);
4287 dwp_file_data_offset);
4294 LLDB_LOG(log,
"Unable to locate for DWP file for: \"{0}\"",
4301llvm::Expected<lldb::TypeSystemSP>
4308 if (
auto err = type_system_or_err.takeError()) {
4310 "Unable to get DWARFASTParser: {0}");
4313 if (
auto ts = *type_system_or_err)
4314 return ts->GetDWARFParser();
4320 return dwarf_ast->GetDeclForUIDFromDWARF(die);
4326 return dwarf_ast->GetDeclContextForUIDFromDWARF(die);
4333 return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
4341 case DW_LANG_Mips_Assembler:
4354 if (llvm::dwarf::isCPlusPlus(lang))
4355 lang = DW_LANG_C_plus_plus;
4361 return m_index->GetIndexTime();
4368 return m_index->ResetStatistics();
4386 if (dwo_error.
Fail())
4387 return dwo_error.
Clone();
4396 if (dwarf_cu->
HasAny({DW_TAG_variable, DW_TAG_formal_parameter}))
4400 "no variable information is available in debug info for this "
4405 std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) {
4409 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
4426 args.insert({comp_unit,
Args(flags)});
static llvm::raw_ostream & error(Stream &strm)
#define DEBUG_PRINTF(fmt,...)
static PluginProperties & GetGlobalPluginProperties()
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
#define LLDB_LOG_ERROR(log, error,...)
#define LLDB_PLUGIN_DEFINE(PluginName)
static double elapsed(const StatsTimepoint &start, const StatsTimepoint &end)
static PluginProperties & GetGlobalPluginProperties()
static bool UpdateCompilerContextForSimpleTemplateNames(TypeQuery &match)
static ConstString GetDWARFMachOSegmentName()
static DWARFExpressionList GetExprListFromAtConstValue(DWARFFormValue form_value, ModuleSP module, const DWARFDIE &die)
Creates a DWARFExpressionList from an DW_AT_const_value.
static void ParseSupportFilesFromPrologue(SupportFileList &support_files, const lldb::ModuleSP &module, const llvm::DWARFDebugLine::Prologue &prologue, FileSpec::Style style, llvm::StringRef compile_dir={})
static CallSiteParameterArray CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die)
Collect call site parameters in a DW_TAG_call_site DIE.
static void MakeAbsoluteAndRemap(FileSpec &file_spec, DWARFUnit &dwarf_cu, const ModuleSP &module_sp)
Make an absolute path out of file_spec and remap it using the module's source remapping dictionary.
static const llvm::DWARFDebugLine::LineTable * ParseLLVMLineTable(DWARFContext &context, llvm::DWARFDebugLine &line, dw_offset_t line_offset, dw_offset_t unit_offset)
bool IsStructOrClassTag(llvm::dwarf::Tag Tag)
static bool SplitTemplateParams(llvm::StringRef fullname, llvm::StringRef &basename, llvm::StringRef &template_params)
Split a name up into a basename and template parameters.
static Symbol * fixupExternalAddrZeroVariable(SymbolFileDWARFDebugMap &debug_map_symfile, llvm::StringRef name, DWARFExpressionList &expr_list, const DWARFDIE &die)
Global variables that are not initialized may have their address set to zero.
static std::optional< uint64_t > GetDWOId(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die)
Return the DW_AT_(GNU_)dwo_id.
static std::set< dw_form_t > GetUnsupportedForms(llvm::DWARFDebugAbbrev *debug_abbrev)
static std::optional< std::string > GetFileByIndex(const llvm::DWARFDebugLine::Prologue &prologue, size_t idx, llvm::StringRef compile_dir, FileSpec::Style style)
static DWARFExpressionList GetExprListFromAtLocation(DWARFFormValue form_value, ModuleSP module, const DWARFDIE &die, const addr_t func_low_pc)
Creates a DWARFExpressionList from an DW_AT_location form_value.
static bool ParseLLVMLineTablePrologue(DWARFContext &context, llvm::DWARFDebugLine::Prologue &prologue, dw_offset_t line_offset, dw_offset_t unit_offset)
static const char * GetDWOName(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die)
Return the DW_AT_(GNU_)dwo_name.
#define DIE_IS_BEING_PARSED
#define ASSERT_MODULE_LOCK(expr)
#define LLDB_SCOPED_TIMER()
#define LLDB_SCOPED_TIMERF(...)
lldb_private::ClangASTImporter & GetClangASTImporter()
void MapDeclDIEToDefDIE(const lldb_private::plugin::dwarf::DWARFDIE &decl_die, const lldb_private::plugin::dwarf::DWARFDIE &def_die)
Address & GetBaseAddress()
Get accessor for the base address of the range.
A section + offset based address class.
lldb::SectionSP GetSection() const
Get const accessor for the section.
void Clear()
Clear the object's state.
lldb::addr_t GetFileAddress() const
Get the file address.
lldb::addr_t GetOffset() const
Get the section relative offset value.
bool IsValid() const
Check if the object state is valid.
A command line argument class.
A class that describes a single lexical block.
lldb::VariableListSP GetBlockVariableList(bool can_create)
Get the variable list for this block only.
lldb::BlockSP CreateChild(lldb::user_id_t uid)
Creates a block with the specified UID uid.
Block * FindBlockByID(lldb::user_id_t block_id)
void SetVariableList(lldb::VariableListSP &variable_list_sp)
Set accessor for the variable list.
bool GetStartAddress(Address &addr)
void SetDidParseVariables(bool b, bool set_children)
void AddRange(const Range &range)
Add a new offset range to this block.
void SetInlinedFunctionInfo(const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr)
Set accessor for any inlined function information.
static bool ExtractContextAndIdentifier(const char *name, llvm::StringRef &context, llvm::StringRef &identifier)
Checksum(llvm::MD5::MD5Result md5=g_sentinel)
bool CanImport(const CompilerType &type)
Returns true iff the given type was copied from another TypeSystemClang and the original type in this...
bool CompleteType(const CompilerType &compiler_type)
static bool LanguageSupportsClangModules(lldb::LanguageType language)
Query whether Clang supports modules for a particular language.
A class that describes a compilation unit.
void SetVariableList(lldb::VariableListSP &variable_list_sp)
Set accessor for the variable list.
const SupportFileList & GetSupportFiles()
Get the compile unit's support file list.
lldb::VariableListSP GetVariableList(bool can_create)
Get the variable list for a compile unit.
void SetDebugMacros(const DebugMacrosSP &debug_macros)
const FileSpec & GetPrimaryFile() const
Return the primary source spec associated with this compile unit.
void ResolveSymbolContext(const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list, RealpathPrefixes *realpath_prefixes=nullptr)
Resolve symbol contexts by file and line.
void SetLineTable(LineTable *line_table)
Set the line table for the compile unit.
lldb::FunctionSP FindFunctionByUID(lldb::user_id_t uid)
Finds a function by user ID.
lldb::LanguageType GetLanguage()
LineTable * GetLineTable()
Get the line table for the compile unit.
Represents a generic declaration context in a program.
ConstString GetScopeQualifiedName() const
ConstString GetName() const
bool IsContainedInLookup(CompilerDeclContext other) const
Check if the given other decl context is contained in the lookup of this decl context (for example be...
TypeSystem * GetTypeSystem() const
void * GetOpaqueDeclContext() const
Represents a generic declaration such as a function declaration.
std::shared_ptr< TypeSystemType > dyn_cast_or_null()
Return a shared_ptr<TypeSystemType> if dyn_cast succeeds.
Generic representation of a type in a programming language.
TypeSystemSPWrapper GetTypeSystem() const
Accessors.
lldb::opaque_compiler_type_t GetOpaqueQualType() const
A uniqued constant string class.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
bool IsEmpty() const
Test for empty string.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
"lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file address range to a single ...
llvm::Expected< Value > Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::addr_t func_load_addr, const Value *initial_value_ptr, const Value *object_address_ptr) const
bool ContainsThreadLocalStorage() const
const DWARFExpression * GetAlwaysValidExpr() const
void SetModule(const lldb::ModuleSP &module)
bool IsValid() const
Return true if the location expression contains data.
void SetFuncFileAddress(lldb::addr_t func_file_addr)
bool LinkThreadLocalStorage(lldb::ModuleSP new_module_sp, std::function< lldb::addr_t(lldb::addr_t file_addr)> const &link_address_callback)
DWARFExpression * GetMutableExpressionAtAddress(lldb::addr_t func_load_addr=LLDB_INVALID_ADDRESS, lldb::addr_t load_addr=0)
"lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location expression and interprets it.
bool Update_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu, lldb::addr_t file_addr)
void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size, uint8_t addr_byte_size)
static bool ParseDWARFLocationList(const plugin::dwarf::DWARFUnit *dwarf_cu, const DataExtractor &data, DWARFExpressionList *loc_list)
A class to manage flag bits.
A class that describes the declaration location of a lldb object.
void SetLine(uint32_t line)
Set accessor for the declaration line number.
void SetColumn(uint16_t column)
Set accessor for the declaration column number.
void SetFile(const FileSpec &file_spec)
Set accessor for the declaration file specification.
A class that measures elapsed time in an exception safe way.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
llvm::iterator_range< const_iterator > files() const
const FileSpec & GetFileSpecAtIndex(size_t idx) const
Get file at index.
void Append(const FileSpec &file)
Append a FileSpec object to the list.
size_t GetSize() const
Get the number of files in the file list.
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
void AppendPathComponent(llvm::StringRef component)
static bool Match(const FileSpec &pattern, const FileSpec &file)
Match FileSpec pattern against FileSpec file.
bool IsRelative() const
Returns true if the filespec represents a relative path.
const ConstString & GetFilename() const
Filename string const get accessor.
void MakeAbsolute(const FileSpec &dir)
Make the FileSpec absolute by treating it relative to dir.
void SetPath(llvm::StringRef p)
Temporary helper for FileSystem change.
ConstString GetFileNameStrippingExtension() const
Return the filename without the extension part.
void PrependPathComponent(llvm::StringRef component)
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
llvm::sys::path::Style Style
void SetFilename(ConstString filename)
Filename string set accessor.
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
static FileSystem & Instance()
A class that describes a function.
const AddressRange & GetAddressRange()
DEPRECATED: Use GetAddressRanges instead.
lldb::ModuleSP CalculateSymbolContextModule() override
CompileUnit * GetCompileUnit()
Get accessor for the compile unit that owns this function.
Block & GetBlock(bool can_create)
Get accessor for the block list.
static const char * GetNameForLanguageType(lldb::LanguageType language)
static bool LanguageIsCPlusPlus(lldb::LanguageType language)
static std::unique_ptr< LineSequence > CreateLineSequenceContainer()
bool FindLineEntryByAddress(const Address &so_addr, LineEntry &line_entry, uint32_t *index_ptr=nullptr)
Find a line entry that contains the section offset address so_addr.
static void AppendLineEntryToSequence(LineSequence *sequence, lldb::addr_t file_addr, uint32_t line, uint16_t column, uint16_t file_idx, bool is_start_of_statement, bool is_start_of_basic_block, bool is_prologue_end, bool is_epilogue_begin, bool is_terminal_entry)
static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef const name)
Try to identify the mangling scheme used.
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
static Status GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl< lldb::ModuleSP > *old_modules, bool *did_create_ptr, bool always_create=false)
ArchSpec & GetArchitecture()
FileSpec & GetSymbolFileSpec()
A class that encapsulates name lookup information.
lldb::FunctionNameType GetNameTypeMask() const
void SetLookupName(ConstString name)
ConstString GetLookupName() const
A class that describes an executable image and its associated object and symbol files.
A plug-in interface definition class for object file parsers.
static lldb::ObjectFileSP FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file_spec, lldb::offset_t file_offset, lldb::offset_t file_size, lldb::DataBufferSP &data_sp, lldb::offset_t &data_offset)
Find a ObjectFile plug-in that can parse file_spec.
Symtab * GetSymtab()
Gets the symbol table for the currently selected architecture (and object for archives).
@ eTypeDebugInfo
An object file that contains only debug information.
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool CreateSettingForSymbolFilePlugin(Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, llvm::StringRef description, bool is_global_property)
static lldb::OptionValuePropertiesSP GetSettingForSymbolFilePlugin(Debugger &debugger, llvm::StringRef setting_name)
static FileSpec LocateExecutableSymbolFile(const ModuleSpec &module_spec, const FileSpecList &default_search_paths)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A Progress indicator helper class.
RangeData< B, S, T > Entry
llvm::StringRef GetText() const
Access the regular expression text.
lldb::SectionSP FindSectionByName(ConstString section_dstr) const
lldb::SectionSP FindSectionByType(lldb::SectionType sect_type, bool check_children, size_t start_idx=0) const
SectionList & GetChildren()
lldb::offset_t GetFileSize() const
"lldb/Core/SourceLocationSpec.h" A source location specifier class.
bool GetCheckInlines() const
FileSpec GetFileSpec() const
This base class provides an interface to stack frames.
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
std::chrono::duration< double > Duration
Status Clone() const
Don't call this function in new code.
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
void AddItem(const ObjectSP &item)
void AddStringItem(llvm::StringRef key, llvm::StringRef value)
void AddItem(llvm::StringRef key, ObjectSP value_sp)
std::shared_ptr< Dictionary > DictionarySP
A list of support files for a CompileUnit.
const FileSpec & GetFileSpecAtIndex(size_t idx) const
void Append(const FileSpec &file)
lldb::SupportFileSP GetSupportFileAtIndex(size_t idx) const
void EmplaceBack(Args &&...args)
Wraps a FileSpec and an optional Checksum.
virtual const FileSpec & Materialize()
Materialize the file to disk and return the path to that temporary file.
Defines a list of symbol context objects.
uint32_t GetSize() const
Get accessor for a symbol context list size.
void Append(const SymbolContext &sc)
Append a new symbol context to the list.
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
virtual CompileUnit * CalculateSymbolContextCompileUnit()