11#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
12#include "llvm/Support/Casting.h"
13#include "llvm/Support/FileUtilities.h"
14#include "llvm/Support/Format.h"
15#include "llvm/Support/Threading.h"
77#include "llvm/DebugInfo/DWARF/DWARFContext.h"
78#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
79#include "llvm/Support/FileSystem.h"
80#include "llvm/Support/FormatVariadic.h"
92#ifdef ENABLE_DEBUG_PRINTF
94#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
96#define DEBUG_PRINTF(fmt, ...)
110#define LLDB_PROPERTIES_symbolfiledwarf
111#include "SymbolFileDWARFProperties.inc"
114#define LLDB_PROPERTIES_symbolfiledwarf
115#include "SymbolFileDWARFPropertiesEnum.inc"
120 static llvm::StringRef GetSettingName() {
125 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
126 m_collection_sp->Initialize(g_symbolfiledwarf_properties);
129 bool IgnoreFileIndexes()
const {
130 return GetPropertyAtIndexAs<bool>(ePropertyIgnoreIndexes,
false);
137 return Tag == llvm::dwarf::Tag::DW_TAG_class_type ||
138 Tag == llvm::dwarf::Tag::DW_TAG_structure_type;
142 static PluginProperties g_settings;
146static const llvm::DWARFDebugLine::LineTable *
152 llvm::DWARFContext &ctx = context.
GetAsLLVM();
153 llvm::Expected<const llvm::DWARFDebugLine::LineTable *> line_table =
154 line.getOrParseLineTable(
155 data, line_offset, ctx,
nullptr, [&](llvm::Error e) {
158 "SymbolFileDWARF::ParseLineTable failed to parse: {0}");
163 "SymbolFileDWARF::ParseLineTable failed to parse: {0}");
170 llvm::DWARFDebugLine::Prologue &prologue,
176 llvm::DWARFContext &ctx = context.
GetAsLLVM();
177 uint64_t offset = line_offset;
178 llvm::Error
error = prologue.parse(
183 "SymbolFileDWARF::ParseSupportFiles failed to parse "
184 "line table prologue: {0}");
189 "SymbolFileDWARF::ParseSupportFiles failed to parse line "
190 "table prologue: {0}");
196static std::optional<std::string>
200 std::string abs_path;
201 auto absolute = llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath;
202 if (prologue.getFileNameByIndex(idx, compile_dir, absolute, abs_path, style))
203 return std::move(abs_path);
206 std::string rel_path;
207 auto relative = llvm::DILineInfoSpecifier::FileLineInfoKind::RawValue;
208 if (!prologue.getFileNameByIndex(idx, compile_dir, relative, rel_path, style))
210 return std::move(rel_path);
216 llvm::StringRef compile_dir = {}) {
219 if (prologue.FileNames.empty())
223 const bool is_one_based = prologue.getVersion() < 5;
224 const size_t file_names = prologue.FileNames.size();
225 const size_t first_file_idx = is_one_based ? 1 : 0;
226 const size_t last_file_idx = is_one_based ? file_names : file_names - 1;
233 for (
size_t idx = first_file_idx; idx <= last_file_idx; ++idx) {
234 std::string remapped_file;
235 if (
auto file_path =
GetFileByIndex(prologue, idx, compile_dir, style)) {
236 auto entry = prologue.getFileNameEntry(idx);
237 auto source = entry.Source.getAsCString();
239 consumeError(source.takeError());
241 llvm::StringRef source_ref(*source);
242 if (!source_ref.empty()) {
246 LazyDWARFSourceFile(
const FileSpec &fs, llvm::StringRef source,
251 llvm::StringRef source;
253 std::unique_ptr<llvm::FileRemover> remover;
260 llvm::SmallString<0> name;
263 auto ec = llvm::sys::fs::createTemporaryFile(
264 "", llvm::sys::path::filename(orig_name, style), fd, name);
267 "Could not create temporary file");
270 remover = std::make_unique<llvm::FileRemover>(name);
272 size_t num_bytes = source.size();
273 file.Write(source.data(), num_bytes);
278 support_files.
Append(std::make_unique<LazyDWARFSourceFile>(
279 FileSpec(*file_path), *source, style));
283 if (
auto remapped = module->RemapSourceFile(llvm::StringRef(*file_path)))
284 remapped_file = *remapped;
286 remapped_file = std::move(*file_path);
290 if (prologue.ContentTypes.HasMD5) {
291 const llvm::DWARFDebugLine::FileNameEntry &file_name_entry =
292 prologue.getFileNameEntry(idx);
293 checksum = file_name_entry.
Checksum;
311 debugger, PluginProperties::GetSettingName())) {
312 const bool is_global_setting =
true;
315 "Properties for the dwarf symbol-file plug-in.", is_global_setting);
326 return "DWARF and DWARF3 debug symbol file reader.";
337 return debug_map_symfile->GetTypeList();
346 if (die_offset >= max_die_offset)
349 if (die_offset >= min_die_offset) {
352 bool add_type =
false;
355 case DW_TAG_array_type:
356 add_type = (type_mask & eTypeClassArray) != 0;
358 case DW_TAG_unspecified_type:
359 case DW_TAG_base_type:
360 add_type = (type_mask & eTypeClassBuiltin) != 0;
362 case DW_TAG_class_type:
363 add_type = (type_mask & eTypeClassClass) != 0;
365 case DW_TAG_structure_type:
366 add_type = (type_mask & eTypeClassStruct) != 0;
368 case DW_TAG_union_type:
369 add_type = (type_mask & eTypeClassUnion) != 0;
371 case DW_TAG_enumeration_type:
372 add_type = (type_mask & eTypeClassEnumeration) != 0;
374 case DW_TAG_subroutine_type:
375 case DW_TAG_subprogram:
376 case DW_TAG_inlined_subroutine:
377 add_type = (type_mask & eTypeClassFunction) != 0;
379 case DW_TAG_pointer_type:
380 add_type = (type_mask & eTypeClassPointer) != 0;
382 case DW_TAG_rvalue_reference_type:
383 case DW_TAG_reference_type:
384 add_type = (type_mask & eTypeClassReference) != 0;
387 add_type = (type_mask & eTypeClassTypedef) != 0;
389 case DW_TAG_ptr_to_member_type:
390 add_type = (type_mask & eTypeClassMemberPointer) != 0;
397 const bool assert_not_being_parsed =
true;
400 type_set.insert(type);
405 GetTypes(child_die, min_die_offset, max_die_offset, type_mask, type_set);
411 TypeClass type_mask,
TypeList &type_list)
424 unit = &unit->GetNonSkeletonUnit();
425 GetTypes(unit->DIE(), unit->GetOffset(), unit->GetNextUnitOffset(),
426 type_mask, type_set);
433 for (
size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx)
437 std::set<CompilerType> compiler_type_set;
438 for (
Type *type : type_set) {
439 CompilerType compiler_type = type->GetForwardCompilerType();
440 if (compiler_type_set.find(compiler_type) == compiler_type_set.end()) {
441 compiler_type_set.insert(compiler_type);
442 type_list.
Insert(type->shared_from_this());
456 case DW_TAG_compile_unit:
457 case DW_TAG_partial_unit:
458 case DW_TAG_subprogram:
459 case DW_TAG_inlined_subroutine:
460 case DW_TAG_lexical_block:
472 m_debug_map_symfile(nullptr),
473 m_context(m_objfile_sp->GetModule()->GetSectionList(), dwo_section_list),
474 m_fetched_external_modules(false),
480 static ConstString g_dwarf_section_name(
"__DWARF");
481 return g_dwarf_section_name;
486 if (debug_map_symfile)
492llvm::Expected<lldb::TypeSystemSP>
495 return debug_map_symfile->GetTypeSystemForLanguage(language);
497 auto type_system_or_err =
498 m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
499 if (type_system_or_err)
500 if (
auto ts = *type_system_or_err)
501 ts->SetSymbolFile(
this);
502 return type_system_or_err;
523 *
GetObjectFile()->GetModule(), apple_names, apple_namespaces,
534 llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or =
539 m_index = std::move(*index_or);
543 "Unable to read .debug_names data: {0}");
548 std::make_unique<ManualDWARFIndex>(*
GetObjectFile()->GetModule(), *
this);
560 for (
SectionSP section_sp : section_list) {
561 if (section_sp->GetChildren().GetSize() > 0) {
571 return version >= 2 && version <= 5;
574static std::set<dw_form_t>
579 std::set<dw_form_t> unsupported_forms;
580 for (
const auto &[_, decl_set] : *debug_abbrev)
581 for (
const auto &decl : decl_set)
582 for (
const auto &attr : decl.attributes())
584 unsupported_forms.insert(attr.Form);
586 return unsupported_forms;
590 uint32_t abilities = 0;
592 const Section *section =
nullptr;
594 if (section_list ==
nullptr)
597 uint64_t debug_abbrev_file_size = 0;
598 uint64_t debug_info_file_size = 0;
599 uint64_t debug_line_file_size = 0;
608 if (section !=
nullptr) {
619 if (!unsupported_forms.empty()) {
621 error.Printf(
"unsupported DW_FORM value%s:",
622 unsupported_forms.size() > 1 ?
"s" :
"");
623 for (
auto form : unsupported_forms)
624 error.Printf(
" %#x", form);
635 llvm::StringRef symfile_dir =
636 m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef();
637 if (symfile_dir.contains_insensitive(
".dsym")) {
648 "empty dSYM file detected, dSYM was created with an "
649 "executable with no debug info.");
656 if (debug_info_file_size >= MaxDebugInfoSize) {
658 "SymbolFileDWARF can't load this DWARF. It's larger then {0:x+16}",
663 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
667 if (debug_line_file_size > 0)
676 const SectionList *section_list = module_sp->GetSectionList();
698 std::make_unique<llvm::DWARFDebugAbbrev>(debug_abbrev_data.
GetAsLLVM());
699 llvm::Error
error = abbr->parse();
703 "Unable to read .debug_abbrev section: {0}");
714 static_cast<void *
>(
this));
730 return llvm::cast_or_null<DWARFCompileUnit>(dwarf_cu);
736 static_cast<void *
>(
this));
739 m_ranges = std::make_unique<DWARFDebugRanges>();
758 if (
auto remapped_file = module_sp->RemapSourceFile(file_spec.
GetPath()))
759 file_spec.
SetFile(*remapped_file, FileSpec::Style::native);
765 const char *dwo_name =
778 cu_sp = comp_unit->shared_from_this();
791 cu_sp = std::make_shared<CompileUnit>(
792 module_sp, &dwarf_cu, support_file_sp,
801 auto lazy_initialize_cu = [&]() {
823 if (support_files.
GetSize() == 0)
830 if (!lazy_initialize_cu()) {
844 initialize_cu(std::make_shared<SupportFile>(cu_file_spec),
863 for (uint32_t i = 0, num = info.
GetNumUnits(); i < num; ++i) {
864 if (
auto *cu = llvm::dyn_cast<DWARFCompileUnit>(info.
GetUnitAtIndex(i))) {
889 if (
auto *dwarf_cu = llvm::cast_or_null<DWARFCompileUnit>(
903 if (
auto err = type_system_or_err.takeError()) {
905 "Unable to parse function: {0}");
908 auto ts = *type_system_or_err;
925 lowest_func_addr >= highest_func_addr ||
932 lowest_func_addr, module_sp->GetSectionList());
936 func_range.
SetByteSize(highest_func_addr - lowest_func_addr);
951 if (
auto err = type_system_or_err.takeError()) {
953 "Unable to construct demangled name for function: {0}");
957 auto ts = *type_system_or_err;
971 if (debug_map_symfile)
978 if (debug_map_symfile) {
1004 const char *sysroot =
1012 module_sp->RegisterXcodeSDK(sdk, sysroot);
1015 if (local_module_sp && local_module_sp != module_sp)
1016 local_module_sp->RegisterXcodeSDK(sdk, sysroot);
1028 size_t functions_added = 0;
1031 if (entry.Tag() != DW_TAG_subprogram)
1041 return functions_added;
1046 llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files,
1047 llvm::function_ref<
bool(
Module &)> lambda) {
1049 if (!visited_symbol_files.insert(
this).second)
1059 if (lambda(*module))
1062 for (std::size_t i = 0; i < module->GetNumCompileUnits(); ++i) {
1063 auto cu = module->GetCompileUnitAtIndex(i);
1064 bool early_exit = cu->ForEachExternalModule(visited_symbol_files, lambda);
1094 llvm::DWARFDebugLine::Prologue prologue;
1106 if (
auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(&unit)) {
1108 return lldb_cu->GetSupportFiles().GetFileSpecAtIndex(file_idx);
1112 auto &tu = llvm::cast<DWARFTypeUnit>(unit);
1124 offset == llvm::DenseMapInfo<dw_offset_t>::getEmptyKey() ||
1125 offset == llvm::DenseMapInfo<dw_offset_t>::getTombstoneKey())
1131 std::unique_ptr<SupportFileList> &list = iter_bool.first->second;
1132 if (iter_bool.second) {
1133 list = std::make_unique<SupportFileList>();
1134 uint64_t line_table_offset = offset;
1135 llvm::DWARFDataExtractor data =
1138 llvm::DWARFDebugLine::Prologue prologue;
1139 auto report = [](llvm::Error
error) {
1142 "SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse "
1143 "the line table prologue: {0}");
1146 llvm::Error
error = prologue.parse(data, &line_table_offset, report, ctx);
1148 report(std::move(
error));
1166 std::vector<SourceModule> &imported_modules) {
1182 if (child_die.Tag() != DW_TAG_imported_declaration)
1186 if (module_die.
Tag() != DW_TAG_module)
1189 if (
const char *name =
1195 while ((parent_die = parent_die.
GetParent())) {
1196 if (parent_die.
Tag() != DW_TAG_module)
1198 if (
const char *name =
1202 std::reverse(module.
path.begin(), module.
path.end());
1204 DW_AT_LLVM_include_path,
nullptr)) {
1211 DW_AT_LLVM_sysroot,
nullptr))
1213 imported_modules.push_back(module);
1233 llvm::DWARFDebugLine line;
1234 const llvm::DWARFDebugLine::LineTable *line_table =
1243 std::vector<std::unique_ptr<LineSequence>> sequences;
1246 for (
const llvm::DWARFDebugLine::Sequence &seq : line_table->Sequences) {
1253 std::unique_ptr<LineSequence> sequence =
1255 for (
unsigned idx = seq.FirstRowIndex; idx < seq.LastRowIndex; ++idx) {
1256 const llvm::DWARFDebugLine::Row &row = line_table->Rows[idx];
1258 sequence.get(), row.Address.Address, row.Line, row.Column, row.File,
1259 row.IsStmt, row.BasicBlock, row.PrologueEnd, row.EpilogueBegin,
1262 sequences.push_back(std::move(sequence));
1265 std::unique_ptr<LineTable> line_table_up =
1266 std::make_unique<LineTable>(&comp_unit, std::move(sequences));
1273 debug_map_symfile->LinkOSOLineTable(
this, line_table_up.get()));
1285 return iter->second;
1299 offset,
this, debug_macros_sp);
1301 return debug_macros_sp;
1308 if (dwarf_cu ==
nullptr)
1330 const DWARFDIE &orig_die,
addr_t subprogram_low_pc, uint32_t depth) {
1331 size_t blocks_added = 0;
1337 case DW_TAG_inlined_subroutine:
1338 case DW_TAG_subprogram:
1339 case DW_TAG_lexical_block: {
1340 Block *block =
nullptr;
1341 if (tag == DW_TAG_subprogram) {
1349 block = parent_block;
1353 block = block_sp.get();
1356 const char *name =
nullptr;
1357 const char *mangled_name =
nullptr;
1359 std::optional<int> decl_file;
1360 std::optional<int> decl_line;
1361 std::optional<int> decl_column;
1362 std::optional<int> call_file;
1363 std::optional<int> call_line;
1364 std::optional<int> call_column;
1366 decl_line, decl_column, call_file, call_line,
1367 call_column,
nullptr)) {
1368 if (tag == DW_TAG_subprogram) {
1371 }
else if (tag == DW_TAG_inlined_subroutine) {
1385 const size_t num_ranges = ranges.
GetSize();
1386 for (
size_t i = 0; i < num_ranges; ++i) {
1389 if (range_base >= subprogram_low_pc)
1394 "{0:x8}: adding range [{1:x16}-{2:x16}) which has a base "
1395 "that is less than the function's low PC {3:x16}. Please file "
1396 "a bug and attach the file at the "
1397 "start of this error message",
1404 if (tag != DW_TAG_subprogram &&
1405 (name !=
nullptr || mangled_name !=
nullptr)) {
1406 std::unique_ptr<Declaration> decl_up;
1407 if (decl_file || decl_line || decl_column)
1408 decl_up = std::make_unique<Declaration>(
1410 decl_file ? *decl_file : 0),
1411 decl_line ? *decl_line : 0, decl_column ? *decl_column : 0);
1413 std::unique_ptr<Declaration> call_up;
1414 if (call_file || call_line || call_column)
1415 call_up = std::make_unique<Declaration>(
1417 call_file ? *call_file : 0),
1418 call_line ? *call_line : 0, call_column ? *call_column : 0);
1429 subprogram_low_pc, depth + 1);
1446 return blocks_added;
1453 bool check_virtuality =
false;
1455 case DW_TAG_inheritance:
1456 case DW_TAG_subprogram:
1457 check_virtuality =
true;
1462 if (check_virtuality) {
1463 if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0)
1473 if (type_system !=
nullptr)
1517std::vector<CompilerContext>
1524 return die.GetDeclContext();
1534 return type_die.ResolveType();
1545 return std::nullopt;
1553 bool assert_not_being_parsed) {
1558 log,
"SymbolFileDWARF::ResolveTypeUID (die = {0:x16}) {1} '{2}'",
1567 switch (decl_ctx_die.
Tag()) {
1568 case DW_TAG_structure_type:
1569 case DW_TAG_union_type:
1570 case DW_TAG_class_type: {
1575 "SymbolFileDWARF::ResolveTypeUID (die = {0:x16}) "
1577 "resolve parent forward type for {3:x16})",
1605 if (!clang_type_system)
1614 auto clang_type_system =
1616 if (clang_type_system) {
1647 log,
"{0:x8}: {1} '{2}' resolving forward declaration...",
1650 assert(compiler_type);
1652 return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type);
1658 bool assert_not_being_parsed,
1659 bool resolve_function_context) {
1663 if (assert_not_being_parsed) {
1668 "Parsing a die that is being parsed die: {0:x16}: {1} {2}",
1697 m_index->GetObjCMethods(class_name, callback);
1703 if (die && llvm::isa<DWARFCompileUnit>(die.
GetCU())) {
1744 std::optional<uint32_t> file_index = die_ref.
file_index();
1747 symbol_file = debug_map->GetSymbolFileByOSOIndex(*file_index);
1764 return symbol_file->
GetDIE(die_ref);
1772 std::optional<uint64_t> dwo_id =
1784 return ::GetDWOId(*cu, *cu_die);
1793std::shared_ptr<SymbolFileDWARFDwo>
1807 if (!dwarf_cu || !dwarf_cu->
GetDWOId().has_value())
1810 const char *dwo_name =
GetDWOName(*dwarf_cu, cu_die);
1813 "missing DWO name in skeleton DIE {0:x16}", cu_die.
GetOffset()));
1826 size_t num_search_paths = debug_file_search_paths.
GetSize();
1832 const char *comp_dir =
1837 dwo_file.
SetFile(comp_dir, FileSpec::Style::native);
1848 FileSpec relative_to_binary = dwo_file;
1850 m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef());
1853 dwo_paths.
Append(relative_to_binary);
1856 for (
size_t idx = 0; idx < num_search_paths; ++idx) {
1864 dwo_paths.
Append(dirspec);
1867 size_t num_possible = dwo_paths.
GetSize();
1868 for (
size_t idx = 0; idx < num_possible && !found; ++idx) {
1871 dwo_file = dwo_spec;
1879 "unable to locate relative .dwo debug file \"%s\" for "
1880 "skeleton DIE 0x%016" PRIx64
" without valid DW_AT_comp_dir "
1891 llvm::StringRef filename_only = dwo_name_spec.
GetFilename();
1894 m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef());
1898 FileSpec dwo_name_binary_directory(binary_directory);
1900 dwo_paths.
Append(dwo_name_binary_directory);
1903 FileSpec filename_binary_directory(binary_directory);
1905 dwo_paths.
Append(filename_binary_directory);
1907 for (
size_t idx = 0; idx < num_search_paths; ++idx) {
1913 FileSpec dwo_name_dirspec(dirspec);
1915 dwo_paths.
Append(dwo_name_dirspec);
1917 FileSpec filename_dirspec(dirspec);
1919 dwo_paths.
Append(filename_dirspec);
1922 size_t num_possible = dwo_paths.
GetSize();
1923 for (
size_t idx = 0; idx < num_possible && !found; ++idx) {
1926 dwo_file = dwo_spec;
1935 if (error_dwo_path.
IsRelative() && comp_dir !=
nullptr) {
1940 "unable to locate .dwo debug file \"{0}\" for skeleton DIE "
1946 "unable to locate separate debug file (dwo, dwp). Debugging will be "
1958 dwo_file_data_offset);
1959 if (dwo_obj_file ==
nullptr) {
1961 "unable to load object file for .dwo debug file \"{0}\" for "
1967 return std::make_shared<SymbolFileDWARFDwo>(*
this, dwo_obj_file,
1979 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
1981 llvm::dyn_cast<DWARFCompileUnit>(debug_info.
GetUnitAtIndex(cu_idx));
2005 const char *comp_dir =
2009 FileSpec::Style::native);
2029 if (
m_objfile_sp->GetFileSpec().GetFileNameExtension() ==
".dwo" &&
2036 nullptr,
nullptr,
nullptr);
2039 "{0:x16}: unable to locate module needed for external types: "
2040 "{1}\nerror: {2}\nDebugging will be degraded due to missing "
2041 "types. Rebuilding the project will regenerate the needed "
2044 error.AsCString(
"unknown error"));
2055 llvm::dyn_cast_or_null<SymbolFileDWARF>(module_sp->GetSymbolFile());
2058 std::optional<uint64_t> dwo_dwo_id = dwo_symfile->GetDWOId();
2062 if (dwo_id != dwo_dwo_id) {
2064 "{0:x16}: Module {1} is out-of-date (hash mismatch). Type "
2066 "from this module may be incomplete or inconsistent with the rest of "
2067 "the program. Rebuilding the project will regenerate the needed "
2080 const size_t num_cus = module_sp->GetNumCompileUnits();
2081 for (
size_t i = 0; i < num_cus; ++i) {
2082 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
2086 const size_t num_globals = globals_sp->GetSize();
2087 for (
size_t g = 0; g < num_globals; ++g) {
2088 VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
2089 if (var_sp && !var_sp->GetLocationIsConstantValueData()) {
2091 var_sp->LocationExpressionList();
2092 Value location_result;
2096 nullptr,
nullptr, location_result,
2103 if (var_sp->GetType())
2105 var_sp->GetType()->GetByteSize(
nullptr).value_or(0);
2107 file_addr, byte_size, var_sp.get()));
2149 SymbolContextItem resolve_scope,
2153 "ResolveSymbolContext (so_addr = { "
2154 "section = %p, offset = 0x%" PRIx64
2155 " }, resolve_scope = 0x%8.8x)",
2156 static_cast<void *
>(so_addr.
GetSection().get()),
2158 uint32_t resolved = 0;
2160 (eSymbolContextCompUnit | eSymbolContextFunction | eSymbolContextBlock |
2161 eSymbolContextLineEntry | eSymbolContextVariable)) {
2173 if (resolve_scope & eSymbolContextVariable) {
2176 map.FindEntryThatContains(file_vm_addr);
2177 if (entry && entry->data) {
2189 if (
auto *dwarf_cu = llvm::dyn_cast_or_null<DWARFCompileUnit>(
2194 resolved |= eSymbolContextCompUnit;
2196 bool force_check_line_table =
false;
2197 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) {
2199 resolve_scope & eSymbolContextBlock, sc);
2201 resolved |= eSymbolContextFunction;
2209 force_check_line_table =
true;
2212 resolved |= eSymbolContextBlock;
2215 if ((resolve_scope & eSymbolContextLineEntry) ||
2216 force_check_line_table) {
2218 if (line_table !=
nullptr) {
2228 resolved |= eSymbolContextLineEntry;
2234 if (force_check_line_table && !(resolved & eSymbolContextLineEntry)) {
2241 resolved &= ~eSymbolContextCompUnit;
2245 "{0:x16}: compile unit {1} failed to create a valid "
2246 "lldb_private::CompileUnit class.",
2260 const uint32_t prev_size = sc_list.
GetSize();
2261 if (resolve_scope & eSymbolContextCompUnit) {
2270 if (check_inlines || file_spec_matches_cu_file_spec) {
2277 return sc_list.
GetSize() - prev_size;
2295 return module_sp->GetMutex();
2311 if (
auto err = type_system_or_err.takeError()) {
2313 "Unable to match namespace decl using TypeSystem: {0}");
2317 if (decl_ctx_type_system == type_system_or_err->get())
2325 log,
"Valid namespace does not match symbol file");
2339 "SymbolFileDWARF::FindGlobalVariables (name=\"{0}\", "
2340 "parent_decl_ctx={1:p}, max_matches={2}, variables)",
2341 name.
GetCString(),
static_cast<const void *
>(&parent_decl_ctx),
2348 const uint32_t original_size = variables.
GetSize();
2350 llvm::StringRef basename;
2351 llvm::StringRef context;
2361 uint32_t pruned_idx = original_size;
2369 if (die.
Tag() != DW_TAG_variable)
2372 auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.
GetCU());
2377 if (parent_decl_ctx) {
2380 dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
2386 if (!actual_parent_decl_ctx ||
2387 (actual_parent_decl_ctx != parent_decl_ctx &&
2394 while (pruned_idx < variables.
GetSize()) {
2396 if (name_is_mangled ||
2397 var_sp->GetName().GetStringRef().contains(name.
GetStringRef()))
2403 return variables.
GetSize() - original_size < max_matches;
2407 const uint32_t num_matches = variables.
GetSize() - original_size;
2408 if (log && num_matches > 0) {
2411 "SymbolFileDWARF::FindGlobalVariables (name=\"{0}\", "
2412 "parent_decl_ctx={1:p}, max_matches={2}, variables) => {3}",
2413 name.
GetCString(),
static_cast<const void *
>(&parent_decl_ctx),
2414 max_matches, num_matches);
2419 uint32_t max_matches,
2427 "SymbolFileDWARF::FindGlobalVariables (regex=\"{0}\", "
2428 "max_matches={1}, variables)",
2429 regex.
GetText().str().c_str(), max_matches);
2433 const uint32_t original_size = variables.
GetSize();
2448 return variables.
GetSize() - original_size < max_matches;
2453 bool include_inlines,
2461 if (!(orig_die.
Tag() == DW_TAG_subprogram ||
2462 (include_inlines && orig_die.
Tag() == DW_TAG_inlined_subroutine)))
2467 if (die.
Tag() == DW_TAG_inlined_subroutine) {
2474 if (die.
Tag() == DW_TAG_subprogram)
2480 assert(die && die.
Tag() == DW_TAG_subprogram);
2487 if (sc.
block ==
nullptr)
2505 bool only_root_namespaces) {
2512 if (only_root_namespaces)
2513 return die.
GetParent().
Tag() == llvm::dwarf::DW_TAG_compile_unit;
2521 dwarf_ast->GetDeclContextContainingUIDFromDWARF(die))
2530 bool include_inlines,
2538 assert((name_type_mask & eFunctionNameTypeAuto) == 0);
2545 "SymbolFileDWARF::FindFunctions (name=\"{0}\", name_type_mask={1:x}, "
2560 const uint32_t original_size = sc_list.
GetSize();
2562 llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
2564 m_index->GetFunctions(lookup_info, *
this, parent_decl_ctx, [&](
DWARFDIE die) {
2565 if (resolved_dies.insert(die.
GetDIE()).second)
2574 auto it = name_ref.find(
'<');
2575 if (it != llvm::StringRef::npos) {
2576 const llvm::StringRef name_no_template_params = name_ref.slice(0, it);
2580 m_index->GetFunctions(no_tp_lookup_info, *
this, parent_decl_ctx,
2582 if (resolved_dies.insert(die.
GetDIE()).second)
2590 const uint32_t num_matches = sc_list.
GetSize() - original_size;
2592 if (log && num_matches > 0) {
2595 "SymbolFileDWARF::FindFunctions (name=\"{0}\", "
2596 "name_type_mask={1:x}, include_inlines={2:d}, sc_list) => {3}",
2597 name.
GetCString(), name_type_mask, include_inlines, num_matches);
2602 bool include_inlines,
2606 regex.
GetText().str().c_str());
2612 log,
"SymbolFileDWARF::FindFunctions (regex=\"{0}\", sc_list)",
2613 regex.
GetText().str().c_str());
2616 llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
2618 if (resolved_dies.insert(die.
GetDIE()).second)
2625 const std::string &scope_qualified_name,
2626 std::vector<ConstString> &mangled_names) {
2629 for (uint32_t i = 0; i < num_comp_units; i++) {
2648 llvm::StringRef &basename,
2649 llvm::StringRef &template_params) {
2650 auto it = fullname.find(
'<');
2651 if (it == llvm::StringRef::npos) {
2652 basename = fullname;
2653 template_params = llvm::StringRef();
2656 basename = fullname.slice(0, it);
2657 template_params = fullname.slice(it, fullname.size());
2665 bool any_context_updated =
false;
2667 llvm::StringRef basename, params;
2670 any_context_updated =
true;
2673 return any_context_updated;
2683 return debug_info_size + dwp_sp->GetDebugInfoSize();
2686 for (uint32_t i = 0; i < num_comp_units; i++) {
2695 return debug_info_size;
2706 bool have_index_match =
false;
2709 if (query.HasLanguage()) {
2710 if (!query.LanguageMatches(GetLanguageFamily(*die.GetCU())))
2715 std::vector<lldb_private::CompilerContext> die_context;
2720 assert(!die_context.empty());
2726 if (matching_type->IsTemplateType()) {
2735 auto CompilerTypeBasename =
2736 matching_type->GetForwardCompilerType().GetTypeName(true);
2737 if (CompilerTypeBasename != query.GetTypeBasename())
2740 have_index_match =
true;
2741 results.
InsertUnique(matching_type->shared_from_this());
2743 return !results.
Done(query);
2746 if (results.Done(query))
2752 if (!have_index_match) {
2765 m_index->GetTypes(query_simple.GetTypeBasename(), [&](
DWARFDIE die) {
2767 if (query.HasLanguage()) {
2768 if (!query.LanguageMatches(GetLanguageFamily(*die.GetCU())))
2773 std::vector<lldb_private::CompilerContext> die_context;
2774 if (query.GetModuleSearch())
2778 assert(!die_context.empty());
2779 if (!query_simple.ContextMatches(die_context))
2783 if (
Type *matching_type = ResolveType(die,
true,
true)) {
2784 ConstString name = matching_type->GetQualifiedName();
2793 TypeQueryOptions::e_exact_match);
2794 if (!query.ContextMatches(die_query.GetContextRef()))
2797 results.InsertUnique(matching_type->shared_from_this());
2799 return !results.Done(query);
2801 if (results.Done(query))
2809 UpdateExternalModuleListIfNeeded();
2811 for (
const auto &pair : m_external_type_modules) {
2812 if (
ModuleSP external_module_sp = pair.second) {
2813 external_module_sp->FindTypes(query, results);
2814 if (results.Done(query))
2823 bool only_root_namespaces) {
2829 log,
"SymbolFileDWARF::FindNamespace (sc, name=\"{0}\")",
2836 return namespace_decl_ctx;
2847 return !namespace_decl_ctx.
IsValid();
2850 if (log && namespace_decl_ctx) {
2853 "SymbolFileDWARF::FindNamespace (sc, name=\"{0}\") => "
2854 "CompilerDeclContext({1:p}/{2:p}) \"{3}\"",
2856 static_cast<const void *
>(namespace_decl_ctx.
GetTypeSystem()),
2861 return namespace_decl_ctx;
2865 bool resolve_function_context) {
2869 if (type_ptr ==
nullptr) {
2871 if (
auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.
GetCU()))
2878 while (parent_die !=
nullptr) {
2879 if (parent_die->
Tag() == DW_TAG_subprogram)
2884 if (resolve_function_context && parent_die !=
nullptr &&
2891 type_sp = type_ptr->shared_from_this();
2906 if (orig_die != die) {
2907 switch (die.
Tag()) {
2908 case DW_TAG_compile_unit:
2909 case DW_TAG_partial_unit:
2910 case DW_TAG_namespace:
2911 case DW_TAG_structure_type:
2912 case DW_TAG_union_type:
2913 case DW_TAG_class_type:
2914 case DW_TAG_lexical_block:
2915 case DW_TAG_subprogram:
2917 case DW_TAG_inlined_subroutine: {
2933 return decl_ctx_die;
2940 return decl_ctx_die;
2950 Symbol *objc_class_symbol =
nullptr;
2959 return objc_class_symbol;
2977 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
2979 if (dwarf_cu != cu &&
3003 m_index->GetCompleteObjCClass(
3004 type_name, must_be_implementation, [&](
DWARFDIE type_die) {
3010 if (must_be_implementation &&
3012 const bool try_resolving_type = type_die.GetAttributeValueAsUnsigned(
3013 DW_AT_APPLE_objc_complete_type, 0);
3014 if (!try_resolving_type)
3023 "resolved 0x%8.8" PRIx64
" from %s to 0x%8.8" PRIx64
3024 " (cu 0x%8.8" PRIx64
")\n",
3026 m_objfile_sp->GetFileSpec().GetFilename().AsCString(
"<Unknown>"),
3027 type_die.
GetID(), type_cu->GetID());
3031 type_sp = resolved_type->shared_from_this();
3051 std::vector<DWARFDIE> decl_ctx_1;
3052 std::vector<DWARFDIE> decl_ctx_2;
3071 const size_t count1 = decl_ctx_1.size();
3072 const size_t count2 = decl_ctx_2.size();
3073 if (count1 != count2)
3081 for (i = 0; i < count1; i++) {
3082 decl_ctx_die1 = decl_ctx_1[i];
3083 decl_ctx_die2 = decl_ctx_2[i];
3084 if (decl_ctx_die1.
Tag() != decl_ctx_die2.
Tag())
3095 assert(cu_tag == DW_TAG_compile_unit || cu_tag == DW_TAG_partial_unit);
3100 for (i = 0; i < count1 - 1; i++) {
3101 decl_ctx_die1 = decl_ctx_1[i];
3102 decl_ctx_die2 = decl_ctx_2[i];
3103 const char *name1 = decl_ctx_die1.
GetName();
3104 const char *name2 = decl_ctx_die2.
GetName();
3112 if (name1 && name2) {
3114 if (strcmp(name1, name2) != 0)
3137 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag={0}, "
3149 if (
auto err = type_system_or_err.takeError()) {
3151 "Cannot get TypeSystem for language {1}: {0}",
3154 type_system = *type_system_or_err;
3168 m_index->GetFullyQualifiedType(die_dwarf_decl_ctx, [&](
DWARFDIE type_die) {
3178 const bool try_resolving_type =
3182 if (!try_resolving_type) {
3187 "FindDefinitionTypeForDWARFDeclContext(tag={0}, "
3188 "name='{1}') ignoring die={2:x16} ({3})",
3200 "FindDefinitionTypeForDWARFDeclContext(tag={0}, "
3201 "name='{1}') trying die={2:x16} ({3})",
3213 if (template_params) {
3214 llvm::StringRef test_base_name =
3216 auto i = test_base_name.find(
'<');
3221 if (i == llvm::StringRef::npos)
3224 llvm::StringRef test_template_params =
3225 test_base_name.slice(i, test_base_name.size());
3227 if (test_template_params != template_params.
GetStringRef())
3231 type_sp = resolved_type->shared_from_this();
3239 bool *type_is_new_ptr) {
3244 if (
auto err = type_system_or_err.takeError()) {
3246 "Unable to parse type: {0}");
3249 auto ts = *type_system_or_err;
3259 if (die.
Tag() == DW_TAG_subprogram) {
3263 if (scope_qualified_name.size()) {
3275 bool parse_siblings,
bool parse_children) {
3276 size_t types_added = 0;
3281 bool type_is_new =
false;
3283 Tag dwarf_tag =
static_cast<Tag
>(tag);
3288 if (isType(dwarf_tag) && tag != DW_TAG_subrange_type)
3295 if (die.
Tag() == DW_TAG_subprogram) {
3320 size_t functions_added = 0;
3329 return functions_added;
3334 size_t types_added = 0;
3356 function_die.
GetCU(),
true);
3360 const size_t num_variables =
3365 return num_variables;
3370 if (dwarf_cu ==
nullptr)
3373 uint32_t vars_added = 0;
3376 if (variables.get() ==
nullptr) {
3377 variables = std::make_shared<VariableList>();
3383 variables->AddVariableIfUnique(var_sp);
3408 die_to_variable[die.
GetDIE()] = var_sp;
3410 die_to_variable[spec_die.GetDIE()] = var_sp;
3419 const addr_t func_low_pc) {
3424 uint64_t block_length = form_value.
Unsigned();
3432 if (form_value.
Form() == DW_FORM_loclistx)
3441 return location_list;
3453 uint64_t block_offset =
3455 uint64_t block_length = form_value.
Unsigned();
3457 module,
DataExtractor(debug_info_data, block_offset, block_length),
3460 if (
const char *str = form_value.
AsCString())
3480 if (!debug_map_objfile)
3484 if (!debug_map_symtab)
3513 if (tag != DW_TAG_variable && tag != DW_TAG_constant &&
3514 (tag != DW_TAG_formal_parameter || !sc.
function))
3518 const char *name =
nullptr;
3519 const char *mangled =
nullptr;
3522 bool is_external =
false;
3523 bool is_artificial =
false;
3527 for (
size_t i = 0; i < attributes.
Size(); ++i) {
3534 case DW_AT_decl_file:
3538 case DW_AT_decl_line:
3541 case DW_AT_decl_column:
3547 case DW_AT_linkage_name:
3548 case DW_AT_MIPS_linkage_name:
3552 type_die_form = form_value;
3554 case DW_AT_external:
3555 is_external = form_value.
Boolean();
3557 case DW_AT_const_value:
3558 const_value_form = form_value;
3560 case DW_AT_location:
3561 location_form = form_value;
3563 case DW_AT_start_scope:
3566 case DW_AT_artificial:
3567 is_artificial = form_value.
Boolean();
3569 case DW_AT_declaration:
3570 case DW_AT_description:
3571 case DW_AT_endianity:
3573 case DW_AT_specification:
3574 case DW_AT_visibility:
3576 case DW_AT_abstract_origin:
3585 bool location_is_const_value_data =
3591 if (const_value_form.
IsValid())
3599 bool is_static_member = (parent_tag == DW_TAG_compile_unit ||
3600 parent_tag == DW_TAG_partial_unit) &&
3601 (parent_context_die.
Tag() == DW_TAG_class_type ||
3602 parent_context_die.
Tag() == DW_TAG_structure_type);
3607 bool has_explicit_mangled = mangled !=
nullptr;
3619 if ((parent_tag == DW_TAG_compile_unit ||
3620 parent_tag == DW_TAG_partial_unit) &&
3626 if (tag == DW_TAG_formal_parameter)
3637 bool has_explicit_location = location_form.
IsValid();
3638 bool is_static_lifetime =
3639 has_explicit_mangled ||
3640 (has_explicit_location && !location_list.
IsValid());
3643 if (!location_is_const_value_data) {
3644 bool op_error =
false;
3647 location_DW_OP_addr =
3653 "{0:x16}: {1} has an invalid location: {2}", die.
GetOffset(),
3657 is_static_lifetime =
true;
3660 if (debug_map_symfile)
3666 if (is_static_lifetime) {
3672 if (debug_map_symfile) {
3673 bool linked_oso_file_addr =
false;
3675 if (is_external && location_DW_OP_addr == 0) {
3677 *debug_map_symfile, mangled ? mangled : name, location_list,
3679 linked_oso_file_addr =
true;
3680 symbol_context_scope = exe_symbol;
3684 if (!linked_oso_file_addr) {
3701 if (location_is_const_value_data &&
3702 die.
GetDIE()->IsGlobalOrStaticScopeVariable())
3706 if (debug_map_symfile) {
3711 [
this, debug_map_symfile](
3713 return debug_map_symfile->LinkOSOFileAddress(
3714 this, unlinked_file_addr);
3723 if (symbol_context_scope ==
nullptr) {
3724 switch (parent_tag) {
3725 case DW_TAG_subprogram:
3726 case DW_TAG_inlined_subroutine:
3727 case DW_TAG_lexical_block:
3729 symbol_context_scope =
3731 if (symbol_context_scope ==
nullptr)
3732 symbol_context_scope = sc.
function;
3742 if (!symbol_context_scope) {
3749 auto type_sp = std::make_shared<SymbolFileType>(
3752 bool use_type_size_for_value =
3753 location_is_const_value_data &&
3755 if (use_type_size_for_value && type_sp->GetType()) {
3758 type_sp->GetType()->GetByteSize(
nullptr).value_or(0),
3762 return std::make_shared<Variable>(
3763 die.
GetID(), name, mangled, type_sp, scope, symbol_context_scope,
3764 scope_ranges, &decl, location_list, is_external, is_artificial,
3765 location_is_const_value_data, is_static_member);
3775 spec_block_die_offset);
3782 switch (die.
Tag()) {
3783 case DW_TAG_subprogram:
3784 case DW_TAG_inlined_subroutine:
3785 case DW_TAG_lexical_block: {
3787 spec_block_die_offset)
3791 spec_block_die_offset)
3819 if (tag != DW_TAG_variable && tag != DW_TAG_constant)
3835 switch (parent_tag) {
3836 case DW_TAG_compile_unit:
3837 case DW_TAG_partial_unit:
3842 "parent {0:x8} {1} with no valid compile unit in "
3843 "symbol context for {2:x8} {3}.\n",
3852 "didn't find appropriate parent DIE for variable list for {0:x8} "
3863 if (variable_list_sp)
3864 variable_list_sp->AddVariableIfUnique(var_sp);
3880 if (block_die.
Tag() != DW_TAG_inlined_subroutine) {
3881 return std::move(variable_dies);
3886 if (!abs_die || abs_die.
Tag() != DW_TAG_subprogram ||
3888 return std::move(variable_dies);
3893 DIEArray::iterator concrete_it = variable_dies.begin();
3896 bool did_merge_abstract =
false;
3897 for (; abstract_child; abstract_child = abstract_child.
GetSibling()) {
3898 if (abstract_child.
Tag() == DW_TAG_formal_parameter) {
3899 if (concrete_it == variable_dies.end() ||
3900 GetDIE(*concrete_it).
Tag() != DW_TAG_formal_parameter) {
3904 merged.push_back(*abstract_child.
GetDIERef());
3905 did_merge_abstract =
true;
3911 if (origin_of_concrete == abstract_child) {
3914 merged.push_back(*concrete_it);
3919 merged.push_back(*abstract_child.
GetDIERef());
3920 did_merge_abstract =
true;
3926 if (!did_merge_abstract)
3927 return std::move(variable_dies);
3934 for (; concrete_it != variable_dies.end(); ++concrete_it) {
3935 if (
GetDIE(*concrete_it).
Tag() == DW_TAG_formal_parameter) {
3936 return std::move(variable_dies);
3938 merged.push_back(*concrete_it);
3954 dummy_block_variables);
3964 size_t vars_added = 0;
3967 if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
3968 (tag == DW_TAG_formal_parameter)) {
3969 accumulator.push_back(*die.
GetDIERef());
3973 case DW_TAG_subprogram:
3974 case DW_TAG_inlined_subroutine:
3975 case DW_TAG_lexical_block: {
3979 if (block ==
nullptr) {
3986 if (concrete_block_die)
3991 if (block ==
nullptr)
3994 const bool can_create =
false;
3997 if (block_variable_list_sp.get() ==
nullptr) {
3998 block_variable_list_sp = std::make_shared<VariableList>();
4006 sc, child, func_low_pc, block_variables);
4011 block_variables, func_low_pc);
4020 sc, child, func_low_pc, accumulator);
4030 llvm::ArrayRef<DIERef> variable_dies,
lldb::addr_t func_low_pc) {
4032 for (
auto &die : variable_dies) {
4037 return variable_dies.size();
4045 if (child.Tag() != DW_TAG_call_site_parameter &&
4046 child.Tag() != DW_TAG_GNU_call_site_parameter)
4049 std::optional<DWARFExpressionList> LocationInCallee;
4050 std::optional<DWARFExpressionList> LocationInCaller;
4056 auto parse_simple_location =
4057 [&](
int attr_index) -> std::optional<DWARFExpressionList> {
4063 auto data = child.GetData();
4064 uint64_t block_offset = form_value.
BlockData() - data.GetDataStart();
4065 uint64_t block_length = form_value.
Unsigned();
4071 for (
size_t i = 0; i < attributes.
Size(); ++i) {
4073 if (attr == DW_AT_location)
4074 LocationInCallee = parse_simple_location(i);
4075 if (attr == DW_AT_call_value || attr == DW_AT_GNU_call_site_value)
4076 LocationInCaller = parse_simple_location(i);
4079 if (LocationInCallee && LocationInCaller) {
4081 parameters.push_back(param);
4088std::vector<std::unique_ptr<lldb_private::CallEdge>>
4092 bool has_call_edges =
4095 if (!has_call_edges)
4099 LLDB_LOG(log,
"CollectCallEdges: Found call site info in {0}",
4107 std::vector<std::unique_ptr<CallEdge>> call_edges;
4109 if (child.Tag() != DW_TAG_call_site && child.Tag() != DW_TAG_GNU_call_site)
4112 std::optional<DWARFDIE> call_origin;
4113 std::optional<DWARFExpressionList> call_target;
4117 bool tail_call =
false;
4123 for (
size_t i = 0; i < attributes.
Size(); ++i) {
4126 LLDB_LOG(log,
"CollectCallEdges: Could not extract TAG_call_site form");
4132 if (attr == DW_AT_call_tail_call || attr == DW_AT_GNU_tail_call)
4133 tail_call = form_value.
Boolean();
4136 if (attr == DW_AT_call_origin || attr == DW_AT_abstract_origin) {
4138 if (!call_origin->IsValid()) {
4139 LLDB_LOG(log,
"CollectCallEdges: Invalid call origin in {0}",
4145 if (attr == DW_AT_low_pc)
4146 low_pc = form_value.
Address();
4151 if (attr == DW_AT_call_return_pc)
4152 return_pc = form_value.
Address();
4157 if (attr == DW_AT_call_pc)
4158 call_inst_pc = form_value.
Address();
4162 if (attr == DW_AT_call_target || attr == DW_AT_GNU_call_site_target) {
4165 "CollectCallEdges: AT_call_target does not have block form");
4169 auto data = child.GetData();
4170 uint64_t block_offset = form_value.
BlockData() - data.GetDataStart();
4171 uint64_t block_length = form_value.
Unsigned();
4177 if (!call_origin && !call_target) {
4178 LLDB_LOG(log,
"CollectCallEdges: call site without any call target");
4185 caller_address = return_pc;
4188 caller_address = low_pc;
4191 caller_address = call_inst_pc;
4194 LLDB_LOG(log,
"CollectCallEdges: No caller address");
4206 std::unique_ptr<CallEdge> edge;
4209 "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x}) "
4211 call_origin->GetPubname(), return_pc, call_inst_pc);
4212 edge = std::make_unique<DirectCallEdge>(
4213 call_origin->GetMangledName(), caller_address_type, caller_address,
4214 tail_call, std::move(parameters));
4220 LLDB_LOG(log,
"CollectCallEdges: Found indirect call target: {0}",
4223 edge = std::make_unique<IndirectCallEdge>(
4224 *call_target, caller_address_type, caller_address, tail_call,
4225 std::move(parameters));
4228 if (log && parameters.size()) {
4231 param.LocationInCallee.GetDescription(&callee_loc_desc,
4233 param.LocationInCaller.GetDescription(&caller_loc_desc,
4235 LLDB_LOG(log,
"CollectCallEdges: \tparam: {0} => {1}",
4240 call_edges.push_back(std::move(edge));
4245std::vector<std::unique_ptr<lldb_private::CallEdge>>
4267 auto ts = *ts_or_err;
4279 for (
size_t cu_idx = 0; cu_idx < num_cus; cu_idx++) {
4282 if (dwarf_cu ==
nullptr)
4287 if (!dwarf_cu->
GetDWOId().has_value())
4291 std::make_shared<StructuredData::Dictionary>();
4292 const uint64_t dwo_id = dwarf_cu->
GetDWOId().value();
4293 dwo_data->AddIntegerItem(
"dwo_id", dwo_id);
4298 dwo_data->AddStringItem(
"dwo_name", dwo_name);
4300 dwo_data->AddStringItem(
"error",
"missing dwo name");
4304 dwarf_cu, DW_AT_comp_dir,
nullptr);
4306 dwo_data->AddStringItem(
"comp_dir", comp_dir);
4309 dwo_data->AddStringItem(
4311 llvm::formatv(
"unable to get unit DIE for DWARFUnit at {0:x}",
4320 dwo_data->AddStringItem(
4321 "resolved_dwo_path",
4324 dwo_data->AddStringItem(
"error",
4327 dwo_data->AddBooleanItem(
"loaded", dwo_symfile !=
nullptr);
4328 if (!errors_only || dwo_data->HasKey(
"error"))
4329 separate_debug_info_files.
AddItem(dwo_data);
4334 d.
AddItem(
"separate-debug-info-files",
4335 std::make_shared<StructuredData::Array>(
4336 std::move(separate_debug_info_files)));
4345 module_sp->GetSymbolFile()->GetBackingSymbolFile());
4357 symfiles.
Append(module_fspec);
4363 if (symfile_fspec != module_fspec) {
4364 symfiles.
Append(symfile_fspec);
4371 if (filename_no_ext != module_fspec.
GetFilename()) {
4372 FileSpec module_spec_no_ext(module_fspec);
4374 symfiles.
Append(module_spec_no_ext);
4381 for (
const auto &symfile : symfiles.
files()) {
4383 FileSpec(symfile.GetPath() +
".dwp", symfile.GetPathStyle());
4384 LLDB_LOG(log,
"Searching for DWP using: \"{0}\"",
4389 LLDB_LOG(log,
"Found DWP file: \"{0}\"", dwp_filespec);
4395 dwp_file_data_offset);
4404 LLDB_LOG(log,
"Unable to locate for DWP file for: \"{0}\"",
4411llvm::Expected<lldb::TypeSystemSP>
4418 if (
auto err = type_system_or_err.takeError()) {
4420 "Unable to get DWARFASTParser: {0}");
4423 if (
auto ts = *type_system_or_err)
4424 return ts->GetDWARFParser();
4430 return dwarf_ast->GetDeclForUIDFromDWARF(die);
4436 return dwarf_ast->GetDeclContextForUIDFromDWARF(die);
4443 return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
4452 return dwarf_decl_ctx;
4459 case DW_LANG_Mips_Assembler:
4472 if (llvm::dwarf::isCPlusPlus(lang))
4473 lang = DW_LANG_C_plus_plus;
4479 return m_index->GetIndexTime();
4498 if (dwo_error.
Fail())
4508 if (dwarf_cu->
HasAny({DW_TAG_variable, DW_TAG_formal_parameter}))
4511 return Status(
"no variable information is available in debug info for this "
4516 std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) {
4520 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
4537 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()
A section + offset based address range class.
Address & GetBaseAddress()
Get accessor for the base address of the range.
void SetByteSize(lldb::addr_t byte_size)
Set accessor for the byte size of this range.
A section + offset based address class.
bool ResolveAddressUsingFileSections(lldb::addr_t addr, const SectionList *sections)
Resolve a file virtual address using a section list.
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.
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 AddChild(const lldb::BlockSP &child_block_sp)
Add a child to this object.
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)
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 ...
bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::addr_t func_load_addr, const Value *initial_value_ptr, const Value *object_address_ptr, Value &result, Status *error_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.
void DumpLocation(Stream *s, lldb::DescriptionLevel level, ABI *abi) const
lldb::addr_t GetLocation_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu, bool &error) const
Return the address specified by the first DW_OP_{addr, addrx, GNU_addr_index} in the operation stream...
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()
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
BaseType GetMaxRangeEnd(BaseType fail_value) const
Entry & GetEntryRef(size_t i)
BaseType GetMinRangeBase(BaseType fail_value) const
llvm::StringRef GetText() const
Access the regular expression text.
unsigned long long ULongLong(unsigned long long fail_value=0) const
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
static Status createWithFormat(const char *format, Args &&...args)
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.
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 either a FileSpec that represents a local file or a source file whose contents is known (for ex...
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()
virtual void CalculateSymbolContext(SymbolContext *sc)=0
Reconstruct the object's symbol context into sc.
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
Block * block
The Block for a given query.
lldb::ModuleSP module_sp
The Module for a given query.
CompileUnit * comp_unit
The CompileUnit for a given query.
uint32_t GetResolvedMask() const
void Clear(bool clear_target)
Clear the object's state.
Variable * variable
The global variable matching the given query.
LineEntry line_entry
The LineEntry for a given query.
Containing protected virtual methods for child classes to override.
lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) override
ObjectFile * GetObjectFile() override
virtual TypeList & GetTypeList()
lldb::ObjectFileSP m_objfile_sp
Symtab * GetSymtab() override
ObjectFile * GetMainObjectFile() override
void SetCompileUnitAtIndex(uint32_t idx, const lldb::CompUnitSP &cu_sp)
uint32_t GetNumCompileUnits() override
void Dump(Stream &s) override
uint64_t GetDebugInfoSize(bool load_all_debug_info=false) override
Metrics gathering functions.
Provides public interface for all SymbolFiles.
std::unordered_map< lldb::CompUnitSP, Args > GetCompileOptions()
Returns a map of compilation unit to the compile option arguments associated with that compilation un...
virtual ObjectFile * GetObjectFile()=0
bool ValueIsAddress() const
Address & GetAddressRef()
Symbol * FindFirstSymbolWithNameAndType(ConstString name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility)
static FileSpecList GetDefaultDebugFileSearchPaths()
void Insert(const lldb::TypeSP &type)
A class that contains all state required for type lookups.
bool GetModuleSearch() const
The m_context can be used in two ways: normal types searching with the context containing a stanadard...
std::vector< lldb_private::CompilerContext > & GetContextRef()
Access the internal compiler context array.
ConstString GetTypeBasename() const
Get the type basename to use when searching the type indexes in each SymbolFile object.
bool ContextMatches(llvm::ArrayRef< lldb_private::CompilerContext > context) const
Check of a CompilerContext array from matching type from a symbol file matches the m_context.
This class tracks the state and results of a TypeQuery.
bool InsertUnique(const lldb::TypeSP &type_sp)
When types that match a TypeQuery are found, this API is used to insert the matching types.
bool Done(const TypeQuery &query) const
Check if the type matching has found all of the matches that it needs.
bool AlreadySearched(lldb_private::SymbolFile *sym_file)
Check if a SymbolFile object has already been searched by this type match object.
A TypeSystem implementation based on Clang.
Interface for representing a type system.
virtual lldb::LanguageType GetMinimumLanguage(lldb::opaque_compiler_type_t type)=0
virtual plugin::dwarf::DWARFASTParser * GetDWARFParser()
const Scalar & GetScalar() const
@ FileAddress
A file address value.
ValueType GetValueType() const
bool AddVariableIfUnique(const lldb::VariableSP &var_sp)
lldb::VariableSP GetVariableAtIndex(size_t idx) const
lldb::VariableSP RemoveVariableAtIndex(size_t idx)
SymbolContextScope * GetSymbolContextScope() const
An abstraction for Xcode-style SDKs that works like ArchSpec.
static std::unique_ptr< AppleDWARFIndex > Create(Module &module, DWARFDataExtractor apple_names, DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types, DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str)
Identifies a DWARF debug info entry within a given Module.
std::optional< uint32_t > file_index() const
static constexpr uint64_t k_file_index_mask
dw_offset_t die_offset() const
virtual ConstString GetDIEClassTemplateParams(const DWARFDIE &die)=0
virtual void EnsureAllDIEsInDeclContextHaveBeenParsed(CompilerDeclContext decl_context)=0
virtual ConstString ConstructDemangledNameFromDWARF(const DWARFDIE &die)=0
virtual lldb::TypeSP ParseTypeFromDWARF(const SymbolContext &sc, const DWARFDIE &die, bool *type_is_new_ptr)=0
virtual Function * ParseFunctionFromDWARF(CompileUnit &comp_unit, const DWARFDIE &die, const AddressRange &range)=0
static std::optional< SymbolFile::ArrayInfo > ParseChildArrayInfo(const DWARFDIE &parent_die, const ExecutionContext *exe_ctx=nullptr)
virtual CompilerDeclContext GetDeclContextForUIDFromDWARF(const DWARFDIE &die)=0
DWARFUnit * CompileUnitAtIndex(uint32_t i) const
dw_attr_t AttributeAtIndex(uint32_t i) const
bool ExtractFormValueAtIndex(uint32_t i, DWARFFormValue &form_value) const
DWARFAttributes GetAttributes(Recurse recurse=Recurse::yes) const
const char * GetTagAsCString() const
const DWARFDataExtractor & GetData() const
const char * GetAttributeValueAsString(const dw_attr_t attr, const char *fail_value) const
std::optional< DIERef > GetDIERef() const
lldb::ModuleSP GetModule() const
SymbolFileDWARF * GetDWARF() const
DWARFDebugInfoEntry * GetDIE() const
DWARFUnit * GetCU() const
bool Supports_DW_AT_APPLE_objc_complete_type() const
const char * GetName() const
uint64_t GetAttributeValueAsUnsigned(const dw_attr_t attr, uint64_t fail_value) const
dw_offset_t GetOffset() const
lldb::user_id_t GetID() const
DWARFDIE LookupAddress(const dw_addr_t address)
DWARFCompileUnit & GetNonSkeletonUnit()
const DWARFDataExtractor & getOrLoadLineData()
const DWARFDataExtractor & getOrLoadStrData()
llvm::DWARFContext & GetAsLLVM()
const DWARFDataExtractor & getOrLoadRangesData()
const DWARFDataExtractor & getOrLoadAbbrevData()
const DWARFDataExtractor & getOrLoadMacroData()
void GetName(Stream &s) const
std::vector< DWARFDIE > GetDeclContextDIEs() const
std::vector< CompilerContext > GetTypeLookupContext() const
Get a context to a type so it can be looked up.
DWARFDIE GetFirstChild() const
DWARFDIE GetParent() const
const char * GetMangledName() const
std::vector< CompilerContext > GetDeclContext() const
Return this DIE's decl context as it is needed to look up types in Clang modules.
DWARFDIE GetDIE(dw_offset_t die_offset) const
llvm::iterator_range< child_iterator > children() const
The range of all the children of this DIE.
bool GetDIENamesAndRanges(const char *&name, const char *&mangled, DWARFRangeList &ranges, std::optional< int > &decl_file, std::optional< int > &decl_line, std::optional< int > &decl_column, std::optional< int > &call_file, std::optional< int > &call_line, std::optional< int > &call_column, DWARFExpressionList *frame_base) const
DWARFDIE LookupDeepestBlock(lldb::addr_t file_addr) const
DWARFDIE GetReferencedDIE(const dw_attr_t attr) const
const char * GetPubname() const
DWARFDIE GetSibling() const
dw_offset_t FindAddress(dw_addr_t address) const
DWARFDebugInfoEntry objects assume that they are living in one big vector and do pointer arithmetic o...
std::optional< uint64_t > GetAttributeValueAsOptionalUnsigned(const DWARFUnit *cu, const dw_attr_t attr, bool check_specification_or_abstract_origin=false) const
dw_offset_t GetOffset() const
const char * GetAttributeValueAsString(const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value, bool check_specification_or_abstract_origin=false) const
DWARFDebugInfoEntry * GetParent()
DWARFUnit * GetSkeletonUnit(DWARFUnit *dwo_unit)
DWARFUnit * GetUnitAtOffset(DIERef::Section section, dw_offset_t cu_offset, uint32_t *idx_ptr=nullptr)
const DWARFDebugAranges & GetCompileUnitAranges()
DWARFDIE GetDIE(const DIERef &die_ref)
DWARFUnit * GetUnitAtIndex(size_t idx)
static void ReadMacroEntries(const DWARFDataExtractor &debug_macro_data, const DWARFDataExtractor &debug_str_data, const bool offset_is_64_bit, lldb::offset_t *sect_offset, SymbolFileDWARF *sym_file_dwarf, DebugMacrosSP &debug_macros_sp)
const char * GetQualifiedName() const
ConstString GetQualifiedNameAsConstString() const
FileSpec::Style GetPathStyle()
DWARFBaseDIE GetUnitDIEOnly()
uint8_t GetAddressByteSize() const
void ExtractUnitDIEIfNeeded()
SymbolFileDWARF & GetSymbolFileDWARF() const
dw_offset_t GetLineTableOffset()
bool Supports_DW_AT_APPLE_objc_complete_type()
DWARFCompileUnit * GetSkeletonUnit()
Get the skeleton compile unit for a DWO file.
const Status & GetDwoError() const
Get the fission .dwo file specific error for this compile unit.
void SetLLDBCompUnit(lldb_private::CompileUnit *cu)
lldb_private::CompileUnit * GetLLDBCompUnit() const
dw_offset_t GetOffset() const
DWARFDataExtractor GetLocationData() const
uint16_t GetVersion() const
die_iterator_range dies()
std::optional< uint64_t > GetLoclistOffset(uint32_t Index)
uint64_t GetDWARFLanguageType()
DWARFUnit & GetNonSkeletonUnit()
DWARFDIE GetDIE(dw_offset_t die_offset)
lldb::ByteOrder GetByteOrder() const
void SetDwoError(const Status &error)
Set the fission .dwo file specific error for this compile unit.
SymbolFileDWARFDwo * GetDwoSymbolFile(bool load_all_debug_info=true)
const FileSpec & GetCompilationDirectory()
std::optional< uint64_t > GetDWOId()
Get the DWO ID from the DWARFUnitHeader for DWARF5, or from the unit DIE's DW_AT_dwo_id or DW_AT_GNU_...
bool HasAny(llvm::ArrayRef< dw_tag_t > tags)
Returns true if any DIEs in the unit match any DW_TAG values in tags.
FileSpec GetFile(size_t file_idx)
static llvm::Expected< std::unique_ptr< DebugNamesDWARFIndex > > Create(Module &module, DWARFDataExtractor debug_names, DWARFDataExtractor debug_str, SymbolFileDWARF &dwarf)
lldb::CompUnitSP GetCompileUnit(SymbolFileDWARF *oso_dwarf, DWARFCompileUnit &dwarf_cu)
Returns the compile unit associated with the dwarf compile unit.
bool Supports_DW_AT_APPLE_objc_complete_type(SymbolFileDWARF *skip_dwarf_oso)
lldb::addr_t LinkOSOFileAddress(SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr)
Convert a .o file "file address" to an executable "file address".
bool LinkOSOAddress(Address &addr)
Convert addr from a .o file address, to an executable address.
UniqueDWARFASTTypeMap & GetUniqueDWARFASTTypeMap()
uint64_t GetDebugInfoSize(bool load_all_debug_info=false) override
Metrics gathering functions.
CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override
static CompilerDeclContext GetContainingDeclContext(const DWARFDIE &die)
static bool SupportedVersion(uint16_t version)
std::optional< uint32_t > GetDWARFUnitIndex(uint32_t cu_idx)
CompileUnit * GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu)
lldb::ModuleSP GetExternalModule(ConstString name)
DWARFDebugRanges * GetDebugRanges()
void BuildCuTranslationTable()
void FindGlobalVariables(ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) override
DWARFDIE FindBlockContainingSpecification(const DIERef &func_die_ref, dw_offset_t spec_block_die_offset)
lldb::VariableSP ParseVariableDIE(const SymbolContext &sc, const DWARFDIE &die, const lldb::addr_t func_low_pc)
void UpdateExternalModuleListIfNeeded()
static DWARFASTParser * GetDWARFParser(DWARFUnit &unit)
bool Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu)
static lldb::LanguageType GetLanguageFamily(DWARFUnit &unit)
Same as GetLanguage() but reports all C++ versions as C++ (no version).
bool ForEachExternalModule(CompileUnit &, llvm::DenseSet< SymbolFile * > &, llvm::function_ref< bool(Module &)>) override
static char ID
LLVM RTTI support.
std::unique_ptr< DWARFDebugInfo > m_info
bool DeclContextMatchesThisSymbolFile(const CompilerDeclContext &decl_ctx)
void GetMangledNamesForFunction(const std::string &scope_qualified_name, std::vector< ConstString > &mangled_names) override
size_t PopulateBlockVariableList(VariableList &variable_list, const SymbolContext &sc, llvm::ArrayRef< DIERef > variable_dies, lldb::addr_t func_low_pc)
Type * ResolveType(const DWARFDIE &die, bool assert_not_being_parsed=true, bool resolve_function_context=false)
llvm::DenseMap< const DWARFDebugInfoEntry *, lldb::VariableSP > DIEToVariableSP
size_t ParseVariablesInFunctionContextRecursive(const SymbolContext &sc, const DWARFDIE &die, lldb::addr_t func_low_pc, DIEArray &accumulator)
virtual lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(const DWARFDIE &die, ConstString type_name, bool must_be_implementation)
const std::shared_ptr< SymbolFileDWARFDwo > & GetDwpSymbolFile()
std::recursive_mutex & GetModuleMutex() const override
Symbols file subclasses should override this to return the Module that owns the TypeSystem that this ...
UniqueDWARFASTTypeMap m_unique_ast_type_map
bool m_fetched_external_modules
GlobalVariableMap & GetGlobalAranges()
virtual DWARFCompileUnit * GetDWARFCompileUnit(CompileUnit *comp_unit)
llvm::SetVector< Type * > TypeSet
Function * ParseFunction(CompileUnit &comp_unit, const DWARFDIE &die)
lldb::TypeSP GetTypeForDIE(const DWARFDIE &die, bool resolve_function_context=false)
lldb::addr_t m_first_code_address
DWARF does not provide a good way for traditional (concatenating) linkers to invalidate debug info de...
ConstString ConstructFunctionDemangledName(const DWARFDIE &die)
lldb::ModuleWP m_debug_map_module_wp
DWARFUnit * GetSkeletonUnit(DWARFUnit *dwo_unit)
Given a DWO DWARFUnit, find the corresponding skeleton DWARFUnit in the main symbol file.
FileSpec GetFile(DWARFUnit &unit, size_t file_idx)
std::shared_ptr< SymbolFileDWARFDwo > m_dwp_symfile
void InitializeFirstCodeAddressRecursive(const SectionList §ion_list)
std::unique_ptr< llvm::DWARFDebugAbbrev > m_abbr
void DumpClangAST(Stream &s) override
std::vector< CompilerContext > GetCompilerContextForUID(lldb::user_id_t uid) override
virtual void GetObjCMethods(ConstString class_name, llvm::function_ref< bool(DWARFDIE die)> callback)
virtual DWARFDIE GetDIE(const DIERef &die_ref)
static llvm::StringRef GetPluginNameStatic()
void InitializeFirstCodeAddress()
std::unique_ptr< GlobalVariableMap > m_global_aranges_up
llvm::once_flag m_info_once_flag
uint64_t GetDebugInfoSize(bool load_all_debug_info=false) override
Metrics gathering functions.
void FindTypes(const lldb_private::TypeQuery &match, lldb_private::TypeResults &results) override
Find types using a type-matching object that contains all search parameters.
static CompilerDecl GetDecl(const DWARFDIE &die)
void ResolveFunctionAndBlock(lldb::addr_t file_vm_addr, bool lookup_block, SymbolContext &sc)
Resolve functions and (possibly) blocks for the given file address and a compile unit.
size_t ParseVariablesForContext(const SymbolContext &sc) override
virtual DIEToTypePtr & GetDIEToType()
uint32_t CalculateNumCompileUnits() override
std::optional< ArrayInfo > GetDynamicArrayInfoForUID(lldb::user_id_t type_uid, const ExecutionContext *exe_ctx) override
If type_uid points to an array type, return its characteristics.
size_t ParseBlocksRecursive(Function &func) override
ExternalTypeModuleMap m_external_type_modules
Type * ResolveTypeUID(lldb::user_id_t type_uid) override
static lldb::LanguageType GetLanguage(DWARFUnit &unit)
LazyBool m_supports_DW_AT_APPLE_objc_complete_type
bool ClassOrStructIsVirtual(const DWARFDIE &die)
llvm::DenseMap< dw_offset_t, std::unique_ptr< SupportFileList > > m_type_unit_support_files
size_t ParseFunctions(CompileUnit &comp_unit) override
bool ParseDebugMacros(CompileUnit &comp_unit) override
NameToOffsetMap m_function_scope_qualified_name_map
static SymbolFile * CreateInstance(lldb::ObjectFileSP objfile_sp)
std::atomic_flag m_dwo_warning_issued
bool ParseSupportFiles(CompileUnit &comp_unit, SupportFileList &support_files) override
XcodeSDK ParseXcodeSDK(CompileUnit &comp_unit) override
Return the Xcode SDK comp_unit was compiled against.
bool ParseImportedModules(const SymbolContext &sc, std::vector< SourceModule > &imported_modules) override
std::optional< uint64_t > GetDWOId()
If this is a DWARF object with a single CU, return its DW_AT_dwo_id.
uint32_t CalculateAbilities() override
void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask, TypeList &type_list) override
SymbolFileDWARFDebugMap * GetDebugMapSymfile()
void ParseDeclsForContext(CompilerDeclContext decl_ctx) override
size_t ParseTypes(CompileUnit &comp_unit) override
std::shared_ptr< SymbolFileDWARFDwo > GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die)
SymbolFileDWARF(lldb::ObjectFileSP objfile_sp, SectionList *dwo_section_list)
static DWARFDeclContext GetDWARFDeclContext(const DWARFDIE &die)
~SymbolFileDWARF() override
lldb::VariableSP ParseVariableDIECached(const SymbolContext &sc, const DWARFDIE &die)
StatsDuration::Duration GetDebugInfoIndexTime() override
Return the time it took to index the debug information in the object file.
bool CompleteType(CompilerType &compiler_type) override
DWARFDebugInfo & DebugInfo()
bool ParseLineTable(CompileUnit &comp_unit) override
bool GetSeparateDebugInfo(StructuredData::Dictionary &d, bool errors_only) override
List separate dwo files.
bool ResolveFunction(const DWARFDIE &die, bool include_inlines, SymbolContextList &sc_list)
bool ParseIsOptimized(CompileUnit &comp_unit) override
virtual lldb::TypeSP FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die)
static llvm::StringRef GetPluginDescriptionStatic()
std::vector< std::unique_ptr< CallEdge > > CollectCallEdges(lldb::ModuleSP module, DWARFDIE function_die)
Parse call site entries (DW_TAG_call_site), including any nested call site parameters (DW_TAG_call_si...
void Dump(Stream &s) override
DIEArray MergeBlockAbstractParameters(const DWARFDIE &block_die, DIEArray &&variable_dies)
std::unique_ptr< DWARFDebugRanges > m_ranges
DWARFDIE GetDeclContextDIEContainingDIE(const DWARFDIE &die)
SymbolFileDWARFDebugMap * m_debug_map_symfile
virtual CompilerTypeToDIE & GetForwardDeclCompilerTypeToDIE()
void InitializeObject() override
Initialize the SymbolFile object.
void ParseAndAppendGlobalVariable(const SymbolContext &sc, const DWARFDIE &die, VariableList &cc_variable_list)
static llvm::Expected< lldb::TypeSystemSP > GetTypeSystem(DWARFUnit &unit)
std::vector< uint32_t > m_lldb_cu_to_dwarf_unit
void FindFunctions(const Module::LookupInfo &lookup_info, const CompilerDeclContext &parent_decl_ctx, bool include_inlines, SymbolContextList &sc_list) override
static bool DIEInDeclContext(const CompilerDeclContext &parent_decl_ctx, const DWARFDIE &die, bool only_root_namespaces=false)
uint32_t ResolveSymbolContext(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc) override
std::unique_ptr< DWARFIndex > m_index
bool HasForwardDeclForCompilerType(const CompilerType &compiler_type)
void PreloadSymbols() override
TypeList & GetTypeList() override
lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu)
CompilerDeclContext FindNamespace(ConstString name, const CompilerDeclContext &parent_decl_ctx, bool only_root_namespaces) override
Finds a namespace of name name and whose parent context is parent_decl_ctx.
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override
static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val)
lldb::TypeSP ParseType(const SymbolContext &sc, const DWARFDIE &die, bool *type_is_new)
static DWARFDIE GetParentSymbolContextDIE(const DWARFDIE &die)
std::vector< std::unique_ptr< CallEdge > > ParseCallEdgesInFunction(UserID func_id) override
lldb::addr_t FixupAddress(lldb::addr_t file_addr)
If this symbol file is linked to by a debug map (see SymbolFileDWARFDebugMap), and file_addr is a fil...
llvm::Expected< lldb::TypeSystemSP > GetTypeSystemForLanguage(lldb::LanguageType language) override
CompilerDecl GetDeclForUID(lldb::user_id_t uid) override
lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override
StatsDuration m_parse_time
llvm::once_flag m_dwp_symfile_once_flag
CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override
static void DebuggerInitialize(Debugger &debugger)
RangeDataVector< lldb::addr_t, lldb::addr_t, Variable * > GlobalVariableMap
size_t ParseVariablesInFunctionContext(const SymbolContext &sc, const DWARFDIE &die, const lldb::addr_t func_low_pc)
DebugMacrosMap m_debug_macros_map
llvm::DWARFDebugAbbrev * DebugAbbrev()
bool DIEDeclContextsMatch(const DWARFDIE &die1, const DWARFDIE &die2)
bool GetFunction(const DWARFDIE &die, SymbolContext &sc)
const SupportFileList * GetTypeUnitSupportFiles(DWARFTypeUnit &tu)
virtual DIEToVariableSP & GetDIEToVariable()
Symbol * GetObjCClassSymbol(ConstString objc_class_name)
static CompilerDeclContext GetDeclContext(const DWARFDIE &die)
virtual UniqueDWARFASTTypeMap & GetUniqueDWARFASTTypeMap()
virtual void LoadSectionData(lldb::SectionType sect_type, DWARFDataExtractor &data)
Status CalculateFrameVariableError(StackFrame &frame) override
Subclasses will override this function to for GetFrameVariableError().
#define DW_INVALID_OFFSET
llvm::dwarf::Tag dw_tag_t
#define DW_DIE_OFFSET_MAX_BITSIZE
llvm::dwarf::Attribute dw_attr_t
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
std::vector< DIERef > DIEArray
const char * DW_TAG_value_to_name(uint32_t val)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::shared_ptr< DebugMacros > DebugMacrosSP
llvm::SmallVector< CallSiteParameter, 0 > CallSiteParameterArray
A vector of CallSiteParameter.
std::shared_ptr< lldb_private::TypeSystem > TypeSystemSP
std::shared_ptr< lldb_private::Block > BlockSP
std::shared_ptr< lldb_private::SupportFile > SupportFileSP
std::shared_ptr< lldb_private::ObjectFile > ObjectFileSP
LanguageType
Programming language type.
@ eLanguageTypeMipsAssembler
Mips_Assembler.
@ eLanguageTypeUnknown
Unknown or invalid language value.
@ eLanguageTypeC_plus_plus
ISO C++:1998.
std::shared_ptr< lldb_private::Type > TypeSP
std::shared_ptr< lldb_private::VariableList > VariableListSP
std::shared_ptr< lldb_private::Variable > VariableSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::Section > SectionSP
@ eSectionTypeDWARFAppleNamespaces
@ eSectionTypeDWARFDebugNames
DWARF v5 .debug_names.
@ eSectionTypeDWARFAppleTypes
@ eSectionTypeDWARFDebugInfo
@ eSectionTypeDWARFDebugLine
@ eSectionTypeDWARFDebugStr
@ eSectionTypeDWARFAppleNames
@ eSectionTypeDWARFAppleObjC
@ eSectionTypeDWARFDebugAbbrev
std::shared_ptr< lldb_private::Module > ModuleSP
std::shared_ptr< lldb_private::CompileUnit > CompUnitSP
@ eValueTypeVariableGlobal
globals variable
@ eValueTypeVariableLocal
function local variables
@ eValueTypeVariableArgument
function argument variables
@ eValueTypeVariableStatic
static variable
@ eValueTypeVariableThreadLocal
thread local storage variable
Represent the locations of a parameter at a call site, both in the caller and in the callee.
static CompilerType RemoveFastQualifiers(const CompilerType &ct)
BaseType GetRangeBase() const
SizeType GetByteSize() const
BaseType GetRangeEnd() const
Information needed to import a source-language module.
std::vector< ConstString > path
Something like "Module.Submodule".
A mix in class that contains a generic user ID.
lldb::user_id_t GetID() const
Get accessor for the user ID.