LLDB mainline
SymbolFileDWARF.cpp
Go to the documentation of this file.
1//===-- SymbolFileDWARF.cpp -----------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "SymbolFileDWARF.h"
10
11#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
12#include "llvm/Support/Casting.h"
13#include "llvm/Support/Threading.h"
14
15#include "lldb/Core/Module.h"
19#include "lldb/Core/Progress.h"
20#include "lldb/Core/Section.h"
22#include "lldb/Core/Value.h"
26#include "lldb/Utility/Scalar.h"
28#include "lldb/Utility/Timer.h"
29
32
34#include "lldb/Host/Host.h"
35
38
42#include "lldb/Symbol/Block.h"
51#include "lldb/Symbol/TypeMap.h"
54
56#include "lldb/Target/Target.h"
57
58#include "AppleDWARFIndex.h"
59#include "DWARFASTParser.h"
60#include "DWARFASTParserClang.h"
61#include "DWARFCompileUnit.h"
62#include "DWARFDebugAbbrev.h"
63#include "DWARFDebugAranges.h"
64#include "DWARFDebugInfo.h"
65#include "DWARFDebugMacro.h"
66#include "DWARFDebugRanges.h"
67#include "DWARFDeclContext.h"
68#include "DWARFFormValue.h"
69#include "DWARFTypeUnit.h"
70#include "DWARFUnit.h"
72#include "LogChannelDWARF.h"
73#include "ManualDWARFIndex.h"
75#include "SymbolFileDWARFDwo.h"
76
77#include "llvm/DebugInfo/DWARF/DWARFContext.h"
78#include "llvm/Support/FileSystem.h"
79#include "llvm/Support/FormatVariadic.h"
80
81#include <algorithm>
82#include <map>
83#include <memory>
84#include <optional>
85
86#include <cctype>
87#include <cstring>
88
89//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
90
91#ifdef ENABLE_DEBUG_PRINTF
92#include <cstdio>
93#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
94#else
95#define DEBUG_PRINTF(fmt, ...)
96#endif
97
98using namespace lldb;
99using namespace lldb_private;
100using namespace lldb_private::dwarf;
101
103
105
106namespace {
107
108#define LLDB_PROPERTIES_symbolfiledwarf
109#include "SymbolFileDWARFProperties.inc"
110
111enum {
112#define LLDB_PROPERTIES_symbolfiledwarf
113#include "SymbolFileDWARFPropertiesEnum.inc"
114};
115
116class PluginProperties : public Properties {
117public:
118 static ConstString GetSettingName() {
120 }
121
122 PluginProperties() {
123 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
124 m_collection_sp->Initialize(g_symbolfiledwarf_properties);
125 }
126
127 bool IgnoreFileIndexes() const {
128 return m_collection_sp->GetPropertyAtIndexAsBoolean(
129 nullptr, ePropertyIgnoreIndexes, false);
130 }
131};
132
133} // namespace
134
135static PluginProperties &GetGlobalPluginProperties() {
136 static PluginProperties g_settings;
137 return g_settings;
138}
139
140static const llvm::DWARFDebugLine::LineTable *
142 llvm::DWARFDebugLine &line, dw_offset_t line_offset,
143 dw_offset_t unit_offset) {
144 Log *log = GetLog(DWARFLog::DebugInfo);
145
146 llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVM();
147 llvm::DWARFContext &ctx = context.GetAsLLVM();
148 llvm::Expected<const llvm::DWARFDebugLine::LineTable *> line_table =
149 line.getOrParseLineTable(
150 data, line_offset, ctx, nullptr, [&](llvm::Error e) {
152 log, std::move(e),
153 "SymbolFileDWARF::ParseLineTable failed to parse: {0}");
154 });
155
156 if (!line_table) {
157 LLDB_LOG_ERROR(log, line_table.takeError(),
158 "SymbolFileDWARF::ParseLineTable failed to parse: {0}");
159 return nullptr;
160 }
161 return *line_table;
162}
163
165 llvm::DWARFDebugLine::Prologue &prologue,
166 dw_offset_t line_offset,
167 dw_offset_t unit_offset) {
168 Log *log = GetLog(DWARFLog::DebugInfo);
169 bool success = true;
170 llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVM();
171 llvm::DWARFContext &ctx = context.GetAsLLVM();
172 uint64_t offset = line_offset;
173 llvm::Error error = prologue.parse(
174 data, &offset,
175 [&](llvm::Error e) {
176 success = false;
177 LLDB_LOG_ERROR(log, std::move(e),
178 "SymbolFileDWARF::ParseSupportFiles failed to parse "
179 "line table prologue: {0}");
180 },
181 ctx, nullptr);
182 if (error) {
183 LLDB_LOG_ERROR(log, std::move(error),
184 "SymbolFileDWARF::ParseSupportFiles failed to parse line "
185 "table prologue: {0}");
186 return false;
187 }
188 return success;
189}
190
191static std::optional<std::string>
192GetFileByIndex(const llvm::DWARFDebugLine::Prologue &prologue, size_t idx,
193 llvm::StringRef compile_dir, FileSpec::Style style) {
194 // Try to get an absolute path first.
195 std::string abs_path;
196 auto absolute = llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath;
197 if (prologue.getFileNameByIndex(idx, compile_dir, absolute, abs_path, style))
198 return std::move(abs_path);
199
200 // Otherwise ask for a relative path.
201 std::string rel_path;
202 auto relative = llvm::DILineInfoSpecifier::FileLineInfoKind::RawValue;
203 if (!prologue.getFileNameByIndex(idx, compile_dir, relative, rel_path, style))
204 return {};
205 return std::move(rel_path);
206}
207
208static FileSpecList
209ParseSupportFilesFromPrologue(const lldb::ModuleSP &module,
210 const llvm::DWARFDebugLine::Prologue &prologue,
211 FileSpec::Style style,
212 llvm::StringRef compile_dir = {}) {
213 FileSpecList support_files;
214 size_t first_file = 0;
215 if (prologue.getVersion() <= 4) {
216 // File index 0 is not valid before DWARF v5. Add a dummy entry to ensure
217 // support file list indices match those we get from the debug info and line
218 // tables.
219 support_files.Append(FileSpec());
220 first_file = 1;
221 }
222
223 const size_t number_of_files = prologue.FileNames.size();
224 for (size_t idx = first_file; idx <= number_of_files; ++idx) {
225 std::string remapped_file;
226 if (auto file_path = GetFileByIndex(prologue, idx, compile_dir, style)) {
227 if (auto remapped = module->RemapSourceFile(llvm::StringRef(*file_path)))
228 remapped_file = *remapped;
229 else
230 remapped_file = std::move(*file_path);
231 }
232
233 // Unconditionally add an entry, so the indices match up.
234 support_files.EmplaceBack(remapped_file, style);
235 }
236
237 return support_files;
238}
239
246}
247
250 debugger, PluginProperties::GetSettingName())) {
251 const bool is_global_setting = true;
253 debugger, GetGlobalPluginProperties().GetValueProperties(),
254 ConstString("Properties for the dwarf symbol-file plug-in."),
255 is_global_setting);
256 }
257}
258
263}
264
266 return "DWARF and DWARF3 debug symbol file reader.";
267}
268
270 return new SymbolFileDWARF(std::move(objfile_sp),
271 /*dwo_section_list*/ nullptr);
272}
273
275 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
276 if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())
277 return debug_map_symfile->GetTypeList();
279}
280void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
281 dw_offset_t max_die_offset, uint32_t type_mask,
282 TypeSet &type_set) {
283 if (die) {
284 const dw_offset_t die_offset = die.GetOffset();
285
286 if (die_offset >= max_die_offset)
287 return;
288
289 if (die_offset >= min_die_offset) {
290 const dw_tag_t tag = die.Tag();
291
292 bool add_type = false;
293
294 switch (tag) {
295 case DW_TAG_array_type:
296 add_type = (type_mask & eTypeClassArray) != 0;
297 break;
298 case DW_TAG_unspecified_type:
299 case DW_TAG_base_type:
300 add_type = (type_mask & eTypeClassBuiltin) != 0;
301 break;
302 case DW_TAG_class_type:
303 add_type = (type_mask & eTypeClassClass) != 0;
304 break;
305 case DW_TAG_structure_type:
306 add_type = (type_mask & eTypeClassStruct) != 0;
307 break;
308 case DW_TAG_union_type:
309 add_type = (type_mask & eTypeClassUnion) != 0;
310 break;
311 case DW_TAG_enumeration_type:
312 add_type = (type_mask & eTypeClassEnumeration) != 0;
313 break;
314 case DW_TAG_subroutine_type:
315 case DW_TAG_subprogram:
316 case DW_TAG_inlined_subroutine:
317 add_type = (type_mask & eTypeClassFunction) != 0;
318 break;
319 case DW_TAG_pointer_type:
320 add_type = (type_mask & eTypeClassPointer) != 0;
321 break;
322 case DW_TAG_rvalue_reference_type:
323 case DW_TAG_reference_type:
324 add_type = (type_mask & eTypeClassReference) != 0;
325 break;
326 case DW_TAG_typedef:
327 add_type = (type_mask & eTypeClassTypedef) != 0;
328 break;
329 case DW_TAG_ptr_to_member_type:
330 add_type = (type_mask & eTypeClassMemberPointer) != 0;
331 break;
332 default:
333 break;
334 }
335
336 if (add_type) {
337 const bool assert_not_being_parsed = true;
338 Type *type = ResolveTypeUID(die, assert_not_being_parsed);
339 if (type)
340 type_set.insert(type);
341 }
342 }
343
344 for (DWARFDIE child_die : die.children()) {
345 GetTypes(child_die, min_die_offset, max_die_offset, type_mask, type_set);
346 }
347 }
348}
349
351 TypeClass type_mask, TypeList &type_list)
352
353{
354 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
355 TypeSet type_set;
356
357 CompileUnit *comp_unit = nullptr;
358 if (sc_scope)
359 comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
360
361 const auto &get = [&](DWARFUnit *unit) {
362 if (!unit)
363 return;
364 unit = &unit->GetNonSkeletonUnit();
365 GetTypes(unit->DIE(), unit->GetOffset(), unit->GetNextUnitOffset(),
366 type_mask, type_set);
367 };
368 if (comp_unit) {
369 get(GetDWARFCompileUnit(comp_unit));
370 } else {
371 DWARFDebugInfo &info = DebugInfo();
372 const size_t num_cus = info.GetNumUnits();
373 for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx)
374 get(info.GetUnitAtIndex(cu_idx));
375 }
376
377 std::set<CompilerType> compiler_type_set;
378 for (Type *type : type_set) {
379 CompilerType compiler_type = type->GetForwardCompilerType();
380 if (compiler_type_set.find(compiler_type) == compiler_type_set.end()) {
381 compiler_type_set.insert(compiler_type);
382 type_list.Insert(type->shared_from_this());
383 }
384 }
385}
386
387// Gets the first parent that is a lexical block, function or inlined
388// subroutine, or compile unit.
391 DWARFDIE die;
392 for (die = child_die.GetParent(); die; die = die.GetParent()) {
393 dw_tag_t tag = die.Tag();
394
395 switch (tag) {
396 case DW_TAG_compile_unit:
397 case DW_TAG_partial_unit:
398 case DW_TAG_subprogram:
399 case DW_TAG_inlined_subroutine:
400 case DW_TAG_lexical_block:
401 return die;
402 default:
403 break;
404 }
405 }
406 return DWARFDIE();
407}
408
409SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp,
410 SectionList *dwo_section_list)
411 : SymbolFileCommon(std::move(objfile_sp)), m_debug_map_module_wp(),
412 m_debug_map_symfile(nullptr),
413 m_context(m_objfile_sp->GetModule()->GetSectionList(), dwo_section_list),
414 m_fetched_external_modules(false),
415 m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
416
418
420 static ConstString g_dwarf_section_name("__DWARF");
421 return g_dwarf_section_name;
422}
423
425 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
426 if (debug_map_symfile)
427 return debug_map_symfile->GetUniqueDWARFASTTypeMap();
428 else
430}
431
432llvm::Expected<lldb::TypeSystemSP>
434 if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())
435 return debug_map_symfile->GetTypeSystemForLanguage(language);
436
437 auto type_system_or_err =
438 m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
439 if (type_system_or_err)
440 if (auto ts = *type_system_or_err)
441 ts->SetSymbolFile(this);
442 return type_system_or_err;
443}
444
446 Log *log = GetLog(DWARFLog::DebugInfo);
447
449
450 if (!GetGlobalPluginProperties().IgnoreFileIndexes()) {
451 StreamString module_desc;
452 GetObjectFile()->GetModule()->GetDescription(module_desc.AsRawOstream(),
454 DWARFDataExtractor apple_names, apple_namespaces, apple_types, apple_objc;
459
460 if (apple_names.GetByteSize() > 0 || apple_namespaces.GetByteSize() > 0 ||
461 apple_types.GetByteSize() > 0 || apple_objc.GetByteSize() > 0) {
462 Progress progress(llvm::formatv("Loading Apple DWARF index for {0}",
463 module_desc.GetData()));
465 *GetObjectFile()->GetModule(), apple_names, apple_namespaces,
466 apple_types, apple_objc, m_context.getOrLoadStrData());
467
468 if (m_index)
469 return;
470 }
471
472 DWARFDataExtractor debug_names;
474 if (debug_names.GetByteSize() > 0) {
475 Progress progress(
476 llvm::formatv("Loading DWARF5 index for {0}", module_desc.GetData()));
477 llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or =
479 debug_names,
480 m_context.getOrLoadStrData(), *this);
481 if (index_or) {
482 m_index = std::move(*index_or);
483 return;
484 }
485 LLDB_LOG_ERROR(log, index_or.takeError(),
486 "Unable to read .debug_names data: {0}");
487 }
488 }
489
490 m_index =
491 std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(), *this);
492}
493
496 *m_objfile_sp->GetModule()->GetSectionList());
499}
500
502 const lldb_private::SectionList &section_list) {
503 for (SectionSP section_sp : section_list) {
504 if (section_sp->GetChildren().GetSize() > 0) {
505 InitializeFirstCodeAddressRecursive(section_sp->GetChildren());
506 } else if (section_sp->GetType() == eSectionTypeCode) {
508 std::min(m_first_code_address, section_sp->GetFileAddress());
509 }
510 }
511}
512
514 return version >= 2 && version <= 5;
515}
516
518 uint32_t abilities = 0;
519 if (m_objfile_sp != nullptr) {
520 const Section *section = nullptr;
521 const SectionList *section_list = m_objfile_sp->GetSectionList();
522 if (section_list == nullptr)
523 return 0;
524
525 uint64_t debug_abbrev_file_size = 0;
526 uint64_t debug_info_file_size = 0;
527 uint64_t debug_line_file_size = 0;
528
529 section = section_list->FindSectionByName(GetDWARFMachOSegmentName()).get();
530
531 if (section)
532 section_list = &section->GetChildren();
533
534 section =
535 section_list->FindSectionByType(eSectionTypeDWARFDebugInfo, true).get();
536 if (section != nullptr) {
537 debug_info_file_size = section->GetFileSize();
538
539 section =
541 .get();
542 if (section)
543 debug_abbrev_file_size = section->GetFileSize();
544
545 DWARFDebugAbbrev *abbrev = DebugAbbrev();
546 if (abbrev) {
547 std::set<dw_form_t> invalid_forms;
548 abbrev->GetUnsupportedForms(invalid_forms);
549 if (!invalid_forms.empty()) {
551 error.Printf("unsupported DW_FORM value%s:",
552 invalid_forms.size() > 1 ? "s" : "");
553 for (auto form : invalid_forms)
554 error.Printf(" %#x", form);
555 m_objfile_sp->GetModule()->ReportWarning(
556 "{0}", error.GetString().str().c_str());
557 return 0;
558 }
559 }
560
561 section =
563 .get();
564 if (section)
565 debug_line_file_size = section->GetFileSize();
566 } else {
567 llvm::StringRef symfile_dir =
568 m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef();
569 if (symfile_dir.contains_insensitive(".dsym")) {
570 if (m_objfile_sp->GetType() == ObjectFile::eTypeDebugInfo) {
571 // We have a dSYM file that didn't have a any debug info. If the
572 // string table has a size of 1, then it was made from an
573 // executable with no debug info, or from an executable that was
574 // stripped.
575 section =
577 .get();
578 if (section && section->GetFileSize() == 1) {
579 m_objfile_sp->GetModule()->ReportWarning(
580 "empty dSYM file detected, dSYM was created with an "
581 "executable with no debug info.");
582 }
583 }
584 }
585 }
586
587 constexpr uint64_t MaxDebugInfoSize = (1ull) << DW_DIE_OFFSET_MAX_BITSIZE;
588 if (debug_info_file_size >= MaxDebugInfoSize) {
589 m_objfile_sp->GetModule()->ReportWarning(
590 "SymbolFileDWARF can't load this DWARF. It's larger then {0:x+16}",
591 MaxDebugInfoSize);
592 return 0;
593 }
594
595 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
596 abilities |= CompileUnits | Functions | Blocks | GlobalVariables |
598
599 if (debug_line_file_size > 0)
600 abilities |= LineTables;
601 }
602 return abilities;
603}
604
606 DWARFDataExtractor &data) {
607 ModuleSP module_sp(m_objfile_sp->GetModule());
608 const SectionList *section_list = module_sp->GetSectionList();
609 if (!section_list)
610 return;
611
612 SectionSP section_sp(section_list->FindSectionByType(sect_type, true));
613 if (!section_sp)
614 return;
615
616 data.Clear();
617 m_objfile_sp->ReadSectionData(section_sp.get(), data);
618}
619
621 if (m_abbr)
622 return m_abbr.get();
623
624 const DWARFDataExtractor &debug_abbrev_data = m_context.getOrLoadAbbrevData();
625 if (debug_abbrev_data.GetByteSize() == 0)
626 return nullptr;
627
628 auto abbr = std::make_unique<DWARFDebugAbbrev>();
629 llvm::Error error = abbr->parse(debug_abbrev_data);
630 if (error) {
631 Log *log = GetLog(DWARFLog::DebugInfo);
632 LLDB_LOG_ERROR(log, std::move(error),
633 "Unable to read .debug_abbrev section: {0}");
634 return nullptr;
635 }
636
637 m_abbr = std::move(abbr);
638 return m_abbr.get();
639}
640
642 llvm::call_once(m_info_once_flag, [&] {
643 LLDB_SCOPED_TIMERF("%s this = %p", LLVM_PRETTY_FUNCTION,
644 static_cast<void *>(this));
645 m_info = std::make_unique<DWARFDebugInfo>(*this, m_context);
646 });
647 return *m_info;
648}
649
651 if (!comp_unit)
652 return nullptr;
653
654 // The compile unit ID is the index of the DWARF unit.
655 DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(comp_unit->GetID());
656 if (dwarf_cu && dwarf_cu->GetUserData() == nullptr)
657 dwarf_cu->SetUserData(comp_unit);
658
659 // It must be DWARFCompileUnit when it created a CompileUnit.
660 return llvm::cast_or_null<DWARFCompileUnit>(dwarf_cu);
661}
662
664 if (!m_ranges) {
665 LLDB_SCOPED_TIMERF("%s this = %p", LLVM_PRETTY_FUNCTION,
666 static_cast<void *>(this));
667
669 m_ranges = std::make_unique<DWARFDebugRanges>();
670
671 if (m_ranges)
672 m_ranges->Extract(m_context);
673 }
674 return m_ranges.get();
675}
676
677/// Make an absolute path out of \p file_spec and remap it using the
678/// module's source remapping dictionary.
679static void MakeAbsoluteAndRemap(FileSpec &file_spec, DWARFUnit &dwarf_cu,
680 const ModuleSP &module_sp) {
681 if (!file_spec)
682 return;
683 // If we have a full path to the compile unit, we don't need to
684 // resolve the file. This can be expensive e.g. when the source
685 // files are NFS mounted.
686 file_spec.MakeAbsolute(dwarf_cu.GetCompilationDirectory());
687
688 if (auto remapped_file = module_sp->RemapSourceFile(file_spec.GetPath()))
689 file_spec.SetFile(*remapped_file, FileSpec::Style::native);
690}
691
692/// Return the DW_AT_(GNU_)dwo_name.
693static const char *GetDWOName(DWARFCompileUnit &dwarf_cu,
694 const DWARFDebugInfoEntry &cu_die) {
695 const char *dwo_name =
696 cu_die.GetAttributeValueAsString(&dwarf_cu, DW_AT_GNU_dwo_name, nullptr);
697 if (!dwo_name)
698 dwo_name =
699 cu_die.GetAttributeValueAsString(&dwarf_cu, DW_AT_dwo_name, nullptr);
700 return dwo_name;
701}
702
704 CompUnitSP cu_sp;
705 CompileUnit *comp_unit = (CompileUnit *)dwarf_cu.GetUserData();
706 if (comp_unit) {
707 // We already parsed this compile unit, had out a shared pointer to it
708 cu_sp = comp_unit->shared_from_this();
709 } else {
710 if (GetDebugMapSymfile()) {
711 // Let the debug map create the compile unit
712 cu_sp = m_debug_map_symfile->GetCompileUnit(this, dwarf_cu);
713 dwarf_cu.SetUserData(cu_sp.get());
714 } else {
715 ModuleSP module_sp(m_objfile_sp->GetModule());
716 if (module_sp) {
717 auto initialize_cu = [&](const FileSpec &file_spec,
718 LanguageType cu_language) {
720 cu_sp = std::make_shared<CompileUnit>(
721 module_sp, &dwarf_cu, file_spec,
722 *GetDWARFUnitIndex(dwarf_cu.GetID()), cu_language,
724
725 dwarf_cu.SetUserData(cu_sp.get());
726
727 SetCompileUnitAtIndex(dwarf_cu.GetID(), cu_sp);
728 };
729
730 auto lazy_initialize_cu = [&]() {
731 // If the version is < 5, we can't do lazy initialization.
732 if (dwarf_cu.GetVersion() < 5)
733 return false;
734
735 // If there is no DWO, there is no reason to initialize
736 // lazily; we will do eager initialization in that case.
737 if (GetDebugMapSymfile())
738 return false;
739 const DWARFBaseDIE cu_die = dwarf_cu.GetUnitDIEOnly();
740 if (!cu_die)
741 return false;
742 if (!GetDWOName(dwarf_cu, *cu_die.GetDIE()))
743 return false;
744
745 // With DWARFv5 we can assume that the first support
746 // file is also the name of the compile unit. This
747 // allows us to avoid loading the non-skeleton unit,
748 // which may be in a separate DWO file.
749 FileSpecList support_files;
750 if (!ParseSupportFiles(dwarf_cu, module_sp, support_files))
751 return false;
752 if (support_files.GetSize() == 0)
753 return false;
754
755 initialize_cu(support_files.GetFileSpecAtIndex(0),
757 cu_sp->SetSupportFiles(std::move(support_files));
758 return true;
759 };
760
761 if (!lazy_initialize_cu()) {
762 // Eagerly initialize compile unit
763 const DWARFBaseDIE cu_die =
765 if (cu_die) {
767 dwarf_cu.GetDWARFLanguageType());
768
769 FileSpec cu_file_spec(cu_die.GetName(), dwarf_cu.GetPathStyle());
770
771 // Path needs to be remapped in this case. In the support files
772 // case ParseSupportFiles takes care of the remapping.
773 MakeAbsoluteAndRemap(cu_file_spec, dwarf_cu, module_sp);
774
775 initialize_cu(cu_file_spec, cu_language);
776 }
777 }
778 }
779 }
780 }
781 return cu_sp;
782}
783
785 if (!m_lldb_cu_to_dwarf_unit.empty())
786 return;
787
788 DWARFDebugInfo &info = DebugInfo();
789 if (!info.ContainsTypeUnits()) {
790 // We can use a 1-to-1 mapping. No need to build a translation table.
791 return;
792 }
793 for (uint32_t i = 0, num = info.GetNumUnits(); i < num; ++i) {
794 if (auto *cu = llvm::dyn_cast<DWARFCompileUnit>(info.GetUnitAtIndex(i))) {
795 cu->SetID(m_lldb_cu_to_dwarf_unit.size());
796 m_lldb_cu_to_dwarf_unit.push_back(i);
797 }
798 }
799}
800
801std::optional<uint32_t> SymbolFileDWARF::GetDWARFUnitIndex(uint32_t cu_idx) {
803 if (m_lldb_cu_to_dwarf_unit.empty())
804 return cu_idx;
805 if (cu_idx >= m_lldb_cu_to_dwarf_unit.size())
806 return std::nullopt;
807 return m_lldb_cu_to_dwarf_unit[cu_idx];
808}
809
814}
815
817 ASSERT_MODULE_LOCK(this);
818 if (std::optional<uint32_t> dwarf_idx = GetDWARFUnitIndex(cu_idx)) {
819 if (auto *dwarf_cu = llvm::cast_or_null<DWARFCompileUnit>(
820 DebugInfo().GetUnitAtIndex(*dwarf_idx)))
821 return ParseCompileUnit(*dwarf_cu);
822 }
823 return {};
824}
825
827 const DWARFDIE &die) {
828 ASSERT_MODULE_LOCK(this);
829 if (!die.IsValid())
830 return nullptr;
831
832 auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));
833 if (auto err = type_system_or_err.takeError()) {
834 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
835 "Unable to parse function");
836 return nullptr;
837 }
838 auto ts = *type_system_or_err;
839 if (!ts)
840 return nullptr;
841 DWARFASTParser *dwarf_ast = ts->GetDWARFParser();
842 if (!dwarf_ast)
843 return nullptr;
844
845 DWARFRangeList ranges;
846 if (die.GetDIE()->GetAttributeAddressRanges(die.GetCU(), ranges,
847 /*check_hi_lo_pc=*/true) == 0)
848 return nullptr;
849
850 // Union of all ranges in the function DIE (if the function is
851 // discontiguous)
852 lldb::addr_t lowest_func_addr = ranges.GetMinRangeBase(0);
853 lldb::addr_t highest_func_addr = ranges.GetMaxRangeEnd(0);
854 if (lowest_func_addr == LLDB_INVALID_ADDRESS ||
855 lowest_func_addr >= highest_func_addr ||
856 lowest_func_addr < m_first_code_address)
857 return nullptr;
858
859 ModuleSP module_sp(die.GetModule());
860 AddressRange func_range;
862 lowest_func_addr, module_sp->GetSectionList());
863 if (!func_range.GetBaseAddress().IsValid())
864 return nullptr;
865
866 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
867 if (!FixupAddress(func_range.GetBaseAddress()))
868 return nullptr;
869
870 return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die, func_range);
871}
872
875 ASSERT_MODULE_LOCK(this);
876 if (!die.IsValid()) {
877 return ConstString();
878 }
879
880 auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));
881 if (auto err = type_system_or_err.takeError()) {
882 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
883 "Unable to construct demangled name for function");
884 return ConstString();
885 }
886
887 auto ts = *type_system_or_err;
888 if (!ts) {
889 LLDB_LOG(GetLog(LLDBLog::Symbols), "Type system no longer live");
890 return ConstString();
891 }
892 DWARFASTParser *dwarf_ast = ts->GetDWARFParser();
893 if (!dwarf_ast)
894 return ConstString();
895
896 return dwarf_ast->ConstructDemangledNameFromDWARF(die);
897}
898
900 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
901 if (debug_map_symfile)
902 return debug_map_symfile->LinkOSOFileAddress(this, file_addr);
903 return file_addr;
904}
905
907 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
908 if (debug_map_symfile) {
909 return debug_map_symfile->LinkOSOAddress(addr);
910 }
911 // This is a normal DWARF file, no address fixups need to happen
912 return true;
913}
915 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
916 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
917 if (dwarf_cu)
918 return GetLanguage(dwarf_cu->GetNonSkeletonUnit());
919 else
921}
922
924 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
925 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
926 if (!dwarf_cu)
927 return {};
928 const DWARFBaseDIE cu_die = dwarf_cu->GetNonSkeletonUnit().GetUnitDIEOnly();
929 if (!cu_die)
930 return {};
931 const char *sdk = cu_die.GetAttributeValueAsString(DW_AT_APPLE_sdk, nullptr);
932 if (!sdk)
933 return {};
934 const char *sysroot =
935 cu_die.GetAttributeValueAsString(DW_AT_LLVM_sysroot, "");
936 // Register the sysroot path remapping with the module belonging to
937 // the CU as well as the one belonging to the symbol file. The two
938 // would be different if this is an OSO object and module is the
939 // corresponding debug map, in which case both should be updated.
940 ModuleSP module_sp = comp_unit.GetModule();
941 if (module_sp)
942 module_sp->RegisterXcodeSDK(sdk, sysroot);
943
944 ModuleSP local_module_sp = m_objfile_sp->GetModule();
945 if (local_module_sp && local_module_sp != module_sp)
946 local_module_sp->RegisterXcodeSDK(sdk, sysroot);
947
948 return {sdk};
949}
950
953 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
954 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
955 if (!dwarf_cu)
956 return 0;
957
958 size_t functions_added = 0;
959 dwarf_cu = &dwarf_cu->GetNonSkeletonUnit();
960 for (DWARFDebugInfoEntry &entry : dwarf_cu->dies()) {
961 if (entry.Tag() != DW_TAG_subprogram)
962 continue;
963
964 DWARFDIE die(dwarf_cu, &entry);
965 if (comp_unit.FindFunctionByUID(die.GetID()))
966 continue;
967 if (ParseFunction(comp_unit, die))
968 ++functions_added;
969 }
970 // FixupTypes();
971 return functions_added;
972}
973
975 CompileUnit &comp_unit,
976 llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files,
977 llvm::function_ref<bool(Module &)> lambda) {
978 // Only visit each symbol file once.
979 if (!visited_symbol_files.insert(this).second)
980 return false;
981
983 for (auto &p : m_external_type_modules) {
984 ModuleSP module = p.second;
985 if (!module)
986 continue;
987
988 // Invoke the action and potentially early-exit.
989 if (lambda(*module))
990 return true;
991
992 for (std::size_t i = 0; i < module->GetNumCompileUnits(); ++i) {
993 auto cu = module->GetCompileUnitAtIndex(i);
994 bool early_exit = cu->ForEachExternalModule(visited_symbol_files, lambda);
995 if (early_exit)
996 return true;
997 }
998 }
999 return false;
1000}
1001
1003 FileSpecList &support_files) {
1004 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1005 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
1006 if (!dwarf_cu)
1007 return false;
1008
1009 if (!ParseSupportFiles(*dwarf_cu, comp_unit.GetModule(), support_files))
1010 return false;
1011
1012 comp_unit.SetSupportFiles(support_files);
1013 return true;
1014}
1015
1017 const ModuleSP &module,
1018 FileSpecList &support_files) {
1019
1020 dw_offset_t offset = dwarf_cu.GetLineTableOffset();
1021 if (offset == DW_INVALID_OFFSET)
1022 return false;
1023
1025 llvm::DWARFDebugLine::Prologue prologue;
1026 if (!ParseLLVMLineTablePrologue(m_context, prologue, offset,
1027 dwarf_cu.GetOffset()))
1028 return false;
1029
1030 std::string comp_dir = dwarf_cu.GetCompilationDirectory().GetPath();
1031 support_files = ParseSupportFilesFromPrologue(
1032 module, prologue, dwarf_cu.GetPathStyle(), comp_dir);
1033 return true;
1034}
1035
1037 if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(&unit)) {
1038 if (CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(*dwarf_cu))
1039 return lldb_cu->GetSupportFiles().GetFileSpecAtIndex(file_idx);
1040 return FileSpec();
1041 }
1042
1043 auto &tu = llvm::cast<DWARFTypeUnit>(unit);
1044 return GetTypeUnitSupportFiles(tu).GetFileSpecAtIndex(file_idx);
1045}
1046
1047const FileSpecList &
1049 static FileSpecList empty_list;
1050
1051 dw_offset_t offset = tu.GetLineTableOffset();
1052 if (offset == DW_INVALID_OFFSET ||
1053 offset == llvm::DenseMapInfo<dw_offset_t>::getEmptyKey() ||
1054 offset == llvm::DenseMapInfo<dw_offset_t>::getTombstoneKey())
1055 return empty_list;
1056
1057 // Many type units can share a line table, so parse the support file list
1058 // once, and cache it based on the offset field.
1059 auto iter_bool = m_type_unit_support_files.try_emplace(offset);
1060 FileSpecList &list = iter_bool.first->second;
1061 if (iter_bool.second) {
1062 uint64_t line_table_offset = offset;
1063 llvm::DWARFDataExtractor data = m_context.getOrLoadLineData().GetAsLLVM();
1064 llvm::DWARFContext &ctx = m_context.GetAsLLVM();
1065 llvm::DWARFDebugLine::Prologue prologue;
1066 auto report = [](llvm::Error error) {
1067 Log *log = GetLog(DWARFLog::DebugInfo);
1068 LLDB_LOG_ERROR(log, std::move(error),
1069 "SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse "
1070 "the line table prologue");
1071 };
1073 llvm::Error error = prologue.parse(data, &line_table_offset, report, ctx);
1074 if (error) {
1075 report(std::move(error));
1076 } else {
1077 list = ParseSupportFilesFromPrologue(GetObjectFile()->GetModule(),
1078 prologue, tu.GetPathStyle());
1079 }
1080 }
1081 return list;
1082}
1083
1085 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1086 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
1087 if (dwarf_cu)
1088 return dwarf_cu->GetNonSkeletonUnit().GetIsOptimized();
1089 return false;
1090}
1091
1094 std::vector<SourceModule> &imported_modules) {
1095 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1096 assert(sc.comp_unit);
1097 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1098 if (!dwarf_cu)
1099 return false;
1101 sc.comp_unit->GetLanguage()))
1102 return false;
1104
1105 const DWARFDIE die = dwarf_cu->DIE();
1106 if (!die)
1107 return false;
1108
1109 for (DWARFDIE child_die : die.children()) {
1110 if (child_die.Tag() != DW_TAG_imported_declaration)
1111 continue;
1112
1113 DWARFDIE module_die = child_die.GetReferencedDIE(DW_AT_import);
1114 if (module_die.Tag() != DW_TAG_module)
1115 continue;
1116
1117 if (const char *name =
1118 module_die.GetAttributeValueAsString(DW_AT_name, nullptr)) {
1119 SourceModule module;
1120 module.path.push_back(ConstString(name));
1121
1122 DWARFDIE parent_die = module_die;
1123 while ((parent_die = parent_die.GetParent())) {
1124 if (parent_die.Tag() != DW_TAG_module)
1125 break;
1126 if (const char *name =
1127 parent_die.GetAttributeValueAsString(DW_AT_name, nullptr))
1128 module.path.push_back(ConstString(name));
1129 }
1130 std::reverse(module.path.begin(), module.path.end());
1131 if (const char *include_path = module_die.GetAttributeValueAsString(
1132 DW_AT_LLVM_include_path, nullptr)) {
1133 FileSpec include_spec(include_path, dwarf_cu->GetPathStyle());
1134 MakeAbsoluteAndRemap(include_spec, *dwarf_cu,
1135 m_objfile_sp->GetModule());
1136 module.search_path = ConstString(include_spec.GetPath());
1137 }
1138 if (const char *sysroot = dwarf_cu->DIE().GetAttributeValueAsString(
1139 DW_AT_LLVM_sysroot, nullptr))
1140 module.sysroot = ConstString(sysroot);
1141 imported_modules.push_back(module);
1142 }
1143 }
1144 return true;
1145}
1146
1148 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1149 if (comp_unit.GetLineTable() != nullptr)
1150 return true;
1151
1152 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
1153 if (!dwarf_cu)
1154 return false;
1155
1156 dw_offset_t offset = dwarf_cu->GetLineTableOffset();
1157 if (offset == DW_INVALID_OFFSET)
1158 return false;
1159
1161 llvm::DWARFDebugLine line;
1162 const llvm::DWARFDebugLine::LineTable *line_table =
1163 ParseLLVMLineTable(m_context, line, offset, dwarf_cu->GetOffset());
1164
1165 if (!line_table)
1166 return false;
1167
1168 // FIXME: Rather than parsing the whole line table and then copying it over
1169 // into LLDB, we should explore using a callback to populate the line table
1170 // while we parse to reduce memory usage.
1171 std::vector<std::unique_ptr<LineSequence>> sequences;
1172 // The Sequences view contains only valid line sequences. Don't iterate over
1173 // the Rows directly.
1174 for (const llvm::DWARFDebugLine::Sequence &seq : line_table->Sequences) {
1175 // Ignore line sequences that do not start after the first code address.
1176 // All addresses generated in a sequence are incremental so we only need
1177 // to check the first one of the sequence. Check the comment at the
1178 // m_first_code_address declaration for more details on this.
1179 if (seq.LowPC < m_first_code_address)
1180 continue;
1181 std::unique_ptr<LineSequence> sequence =
1183 for (unsigned idx = seq.FirstRowIndex; idx < seq.LastRowIndex; ++idx) {
1184 const llvm::DWARFDebugLine::Row &row = line_table->Rows[idx];
1186 sequence.get(), row.Address.Address, row.Line, row.Column, row.File,
1187 row.IsStmt, row.BasicBlock, row.PrologueEnd, row.EpilogueBegin,
1188 row.EndSequence);
1189 }
1190 sequences.push_back(std::move(sequence));
1191 }
1192
1193 std::unique_ptr<LineTable> line_table_up =
1194 std::make_unique<LineTable>(&comp_unit, std::move(sequences));
1195
1196 if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile()) {
1197 // We have an object file that has a line table with addresses that are not
1198 // linked. We need to link the line table and convert the addresses that
1199 // are relative to the .o file into addresses for the main executable.
1200 comp_unit.SetLineTable(
1201 debug_map_symfile->LinkOSOLineTable(this, line_table_up.get()));
1202 } else {
1203 comp_unit.SetLineTable(line_table_up.release());
1204 }
1205
1206 return true;
1207}
1208
1211 auto iter = m_debug_macros_map.find(*offset);
1212 if (iter != m_debug_macros_map.end())
1213 return iter->second;
1214
1216 const DWARFDataExtractor &debug_macro_data = m_context.getOrLoadMacroData();
1217 if (debug_macro_data.GetByteSize() == 0)
1218 return DebugMacrosSP();
1219
1221 m_debug_macros_map[*offset] = debug_macros_sp;
1222
1223 const DWARFDebugMacroHeader &header =
1224 DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset);
1226 debug_macro_data, m_context.getOrLoadStrData(), header.OffsetIs64Bit(),
1227 offset, this, debug_macros_sp);
1228
1229 return debug_macros_sp;
1230}
1231
1233 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1234
1235 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
1236 if (dwarf_cu == nullptr)
1237 return false;
1238
1239 const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly();
1240 if (!dwarf_cu_die)
1241 return false;
1242
1243 lldb::offset_t sect_offset =
1244 dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_macros, DW_INVALID_OFFSET);
1245 if (sect_offset == DW_INVALID_OFFSET)
1246 sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_macros,
1248 if (sect_offset == DW_INVALID_OFFSET)
1249 return false;
1250
1251 comp_unit.SetDebugMacros(ParseDebugMacros(&sect_offset));
1252
1253 return true;
1254}
1255
1257 lldb_private::CompileUnit &comp_unit, Block *parent_block,
1258 const DWARFDIE &orig_die, addr_t subprogram_low_pc, uint32_t depth) {
1259 size_t blocks_added = 0;
1260 DWARFDIE die = orig_die;
1261 while (die) {
1262 dw_tag_t tag = die.Tag();
1263
1264 switch (tag) {
1265 case DW_TAG_inlined_subroutine:
1266 case DW_TAG_subprogram:
1267 case DW_TAG_lexical_block: {
1268 Block *block = nullptr;
1269 if (tag == DW_TAG_subprogram) {
1270 // Skip any DW_TAG_subprogram DIEs that are inside of a normal or
1271 // inlined functions. These will be parsed on their own as separate
1272 // entities.
1273
1274 if (depth > 0)
1275 break;
1276
1277 block = parent_block;
1278 } else {
1279 BlockSP block_sp(new Block(die.GetID()));
1280 parent_block->AddChild(block_sp);
1281 block = block_sp.get();
1282 }
1283 DWARFRangeList ranges;
1284 const char *name = nullptr;
1285 const char *mangled_name = nullptr;
1286
1287 std::optional<int> decl_file;
1288 std::optional<int> decl_line;
1289 std::optional<int> decl_column;
1290 std::optional<int> call_file;
1291 std::optional<int> call_line;
1292 std::optional<int> call_column;
1293 if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file,
1294 decl_line, decl_column, call_file, call_line,
1295 call_column, nullptr)) {
1296 if (tag == DW_TAG_subprogram) {
1297 assert(subprogram_low_pc == LLDB_INVALID_ADDRESS);
1298 subprogram_low_pc = ranges.GetMinRangeBase(0);
1299 } else if (tag == DW_TAG_inlined_subroutine) {
1300 // We get called here for inlined subroutines in two ways. The first
1301 // time is when we are making the Function object for this inlined
1302 // concrete instance. Since we're creating a top level block at
1303 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we
1304 // need to adjust the containing address. The second time is when we
1305 // are parsing the blocks inside the function that contains the
1306 // inlined concrete instance. Since these will be blocks inside the
1307 // containing "real" function the offset will be for that function.
1308 if (subprogram_low_pc == LLDB_INVALID_ADDRESS) {
1309 subprogram_low_pc = ranges.GetMinRangeBase(0);
1310 }
1311 }
1312
1313 const size_t num_ranges = ranges.GetSize();
1314 for (size_t i = 0; i < num_ranges; ++i) {
1315 const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
1316 const addr_t range_base = range.GetRangeBase();
1317 if (range_base >= subprogram_low_pc)
1318 block->AddRange(Block::Range(range_base - subprogram_low_pc,
1319 range.GetByteSize()));
1320 else {
1321 GetObjectFile()->GetModule()->ReportError(
1322 "{0x:+8}: adding range [{1:x16}-{2:x16}) which has a base "
1323 "that is less than the function's low PC {3:x16}. Please file "
1324 "a bug and attach the file at the "
1325 "start of this error message",
1326 block->GetID(), range_base, range.GetRangeEnd(),
1327 subprogram_low_pc);
1328 }
1329 }
1330 block->FinalizeRanges();
1331
1332 if (tag != DW_TAG_subprogram &&
1333 (name != nullptr || mangled_name != nullptr)) {
1334 std::unique_ptr<Declaration> decl_up;
1335 if (decl_file || decl_line || decl_column)
1336 decl_up = std::make_unique<Declaration>(
1337 comp_unit.GetSupportFiles().GetFileSpecAtIndex(
1338 decl_file ? *decl_file : 0),
1339 decl_line ? *decl_line : 0, decl_column ? *decl_column : 0);
1340
1341 std::unique_ptr<Declaration> call_up;
1342 if (call_file || call_line || call_column)
1343 call_up = std::make_unique<Declaration>(
1344 comp_unit.GetSupportFiles().GetFileSpecAtIndex(
1345 call_file ? *call_file : 0),
1346 call_line ? *call_line : 0, call_column ? *call_column : 0);
1347
1348 block->SetInlinedFunctionInfo(name, mangled_name, decl_up.get(),
1349 call_up.get());
1350 }
1351
1352 ++blocks_added;
1353
1354 if (die.HasChildren()) {
1355 blocks_added +=
1356 ParseBlocksRecursive(comp_unit, block, die.GetFirstChild(),
1357 subprogram_low_pc, depth + 1);
1358 }
1359 }
1360 } break;
1361 default:
1362 break;
1363 }
1364
1365 // Only parse siblings of the block if we are not at depth zero. A depth of
1366 // zero indicates we are currently parsing the top level DW_TAG_subprogram
1367 // DIE
1368
1369 if (depth == 0)
1370 die.Clear();
1371 else
1372 die = die.GetSibling();
1373 }
1374 return blocks_added;
1375}
1376
1378 if (parent_die) {
1379 for (DWARFDIE die : parent_die.children()) {
1380 dw_tag_t tag = die.Tag();
1381 bool check_virtuality = false;
1382 switch (tag) {
1383 case DW_TAG_inheritance:
1384 case DW_TAG_subprogram:
1385 check_virtuality = true;
1386 break;
1387 default:
1388 break;
1389 }
1390 if (check_virtuality) {
1391 if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0)
1392 return true;
1393 }
1394 }
1395 }
1396 return false;
1397}
1398
1400 auto *type_system = decl_ctx.GetTypeSystem();
1401 if (type_system != nullptr)
1403 decl_ctx);
1404}
1405
1408
1410 // This method can be called without going through the symbol vendor so we
1411 // need to lock the module.
1412 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1413 // Anytime we have a lldb::user_id_t, we must get the DIE by calling
1414 // SymbolFileDWARF::GetDIE(). See comments inside the
1415 // SymbolFileDWARF::GetDIE() for details.
1416 if (DWARFDIE die = GetDIE(type_uid))
1417 return GetDecl(die);
1418 return CompilerDecl();
1419}
1420
1423 // This method can be called without going through the symbol vendor so we
1424 // need to lock the module.
1425 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1426 // Anytime we have a lldb::user_id_t, we must get the DIE by calling
1427 // SymbolFileDWARF::GetDIE(). See comments inside the
1428 // SymbolFileDWARF::GetDIE() for details.
1429 if (DWARFDIE die = GetDIE(type_uid))
1430 return GetDeclContext(die);
1431 return CompilerDeclContext();
1432}
1433
1436 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1437 // Anytime we have a lldb::user_id_t, we must get the DIE by calling
1438 // SymbolFileDWARF::GetDIE(). See comments inside the
1439 // SymbolFileDWARF::GetDIE() for details.
1440 if (DWARFDIE die = GetDIE(type_uid))
1441 return GetContainingDeclContext(die);
1442 return CompilerDeclContext();
1443}
1444
1446 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1447 // Anytime we have a lldb::user_id_t, we must get the DIE by calling
1448 // SymbolFileDWARF::GetDIE(). See comments inside the
1449 // SymbolFileDWARF::GetDIE() for details.
1450 if (DWARFDIE type_die = GetDIE(type_uid))
1451 return type_die.ResolveType();
1452 else
1453 return nullptr;
1454}
1455
1456std::optional<SymbolFile::ArrayInfo> SymbolFileDWARF::GetDynamicArrayInfoForUID(
1457 lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
1458 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1459 if (DWARFDIE type_die = GetDIE(type_uid))
1460 return DWARFASTParser::ParseChildArrayInfo(type_die, exe_ctx);
1461 else
1462 return std::nullopt;
1463}
1464
1466 return ResolveType(GetDIE(die_ref), true);
1467}
1468
1470 bool assert_not_being_parsed) {
1471 if (die) {
1472 Log *log = GetLog(DWARFLog::DebugInfo);
1473 if (log)
1474 GetObjectFile()->GetModule()->LogMessage(
1475 log, "SymbolFileDWARF::ResolveTypeUID (die = {0:x16}) {1} '{2}'",
1476 die.GetOffset(), die.GetTagAsCString(), die.GetName());
1477
1478 // We might be coming in in the middle of a type tree (a class within a
1479 // class, an enum within a class), so parse any needed parent DIEs before
1480 // we get to this one...
1481 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(die);
1482 if (decl_ctx_die) {
1483 if (log) {
1484 switch (decl_ctx_die.Tag()) {
1485 case DW_TAG_structure_type:
1486 case DW_TAG_union_type:
1487 case DW_TAG_class_type: {
1488 // Get the type, which could be a forward declaration
1489 if (log)
1490 GetObjectFile()->GetModule()->LogMessage(
1491 log,
1492 "SymbolFileDWARF::ResolveTypeUID (die = {0:x16}) "
1493 "{1} '{2}' "
1494 "resolve parent forward type for {3:x16})",
1495 die.GetOffset(), die.GetTagAsCString(), die.GetName(),
1496 decl_ctx_die.GetOffset());
1497 } break;
1498
1499 default:
1500 break;
1501 }
1502 }
1503 }
1504 return ResolveType(die);
1505 }
1506 return nullptr;
1507}
1508
1509// This function is used when SymbolFileDWARFDebugMap owns a bunch of
1510// SymbolFileDWARF objects to detect if this DWARF file is the one that can
1511// resolve a compiler_type.
1513 const CompilerType &compiler_type) {
1514 CompilerType compiler_type_no_qualifiers =
1515 ClangUtil::RemoveFastQualifiers(compiler_type);
1516 if (GetForwardDeclClangTypeToDie().count(
1517 compiler_type_no_qualifiers.GetOpaqueQualType())) {
1518 return true;
1519 }
1520 auto type_system = compiler_type.GetTypeSystem();
1521 auto clang_type_system = type_system.dyn_cast_or_null<TypeSystemClang>();
1522 if (!clang_type_system)
1523 return false;
1524 DWARFASTParserClang *ast_parser =
1525 static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
1526 return ast_parser->GetClangASTImporter().CanImport(compiler_type);
1527}
1528
1530 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1531 auto clang_type_system =
1533 if (clang_type_system) {
1534 DWARFASTParserClang *ast_parser =
1535 static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
1536 if (ast_parser &&
1537 ast_parser->GetClangASTImporter().CanImport(compiler_type))
1538 return ast_parser->GetClangASTImporter().CompleteType(compiler_type);
1539 }
1540
1541 // We have a struct/union/class/enum that needs to be fully resolved.
1542 CompilerType compiler_type_no_qualifiers =
1543 ClangUtil::RemoveFastQualifiers(compiler_type);
1544 auto die_it = GetForwardDeclClangTypeToDie().find(
1545 compiler_type_no_qualifiers.GetOpaqueQualType());
1546 if (die_it == GetForwardDeclClangTypeToDie().end()) {
1547 // We have already resolved this type...
1548 return true;
1549 }
1550
1551 DWARFDIE dwarf_die = GetDIE(die_it->getSecond());
1552 if (dwarf_die) {
1553 // Once we start resolving this type, remove it from the forward
1554 // declaration map in case anyone child members or other types require this
1555 // type to get resolved. The type will get resolved when all of the calls
1556 // to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition are done.
1557 GetForwardDeclClangTypeToDie().erase(die_it);
1558
1559 Type *type = GetDIEToType().lookup(dwarf_die.GetDIE());
1560
1561 Log *log = GetLog(DWARFLog::DebugInfo | DWARFLog::TypeCompletion);
1562 if (log)
1563 GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
1564 log, "{0:x8}: {1} '{2}' resolving forward declaration...",
1565 dwarf_die.GetID(), dwarf_die.GetTagAsCString(),
1566 type->GetName().AsCString());
1567 assert(compiler_type);
1568 if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetCU()))
1569 return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type);
1570 }
1571 return false;
1572}
1573
1575 bool assert_not_being_parsed,
1576 bool resolve_function_context) {
1577 if (die) {
1578 Type *type = GetTypeForDIE(die, resolve_function_context).get();
1579
1580 if (assert_not_being_parsed) {
1581 if (type != DIE_IS_BEING_PARSED)
1582 return type;
1583
1584 GetObjectFile()->GetModule()->ReportError(
1585 "Parsing a die that is being parsed die: {0:x16}: {1} {2}",
1586 die.GetOffset(), die.GetTagAsCString(), die.GetName());
1587
1588 } else
1589 return type;
1590 }
1591 return nullptr;
1592}
1593
1596 if (dwarf_cu.IsDWOUnit()) {
1597 DWARFCompileUnit *non_dwo_cu =
1598 static_cast<DWARFCompileUnit *>(dwarf_cu.GetUserData());
1599 assert(non_dwo_cu);
1601 *non_dwo_cu);
1602 }
1603 // Check if the symbol vendor already knows about this compile unit?
1604 if (dwarf_cu.GetUserData() == nullptr) {
1605 // The symbol vendor doesn't know about this compile unit, we need to parse
1606 // and add it to the symbol vendor object.
1607 return ParseCompileUnit(dwarf_cu).get();
1608 }
1609 return static_cast<CompileUnit *>(dwarf_cu.GetUserData());
1610}
1611
1613 ConstString class_name, llvm::function_ref<bool(DWARFDIE die)> callback) {
1614 m_index->GetObjCMethods(class_name, callback);
1615}
1616
1618 sc.Clear(false);
1619
1620 if (die && llvm::isa<DWARFCompileUnit>(die.GetCU())) {
1621 // Check if the symbol vendor already knows about this compile unit?
1622 sc.comp_unit =
1623 GetCompUnitForDWARFCompUnit(llvm::cast<DWARFCompileUnit>(*die.GetCU()));
1624
1625 sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
1626 if (sc.function == nullptr)
1627 sc.function = ParseFunction(*sc.comp_unit, die);
1628
1629 if (sc.function) {
1631 return true;
1632 }
1633 }
1634
1635 return false;
1636}
1637
1640 const auto &pos = m_external_type_modules.find(name);
1641 if (pos != m_external_type_modules.end())
1642 return pos->second;
1643 else
1644 return lldb::ModuleSP();
1645}
1646
1649 // This method can be called without going through the symbol vendor so we
1650 // need to lock the module.
1651 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1652
1653 SymbolFileDWARF *symbol_file = nullptr;
1654
1655 // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we
1656 // must make sure we use the correct DWARF file when resolving things. On
1657 // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
1658 // SymbolFileDWARF classes, one for each .o file. We can often end up with
1659 // references to other DWARF objects and we must be ready to receive a
1660 // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
1661 // instance.
1662 std::optional<uint32_t> file_index = die_ref.file_index();
1663 if (file_index) {
1664 if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) {
1665 symbol_file = debug_map->GetSymbolFileByOSOIndex(*file_index); // OSO case
1666 if (symbol_file)
1667 return symbol_file->DebugInfo().GetDIE(die_ref);
1668 return DWARFDIE();
1669 }
1670
1671 if (*file_index == DIERef::k_file_index_mask)
1672 symbol_file = m_dwp_symfile.get(); // DWP case
1673 else
1674 symbol_file = this->DebugInfo()
1675 .GetUnitAtIndex(*die_ref.file_index())
1676 ->GetDwoSymbolFile(); // DWO case
1677 } else if (die_ref.die_offset() == DW_INVALID_OFFSET) {
1678 return DWARFDIE();
1679 }
1680
1681 if (symbol_file)
1682 return symbol_file->GetDIE(die_ref);
1683
1684 return DebugInfo().GetDIE(die_ref);
1685}
1686
1687/// Return the DW_AT_(GNU_)dwo_id.
1688static std::optional<uint64_t> GetDWOId(DWARFCompileUnit &dwarf_cu,
1689 const DWARFDebugInfoEntry &cu_die) {
1690 std::optional<uint64_t> dwo_id =
1691 cu_die.GetAttributeValueAsOptionalUnsigned(&dwarf_cu, DW_AT_GNU_dwo_id);
1692 if (dwo_id)
1693 return dwo_id;
1694 return cu_die.GetAttributeValueAsOptionalUnsigned(&dwarf_cu, DW_AT_dwo_id);
1695}
1696
1697std::optional<uint64_t> SymbolFileDWARF::GetDWOId() {
1698 if (GetNumCompileUnits() == 1) {
1699 if (auto comp_unit = GetCompileUnitAtIndex(0))
1700 if (DWARFCompileUnit *cu = GetDWARFCompileUnit(comp_unit.get()))
1701 if (DWARFDebugInfoEntry *cu_die = cu->DIE().GetDIE())
1702 return ::GetDWOId(*cu, *cu_die);
1703 }
1704 return {};
1705}
1706
1707std::shared_ptr<SymbolFileDWARFDwo>
1709 DWARFUnit &unit, const DWARFDebugInfoEntry &cu_die) {
1710 // If this is a Darwin-style debug map (non-.dSYM) symbol file,
1711 // never attempt to load ELF-style DWO files since the -gmodules
1712 // support uses the same DWO mechanism to specify full debug info
1713 // files for modules. This is handled in
1714 // UpdateExternalModuleListIfNeeded().
1715 if (GetDebugMapSymfile())
1716 return nullptr;
1717
1718 DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(&unit);
1719 // Only compile units can be split into two parts and we should only
1720 // look for a DWO file if there is a valid DWO ID.
1721 if (!dwarf_cu || !dwarf_cu->GetDWOId().has_value())
1722 return nullptr;
1723
1724 const char *dwo_name = GetDWOName(*dwarf_cu, cu_die);
1725 if (!dwo_name) {
1727 "missing DWO name in skeleton DIE {0:x16}", cu_die.GetOffset()));
1728 return nullptr;
1729 }
1730
1731 if (std::shared_ptr<SymbolFileDWARFDwo> dwp_sp = GetDwpSymbolFile())
1732 return dwp_sp;
1733
1734 const char *comp_dir = nullptr;
1735 FileSpec dwo_file(dwo_name);
1736 FileSystem::Instance().Resolve(dwo_file);
1737 if (dwo_file.IsRelative()) {
1738 comp_dir = cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_comp_dir,
1739 nullptr);
1740 if (!comp_dir) {
1742 "unable to locate relative .dwo debug file \"{0}\" for "
1743 "skeleton DIE {1:x16} without valid DW_AT_comp_dir "
1744 "attribute",
1745 dwo_name, cu_die.GetOffset()));
1746 return nullptr;
1747 }
1748
1749 dwo_file.SetFile(comp_dir, FileSpec::Style::native);
1750 if (dwo_file.IsRelative()) {
1751 // if DW_AT_comp_dir is relative, it should be relative to the location
1752 // of the executable, not to the location from which the debugger was
1753 // launched.
1754 dwo_file.PrependPathComponent(
1755 m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef());
1756 }
1757 FileSystem::Instance().Resolve(dwo_file);
1758 dwo_file.AppendPathComponent(dwo_name);
1759 }
1760
1761 if (!FileSystem::Instance().Exists(dwo_file)) {
1763 "unable to locate .dwo debug file \"{0}\" for skeleton DIE "
1764 "{1:x16}",
1765 dwo_file.GetPath().c_str(), cu_die.GetOffset()));
1766
1767 if (m_dwo_warning_issued.test_and_set(std::memory_order_relaxed) == false) {
1768 GetObjectFile()->GetModule()->ReportWarning(
1769 "unable to locate separate debug file (dwo, dwp). Debugging will be "
1770 "degraded.");
1771 }
1772 return nullptr;
1773 }
1774
1775 const lldb::offset_t file_offset = 0;
1776 DataBufferSP dwo_file_data_sp;
1777 lldb::offset_t dwo_file_data_offset = 0;
1778 ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(
1779 GetObjectFile()->GetModule(), &dwo_file, file_offset,
1780 FileSystem::Instance().GetByteSize(dwo_file), dwo_file_data_sp,
1781 dwo_file_data_offset);
1782 if (dwo_obj_file == nullptr) {
1784 "unable to load object file for .dwo debug file \"{0}\" for "
1785 "unit DIE {1:x16}",
1786 dwo_name, cu_die.GetOffset()));
1787 return nullptr;
1788 }
1789
1790 return std::make_shared<SymbolFileDWARFDwo>(*this, dwo_obj_file,
1791 dwarf_cu->GetID());
1792}
1793
1796 return;
1798 DWARFDebugInfo &debug_info = DebugInfo();
1799
1800 // Follow DWO skeleton unit breadcrumbs.
1801 const uint32_t num_compile_units = GetNumCompileUnits();
1802 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
1803 auto *dwarf_cu =
1804 llvm::dyn_cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(cu_idx));
1805 if (!dwarf_cu)
1806 continue;
1807
1808 const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly();
1809 if (!die || die.HasChildren() || !die.GetDIE())
1810 continue;
1811
1812 const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr);
1813 if (!name)
1814 continue;
1815
1816 ConstString const_name(name);
1817 ModuleSP &module_sp = m_external_type_modules[const_name];
1818 if (module_sp)
1819 continue;
1820
1821 const char *dwo_path = GetDWOName(*dwarf_cu, *die.GetDIE());
1822 if (!dwo_path)
1823 continue;
1824
1825 ModuleSpec dwo_module_spec;
1826 dwo_module_spec.GetFileSpec().SetFile(dwo_path, FileSpec::Style::native);
1827 if (dwo_module_spec.GetFileSpec().IsRelative()) {
1828 const char *comp_dir =
1829 die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr);
1830 if (comp_dir) {
1831 dwo_module_spec.GetFileSpec().SetFile(comp_dir,
1832 FileSpec::Style::native);
1833 FileSystem::Instance().Resolve(dwo_module_spec.GetFileSpec());
1834 dwo_module_spec.GetFileSpec().AppendPathComponent(dwo_path);
1835 }
1836 }
1837 dwo_module_spec.GetArchitecture() =
1838 m_objfile_sp->GetModule()->GetArchitecture();
1839
1840 // When LLDB loads "external" modules it looks at the presence of
1841 // DW_AT_dwo_name. However, when the already created module
1842 // (corresponding to .dwo itself) is being processed, it will see
1843 // the presence of DW_AT_dwo_name (which contains the name of dwo
1844 // file) and will try to call ModuleList::GetSharedModule
1845 // again. In some cases (i.e., for empty files) Clang 4.0
1846 // generates a *.dwo file which has DW_AT_dwo_name, but no
1847 // DW_AT_comp_dir. In this case the method
1848 // ModuleList::GetSharedModule will fail and the warning will be
1849 // printed. However, as one can notice in this case we don't
1850 // actually need to try to load the already loaded module
1851 // (corresponding to .dwo) so we simply skip it.
1852 if (m_objfile_sp->GetFileSpec().GetFileNameExtension() == ".dwo" &&
1853 llvm::StringRef(m_objfile_sp->GetFileSpec().GetPath())
1854 .endswith(dwo_module_spec.GetFileSpec().GetPath())) {
1855 continue;
1856 }
1857
1858 Status error = ModuleList::GetSharedModule(dwo_module_spec, module_sp,
1859 nullptr, nullptr, nullptr);
1860 if (!module_sp) {
1861 GetObjectFile()->GetModule()->ReportWarning(
1862 "{0:x16}: unable to locate module needed for external types: "
1863 "{1}\nerror: {2}\nDebugging will be degraded due to missing "
1864 "types. Rebuilding the project will regenerate the needed "
1865 "module files.",
1866 die.GetOffset(), dwo_module_spec.GetFileSpec().GetPath().c_str(),
1867 error.AsCString("unknown error"));
1868 continue;
1869 }
1870
1871 // Verify the DWO hash.
1872 // FIXME: Technically "0" is a valid hash.
1873 std::optional<uint64_t> dwo_id = ::GetDWOId(*dwarf_cu, *die.GetDIE());
1874 if (!dwo_id)
1875 continue;
1876
1877 auto *dwo_symfile =
1878 llvm::dyn_cast_or_null<SymbolFileDWARF>(module_sp->GetSymbolFile());
1879 if (!dwo_symfile)
1880 continue;
1881 std::optional<uint64_t> dwo_dwo_id = dwo_symfile->GetDWOId();
1882 if (!dwo_dwo_id)
1883 continue;
1884
1885 if (dwo_id != dwo_dwo_id) {
1886 GetObjectFile()->GetModule()->ReportWarning(
1887 "{0:x16}: Module {1} is out-of-date (hash mismatch). Type "
1888 "information "
1889 "from this module may be incomplete or inconsistent with the rest of "
1890 "the program. Rebuilding the project will regenerate the needed "
1891 "module files.",
1892 die.GetOffset(), dwo_module_spec.GetFileSpec().GetPath().c_str());
1893 }
1894 }
1895}
1896
1898 if (!m_global_aranges_up) {
1899 m_global_aranges_up = std::make_unique<GlobalVariableMap>();
1900
1901 ModuleSP module_sp = GetObjectFile()->GetModule();
1902 if (module_sp) {
1903 const size_t num_cus = module_sp->GetNumCompileUnits();
1904 for (size_t i = 0; i < num_cus; ++i) {
1905 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
1906 if (cu_sp) {
1907 VariableListSP globals_sp = cu_sp->GetVariableList(true);
1908 if (globals_sp) {
1909 const size_t num_globals = globals_sp->GetSize();
1910 for (size_t g = 0; g < num_globals; ++g) {
1911 VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
1912 if (var_sp && !var_sp->GetLocationIsConstantValueData()) {
1913 const DWARFExpressionList &location =
1914 var_sp->LocationExpressionList();
1915 Value location_result;
1916 Status error;
1917 ExecutionContext exe_ctx;
1918 if (location.Evaluate(&exe_ctx, nullptr, LLDB_INVALID_ADDRESS,
1919 nullptr, nullptr, location_result,
1920 &error)) {
1921 if (location_result.GetValueType() ==
1922 Value::ValueType::FileAddress) {
1923 lldb::addr_t file_addr =
1924 location_result.GetScalar().ULongLong();
1925 lldb::addr_t byte_size = 1;
1926 if (var_sp->GetType())
1927 byte_size =
1928 var_sp->GetType()->GetByteSize(nullptr).value_or(0);
1930 file_addr, byte_size, var_sp.get()));
1931 }
1932 }
1933 }
1934 }
1935 }
1936 }
1937 }
1938 }
1939 m_global_aranges_up->Sort();
1940 }
1941 return *m_global_aranges_up;
1942}
1943
1945 bool lookup_block,
1946 SymbolContext &sc) {
1947 assert(sc.comp_unit);
1948 DWARFCompileUnit &cu =
1950 DWARFDIE function_die = cu.LookupAddress(file_vm_addr);
1951 DWARFDIE block_die;
1952 if (function_die) {
1953 sc.function = sc.comp_unit->FindFunctionByUID(function_die.GetID()).get();
1954 if (sc.function == nullptr)
1955 sc.function = ParseFunction(*sc.comp_unit, function_die);
1956
1957 if (sc.function && lookup_block)
1958 block_die = function_die.LookupDeepestBlock(file_vm_addr);
1959 }
1960
1961 if (!sc.function || !lookup_block)
1962 return;
1963
1964 Block &block = sc.function->GetBlock(true);
1965 if (block_die)
1966 sc.block = block.FindBlockByID(block_die.GetID());
1967 else
1968 sc.block = block.FindBlockByID(function_die.GetID());
1969}
1970
1972 SymbolContextItem resolve_scope,
1973 SymbolContext &sc) {
1974 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1975 LLDB_SCOPED_TIMERF("SymbolFileDWARF::"
1976 "ResolveSymbolContext (so_addr = { "
1977 "section = %p, offset = 0x%" PRIx64
1978 " }, resolve_scope = 0x%8.8x)",
1979 static_cast<void *>(so_addr.GetSection().get()),
1980 so_addr.GetOffset(), resolve_scope);
1981 uint32_t resolved = 0;
1982 if (resolve_scope &
1983 (eSymbolContextCompUnit | eSymbolContextFunction | eSymbolContextBlock |
1984 eSymbolContextLineEntry | eSymbolContextVariable)) {
1985 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1986
1987 DWARFDebugInfo &debug_info = DebugInfo();
1988 const DWARFDebugAranges &aranges = debug_info.GetCompileUnitAranges();
1989 const dw_offset_t cu_offset = aranges.FindAddress(file_vm_addr);
1990 if (cu_offset == DW_INVALID_OFFSET) {
1991 // Global variables are not in the compile unit address ranges. The only
1992 // way to currently find global variables is to iterate over the
1993 // .debug_pubnames or the __apple_names table and find all items in there
1994 // that point to DW_TAG_variable DIEs and then find the address that
1995 // matches.
1996 if (resolve_scope & eSymbolContextVariable) {
1998 const GlobalVariableMap::Entry *entry =
1999 map.FindEntryThatContains(file_vm_addr);
2000 if (entry && entry->data) {
2001 Variable *variable = entry->data;
2002 SymbolContextScope *scc = variable->GetSymbolContextScope();
2003 if (scc) {
2004 scc->CalculateSymbolContext(&sc);
2005 sc.variable = variable;
2006 }
2007 return sc.GetResolvedMask();
2008 }
2009 }
2010 } else {
2011 uint32_t cu_idx = DW_INVALID_INDEX;
2012 if (auto *dwarf_cu = llvm::dyn_cast_or_null<DWARFCompileUnit>(
2013 debug_info.GetUnitAtOffset(DIERef::Section::DebugInfo, cu_offset,
2014 &cu_idx))) {
2015 sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
2016 if (sc.comp_unit) {
2017 resolved |= eSymbolContextCompUnit;
2018
2019 bool force_check_line_table = false;
2020 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) {
2021 ResolveFunctionAndBlock(file_vm_addr,
2022 resolve_scope & eSymbolContextBlock, sc);
2023 if (sc.function)
2024 resolved |= eSymbolContextFunction;
2025 else {
2026 // We might have had a compile unit that had discontiguous address
2027 // ranges where the gaps are symbols that don't have any debug
2028 // info. Discontiguous compile unit address ranges should only
2029 // happen when there aren't other functions from other compile
2030 // units in these gaps. This helps keep the size of the aranges
2031 // down.
2032 force_check_line_table = true;
2033 }
2034 if (sc.block)
2035 resolved |= eSymbolContextBlock;
2036 }
2037
2038 if ((resolve_scope & eSymbolContextLineEntry) ||
2039 force_check_line_table) {
2040 LineTable *line_table = sc.comp_unit->GetLineTable();
2041 if (line_table != nullptr) {
2042 // And address that makes it into this function should be in terms
2043 // of this debug file if there is no debug map, or it will be an
2044 // address in the .o file which needs to be fixed up to be in
2045 // terms of the debug map executable. Either way, calling
2046 // FixupAddress() will work for us.
2047 Address exe_so_addr(so_addr);
2048 if (FixupAddress(exe_so_addr)) {
2049 if (line_table->FindLineEntryByAddress(exe_so_addr,
2050 sc.line_entry)) {
2051 resolved |= eSymbolContextLineEntry;
2052 }
2053 }
2054 }
2055 }
2056
2057 if (force_check_line_table && !(resolved & eSymbolContextLineEntry)) {
2058 // We might have had a compile unit that had discontiguous address
2059 // ranges where the gaps are symbols that don't have any debug info.
2060 // Discontiguous compile unit address ranges should only happen when
2061 // there aren't other functions from other compile units in these
2062 // gaps. This helps keep the size of the aranges down.
2063 sc.comp_unit = nullptr;
2064 resolved &= ~eSymbolContextCompUnit;
2065 }
2066 } else {
2067 GetObjectFile()->GetModule()->ReportWarning(
2068 "{0:x16}: compile unit {1} failed to create a valid "
2069 "lldb_private::CompileUnit class.",
2070 cu_offset, cu_idx);
2071 }
2072 }
2073 }
2074 }
2075 return resolved;
2076}
2077
2079 const SourceLocationSpec &src_location_spec,
2080 SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
2081 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2082 const bool check_inlines = src_location_spec.GetCheckInlines();
2083 const uint32_t prev_size = sc_list.GetSize();
2084 if (resolve_scope & eSymbolContextCompUnit) {
2085 for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;
2086 ++cu_idx) {
2087 CompileUnit *dc_cu = ParseCompileUnitAtIndex(cu_idx).get();
2088 if (!dc_cu)
2089 continue;
2090
2091 bool file_spec_matches_cu_file_spec = FileSpec::Match(
2092 src_location_spec.GetFileSpec(), dc_cu->GetPrimaryFile());
2093 if (check_inlines || file_spec_matches_cu_file_spec) {
2094 dc_cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list);
2095 if (!check_inlines)
2096 break;
2097 }
2098 }
2099 }
2100 return sc_list.GetSize() - prev_size;
2101}
2102
2104 // Get the symbol table for the symbol file prior to taking the module lock
2105 // so that it is available without needing to take the module lock. The DWARF
2106 // indexing might end up needing to relocate items when DWARF sections are
2107 // loaded as they might end up getting the section contents which can call
2108 // ObjectFileELF::RelocateSection() which in turn will ask for the symbol
2109 // table and can cause deadlocks.
2110 GetSymtab();
2111 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2112 m_index->Preload();
2113}
2114
2115std::recursive_mutex &SymbolFileDWARF::GetModuleMutex() const {
2116 lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());
2117 if (module_sp)
2118 return module_sp->GetMutex();
2119 return GetObjectFile()->GetModule()->GetMutex();
2120}
2121
2123 const lldb_private::CompilerDeclContext &decl_ctx) {
2124 if (!decl_ctx.IsValid()) {
2125 // Invalid namespace decl which means we aren't matching only things in
2126 // this symbol file, so return true to indicate it matches this symbol
2127 // file.
2128 return true;
2129 }
2130
2131 TypeSystem *decl_ctx_type_system = decl_ctx.GetTypeSystem();
2132 auto type_system_or_err = GetTypeSystemForLanguage(
2133 decl_ctx_type_system->GetMinimumLanguage(nullptr));
2134 if (auto err = type_system_or_err.takeError()) {
2135 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
2136 "Unable to match namespace decl using TypeSystem");
2137 return false;
2138 }
2139
2140 if (decl_ctx_type_system == type_system_or_err->get())
2141 return true; // The type systems match, return true
2142
2143 // The namespace AST was valid, and it does not match...
2144 Log *log = GetLog(DWARFLog::Lookups);
2145
2146 if (log)
2147 GetObjectFile()->GetModule()->LogMessage(
2148 log, "Valid namespace does not match symbol file");
2149
2150 return false;
2151}
2152
2154 ConstString name, const CompilerDeclContext &parent_decl_ctx,
2155 uint32_t max_matches, VariableList &variables) {
2156 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2157 Log *log = GetLog(DWARFLog::Lookups);
2158
2159 if (log)
2160 GetObjectFile()->GetModule()->LogMessage(
2161 log,
2162 "SymbolFileDWARF::FindGlobalVariables (name=\"{0}\", "
2163 "parent_decl_ctx={1:p}, max_matches={2}, variables)",
2164 name.GetCString(), static_cast<const void *>(&parent_decl_ctx),
2165 max_matches);
2166
2167 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2168 return;
2169
2170 // Remember how many variables are in the list before we search.
2171 const uint32_t original_size = variables.GetSize();
2172
2173 llvm::StringRef basename;
2174 llvm::StringRef context;
2175 bool name_is_mangled = Mangled::GetManglingScheme(name.GetStringRef()) !=
2176 Mangled::eManglingSchemeNone;
2177
2179 context, basename))
2180 basename = name.GetStringRef();
2181
2182 // Loop invariant: Variables up to this index have been checked for context
2183 // matches.
2184 uint32_t pruned_idx = original_size;
2185
2186 SymbolContext sc;
2187 m_index->GetGlobalVariables(ConstString(basename), [&](DWARFDIE die) {
2188 if (!sc.module_sp)
2189 sc.module_sp = m_objfile_sp->GetModule();
2190 assert(sc.module_sp);
2191
2192 if (die.Tag() != DW_TAG_variable)
2193 return true;
2194
2195 auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
2196 if (!dwarf_cu)
2197 return true;
2198 sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
2199
2200 if (parent_decl_ctx) {
2201 if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) {
2202 CompilerDeclContext actual_parent_decl_ctx =
2203 dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
2204
2205 /// If the actual namespace is inline (i.e., had a DW_AT_export_symbols)
2206 /// and a child (possibly through other layers of inline namespaces)
2207 /// of the namespace referred to by 'basename', allow the lookup to
2208 /// succeed.
2209 if (!actual_parent_decl_ctx ||
2210 (actual_parent_decl_ctx != parent_decl_ctx &&
2211 !parent_decl_ctx.IsContainedInLookup(actual_parent_decl_ctx)))
2212 return true;
2213 }
2214 }
2215
2216 ParseAndAppendGlobalVariable(sc, die, variables);
2217 while (pruned_idx < variables.GetSize()) {
2218 VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx);
2219 if (name_is_mangled ||
2220 var_sp->GetName().GetStringRef().contains(name.GetStringRef()))
2221 ++pruned_idx;
2222 else
2223 variables.RemoveVariableAtIndex(pruned_idx);
2224 }
2225
2226 return variables.GetSize() - original_size < max_matches;
2227 });
2228
2229 // Return the number of variable that were appended to the list
2230 const uint32_t num_matches = variables.GetSize() - original_size;
2231 if (log && num_matches > 0) {
2232 GetObjectFile()->GetModule()->LogMessage(
2233 log,
2234 "SymbolFileDWARF::FindGlobalVariables (name=\"{0}\", "
2235 "parent_decl_ctx={1:p}, max_matches={2}, variables) => {3}",
2236 name.GetCString(), static_cast<const void *>(&parent_decl_ctx),
2237 max_matches, num_matches);
2238 }
2239}
2240
2242 uint32_t max_matches,
2243 VariableList &variables) {
2244 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2245 Log *log = GetLog(DWARFLog::Lookups);
2246
2247 if (log) {
2248 GetObjectFile()->GetModule()->LogMessage(
2249 log,
2250 "SymbolFileDWARF::FindGlobalVariables (regex=\"{0}\", "
2251 "max_matches={1}, variables)",
2252 regex.GetText().str().c_str(), max_matches);
2253 }
2254
2255 // Remember how many variables are in the list before we search.
2256 const uint32_t original_size = variables.GetSize();
2257
2258 SymbolContext sc;
2259 m_index->GetGlobalVariables(regex, [&](DWARFDIE die) {
2260 if (!sc.module_sp)
2261 sc.module_sp = m_objfile_sp->GetModule();
2262 assert(sc.module_sp);
2263
2264 DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
2265 if (!dwarf_cu)
2266 return true;
2267 sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
2268
2269 ParseAndAppendGlobalVariable(sc, die, variables);
2270
2271 return variables.GetSize() - original_size < max_matches;
2272 });
2273}
2274
2276 bool include_inlines,
2277 SymbolContextList &sc_list) {
2278 SymbolContext sc;
2279
2280 if (!orig_die)
2281 return false;
2282
2283 // If we were passed a die that is not a function, just return false...
2284 if (!(orig_die.Tag() == DW_TAG_subprogram ||
2285 (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine)))
2286 return false;
2287
2288 DWARFDIE die = orig_die;
2289 DWARFDIE inlined_die;
2290 if (die.Tag() == DW_TAG_inlined_subroutine) {
2291 inlined_die = die;
2292
2293 while (true) {
2294 die = die.GetParent();
2295
2296 if (die) {
2297 if (die.Tag() == DW_TAG_subprogram)
2298 break;
2299 } else
2300 break;
2301 }
2302 }
2303 assert(die && die.Tag() == DW_TAG_subprogram);
2304 if (GetFunction(die, sc)) {
2305 Address addr;
2306 // Parse all blocks if needed
2307 if (inlined_die) {
2308 Block &function_block = sc.function->GetBlock(true);
2309 sc.block = function_block.FindBlockByID(inlined_die.GetID());
2310 if (sc.block == nullptr)
2311 sc.block = function_block.FindBlockByID(inlined_die.GetOffset());
2312 if (sc.block == nullptr || !sc.block->GetStartAddress(addr))
2313 addr.Clear();
2314 } else {
2315 sc.block = nullptr;
2317 }
2318
2319 sc_list.Append(sc);
2320 return true;
2321 }
2322
2323 return false;
2324}
2325
2327 const DWARFDIE &die) {
2328 // If we have no parent decl context to match this DIE matches, and if the
2329 // parent decl context isn't valid, we aren't trying to look for any
2330 // particular decl context so any die matches.
2331 if (!decl_ctx.IsValid())
2332 return true;
2333
2334 if (die) {
2335 if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) {
2336 if (CompilerDeclContext actual_decl_ctx =
2337 dwarf_ast->GetDeclContextContainingUIDFromDWARF(die))
2338 return decl_ctx.IsContainedInLookup(actual_decl_ctx);
2339 }
2340 }
2341 return false;
2342}
2343
2345 const CompilerDeclContext &parent_decl_ctx,
2346 bool include_inlines,
2347 SymbolContextList &sc_list) {
2348 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2349 ConstString name = lookup_info.GetLookupName();
2350 FunctionNameType name_type_mask = lookup_info.GetNameTypeMask();
2351
2352 // eFunctionNameTypeAuto should be pre-resolved by a call to
2353 // Module::LookupInfo::LookupInfo()
2354 assert((name_type_mask & eFunctionNameTypeAuto) == 0);
2355
2356 Log *log = GetLog(DWARFLog::Lookups);
2357
2358 if (log) {
2359 GetObjectFile()->GetModule()->LogMessage(
2360 log,
2361 "SymbolFileDWARF::FindFunctions (name=\"{0}\", name_type_mask={1:x}, "
2362 "sc_list)",
2363 name.GetCString(), name_type_mask);
2364 }
2365
2366 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2367 return;
2368
2369 // If name is empty then we won't find anything.
2370 if (name.IsEmpty())
2371 return;
2372
2373 // Remember how many sc_list are in the list before we search in case we are
2374 // appending the results to a variable list.
2375
2376 const uint32_t original_size = sc_list.GetSize();
2377
2378 llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
2379
2380 m_index->GetFunctions(lookup_info, *this, parent_decl_ctx, [&](DWARFDIE die) {
2381 if (resolved_dies.insert(die.GetDIE()).second)
2382 ResolveFunction(die, include_inlines, sc_list);
2383 return true;
2384 });
2385 // With -gsimple-template-names, a templated type's DW_AT_name will not
2386 // contain the template parameters. Try again stripping '<' and anything
2387 // after, filtering out entries with template parameters that don't match.
2388 {
2389 const llvm::StringRef name_ref = name.GetStringRef();
2390 auto it = name_ref.find('<');
2391 if (it != llvm::StringRef::npos) {
2392 const llvm::StringRef name_no_template_params = name_ref.slice(0, it);
2393
2394 Module::LookupInfo no_tp_lookup_info(lookup_info);
2395 no_tp_lookup_info.SetLookupName(ConstString(name_no_template_params));
2396 m_index->GetFunctions(no_tp_lookup_info, *this, parent_decl_ctx, [&](DWARFDIE die) {
2397 if (resolved_dies.insert(die.GetDIE()).second)
2398 ResolveFunction(die, include_inlines, sc_list);
2399 return true;
2400 });
2401 }
2402 }
2403
2404 // Return the number of variable that were appended to the list
2405 const uint32_t num_matches = sc_list.GetSize() - original_size;
2406
2407 if (log && num_matches > 0) {
2408 GetObjectFile()->GetModule()->LogMessage(
2409 log,
2410 "SymbolFileDWARF::FindFunctions (name=\"{0}\", "
2411 "name_type_mask={1:x}, include_inlines={2:d}, sc_list) => {3}",
2412 name.GetCString(), name_type_mask, include_inlines, num_matches);
2413 }
2414}
2415
2417 bool include_inlines,
2418 SymbolContextList &sc_list) {
2419 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2420 LLDB_SCOPED_TIMERF("SymbolFileDWARF::FindFunctions (regex = '%s')",
2421 regex.GetText().str().c_str());
2422
2423 Log *log = GetLog(DWARFLog::Lookups);
2424
2425 if (log) {
2426 GetObjectFile()->GetModule()->LogMessage(
2427 log, "SymbolFileDWARF::FindFunctions (regex=\"{0}\", sc_list)",
2428 regex.GetText().str().c_str());
2429 }
2430
2431 llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
2432 m_index->GetFunctions(regex, [&](DWARFDIE die) {
2433 if (resolved_dies.insert(die.GetDIE()).second)
2434 ResolveFunction(die, include_inlines, sc_list);
2435 return true;
2436 });
2437}
2438
2440 const std::string &scope_qualified_name,
2441 std::vector<ConstString> &mangled_names) {
2442 DWARFDebugInfo &info = DebugInfo();
2443 uint32_t num_comp_units = info.GetNumUnits();
2444 for (uint32_t i = 0; i < num_comp_units; i++) {
2445 DWARFUnit *cu = info.GetUnitAtIndex(i);
2446 if (cu == nullptr)
2447 continue;
2448
2450 if (dwo)
2451 dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names);
2452 }
2453
2454 for (DIERef die_ref :
2455 m_function_scope_qualified_name_map.lookup(scope_qualified_name)) {
2456 DWARFDIE die = GetDIE(die_ref);
2457 mangled_names.push_back(ConstString(die.GetMangledName()));
2458 }
2459}
2460
2462 ConstString name, const CompilerDeclContext &parent_decl_ctx,
2463 uint32_t max_matches,
2464 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
2465 TypeMap &types) {
2466 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2467 // Make sure we haven't already searched this SymbolFile before.
2468 if (!searched_symbol_files.insert(this).second)
2469 return;
2470
2471 Log *log = GetLog(DWARFLog::Lookups);
2472
2473 if (log) {
2474 if (parent_decl_ctx)
2475 GetObjectFile()->GetModule()->LogMessage(
2476 log,
2477 "SymbolFileDWARF::FindTypes (sc, name=\"{0}\", parent_decl_ctx = "
2478 "{1:p} (\"{2}\"), max_matches={3}, type_list)",
2479 name.GetCString(), static_cast<const void *>(&parent_decl_ctx),
2480 parent_decl_ctx.GetName().AsCString("<NULL>"), max_matches);
2481 else
2482 GetObjectFile()->GetModule()->LogMessage(
2483 log,
2484 "SymbolFileDWARF::FindTypes (sc, name=\"{0}\", parent_decl_ctx = "
2485 "NULL, max_matches={1}, type_list)",
2486 name.GetCString(), max_matches);
2487 }
2488
2489 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2490 return;
2491
2492 // Unlike FindFunctions(), FindTypes() following cannot produce false
2493 // positives.
2494
2495 const llvm::StringRef name_ref = name.GetStringRef();
2496 auto name_bracket_index = name_ref.find('<');
2497 m_index->GetTypes(name, [&](DWARFDIE die) {
2498 if (!DIEInDeclContext(parent_decl_ctx, die))
2499 return true; // The containing decl contexts don't match
2500
2501 Type *matching_type = ResolveType(die, true, true);
2502 if (!matching_type)
2503 return true;
2504
2505 // With -gsimple-template-names, a templated type's DW_AT_name will not
2506 // contain the template parameters. Make sure that if the original query
2507 // didn't contain a '<', we filter out entries with template parameters.
2508 if (name_bracket_index == llvm::StringRef::npos &&
2509 matching_type->IsTemplateType())
2510 return true;
2511
2512 // We found a type pointer, now find the shared pointer form our type
2513 // list
2514 types.InsertUnique(matching_type->shared_from_this());
2515 return types.GetSize() < max_matches;
2516 });
2517
2518 // With -gsimple-template-names, a templated type's DW_AT_name will not
2519 // contain the template parameters. Try again stripping '<' and anything
2520 // after, filtering out entries with template parameters that don't match.
2521 if (types.GetSize() < max_matches) {
2522 if (name_bracket_index != llvm::StringRef::npos) {
2523 const llvm::StringRef name_no_template_params =
2524 name_ref.slice(0, name_bracket_index);
2525 const llvm::StringRef template_params =
2526 name_ref.slice(name_bracket_index, name_ref.size());
2527 m_index->GetTypes(ConstString(name_no_template_params), [&](DWARFDIE die) {
2528 if (!DIEInDeclContext(parent_decl_ctx, die))
2529 return true; // The containing decl contexts don't match
2530
2531 const llvm::StringRef base_name = GetTypeForDIE(die)->GetBaseName().AsCString();
2532 auto it = base_name.find('<');
2533 // If the candidate qualified name doesn't have '<', it doesn't have
2534 // template params to compare.
2535 if (it == llvm::StringRef::npos)
2536 return true;
2537
2538 // Filter out non-matching instantiations by comparing template params.
2539 const llvm::StringRef base_name_template_params =
2540 base_name.slice(it, base_name.size());
2541
2542 if (template_params != base_name_template_params)
2543 return true;
2544
2545 Type *matching_type = ResolveType(die, true, true);
2546 if (!matching_type)
2547 return true;
2548
2549 // We found a type pointer, now find the shared pointer form our type
2550 // list.
2551 types.InsertUnique(matching_type->shared_from_this());
2552 return types.GetSize() < max_matches;
2553 });
2554 }
2555 }
2556
2557 // Next search through the reachable Clang modules. This only applies for
2558 // DWARF objects compiled with -gmodules that haven't been processed by
2559 // dsymutil.
2560 if (types.GetSize() < max_matches) {
2562
2563 for (const auto &pair : m_external_type_modules)
2564 if (ModuleSP external_module_sp = pair.second)
2565 if (SymbolFile *sym_file = external_module_sp->GetSymbolFile())
2566 sym_file->FindTypes(name, parent_decl_ctx, max_matches,
2567 searched_symbol_files, types);
2568 }
2569
2570 if (log && types.GetSize()) {
2571 if (parent_decl_ctx) {
2572 GetObjectFile()->GetModule()->LogMessage(
2573 log,
2574 "SymbolFileDWARF::FindTypes (sc, name=\"{0}\", parent_decl_ctx "
2575 "= {1:p} (\"{2}\"), max_matches={3}, type_list) => {4}",
2576 name.GetCString(), static_cast<const void *>(&parent_decl_ctx),
2577 parent_decl_ctx.GetName().AsCString("<NULL>"), max_matches,
2578 types.GetSize());
2579 } else {
2580 GetObjectFile()->GetModule()->LogMessage(
2581 log,
2582 "SymbolFileDWARF::FindTypes (sc, name=\"{0}\", parent_decl_ctx "
2583 "= NULL, max_matches={1}, type_list) => {2}",
2584 name.GetCString(), max_matches, types.GetSize());
2585 }
2586 }
2587}
2588
2590 llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
2591 llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
2592 // Make sure we haven't already searched this SymbolFile before.
2593 if (!searched_symbol_files.insert(this).second)
2594 return;
2595
2596 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2597 if (pattern.empty())
2598 return;
2599
2600 ConstString name = pattern.back().name;
2601
2602 if (!name)
2603 return;
2604
2605 m_index->GetTypes(name, [&](DWARFDIE die) {
2606 if (!languages[GetLanguageFamily(*die.GetCU())])
2607 return true;
2608
2609 llvm::SmallVector<CompilerContext, 4> die_context;
2610 die.GetDeclContext(die_context);
2611 if (!contextMatches(die_context, pattern))
2612 return true;
2613
2614 if (Type *matching_type = ResolveType(die, true, true)) {
2615 // We found a type pointer, now find the shared pointer form our type
2616 // list.
2617 types.InsertUnique(matching_type->shared_from_this());
2618 }
2619 return true;
2620 });
2621
2622 // Next search through the reachable Clang modules. This only applies for
2623 // DWARF objects compiled with -gmodules that haven't been processed by
2624 // dsymutil.
2626
2627 for (const auto &pair : m_external_type_modules)
2628 if (ModuleSP external_module_sp = pair.second)
2629 external_module_sp->FindTypes(pattern, languages, searched_symbol_files,
2630 types);
2631}
2632
2635 const CompilerDeclContext &parent_decl_ctx) {
2636 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2637 Log *log = GetLog(DWARFLog::Lookups);
2638
2639 if (log) {
2640 GetObjectFile()->GetModule()->LogMessage(
2641 log, "SymbolFileDWARF::FindNamespace (sc, name=\"{0}\")",
2642 name.GetCString());
2643 }
2644
2645 CompilerDeclContext namespace_decl_ctx;
2646
2647 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2648 return namespace_decl_ctx;
2649
2650 m_index->GetNamespaces(name, [&](DWARFDIE die) {
2651 if (!DIEInDeclContext(parent_decl_ctx, die))
2652 return true; // The containing decl contexts don't match
2653
2654 DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU());
2655 if (!dwarf_ast)
2656 return true;
2657
2658 namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die);
2659 return !namespace_decl_ctx.IsValid();
2660 });
2661
2662 if (log && namespace_decl_ctx) {
2663 GetObjectFile()->GetModule()->LogMessage(
2664 log,
2665 "SymbolFileDWARF::FindNamespace (sc, name=\"{0}\") => "
2666 "CompilerDeclContext({1:p}/{2:p}) \"{3}\"",
2667 name.GetCString(),
2668 static_cast<const void *>(namespace_decl_ctx.GetTypeSystem()),
2669 static_cast<const void *>(namespace_decl_ctx.GetOpaqueDeclContext()),
2670 namespace_decl_ctx.GetName().AsCString("<NULL>"));
2671 }
2672
2673 return namespace_decl_ctx;
2674}
2675
2677 bool resolve_function_context) {
2678 TypeSP type_sp;
2679 if (die) {
2680 Type *type_ptr = GetDIEToType().lookup(die.GetDIE());
2681 if (type_ptr == nullptr) {
2682 SymbolContextScope *scope;
2683 if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU()))
2684 scope = GetCompUnitForDWARFCompUnit(*dwarf_cu);
2685 else
2686 scope = GetObjectFile()->GetModule().get();
2687 assert(scope);
2688 SymbolContext sc(scope);
2689 const DWARFDebugInfoEntry *parent_die = die.GetParent().GetDIE();
2690 while (parent_die != nullptr) {
2691 if (parent_die->Tag() == DW_TAG_subprogram)
2692 break;
2693 parent_die = parent_die->GetParent();
2694 }
2695 SymbolContext sc_backup = sc;
2696 if (resolve_function_context && parent_die != nullptr &&
2697 !GetFunction(DWARFDIE(die.GetCU(), parent_die), sc))
2698 sc = sc_backup;
2699
2700 type_sp = ParseType(sc, die, nullptr);
2701 } else if (type_ptr != DIE_IS_BEING_PARSED) {
2702 // Get the original shared pointer for this type
2703 type_sp = type_ptr->shared_from_this();
2704 }
2705 }
2706 return type_sp;
2707}
2708
2711 if (orig_die) {
2712 DWARFDIE die = orig_die;
2713
2714 while (die) {
2715 // If this is the original DIE that we are searching for a declaration
2716 // for, then don't look in the cache as we don't want our own decl
2717 // context to be our decl context...
2718 if (orig_die != die) {
2719 switch (die.Tag()) {
2720 case DW_TAG_compile_unit:
2721 case DW_TAG_partial_unit:
2722 case DW_TAG_namespace:
2723 case DW_TAG_structure_type:
2724 case DW_TAG_union_type:
2725 case DW_TAG_class_type:
2726 case DW_TAG_lexical_block:
2727 case DW_TAG_subprogram:
2728 return die;
2729 case DW_TAG_inlined_subroutine: {
2730 DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
2731 if (abs_die) {
2732 return abs_die;
2733 }
2734 break;
2735 }
2736 default:
2737 break;
2738 }
2739 }
2740
2741 DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification);
2742 if (spec_die) {
2743 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die);
2744 if (decl_ctx_die)
2745 return decl_ctx_die;
2746 }
2747
2748 DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
2749 if (abs_die) {
2750 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die);
2751 if (decl_ctx_die)
2752 return decl_ctx_die;
2753 }
2754
2755 die = die.GetParent();
2756 }
2757 }
2758 return DWARFDIE();
2759}
2760
2762 Symbol *objc_class_symbol = nullptr;
2763 if (m_objfile_sp) {
2764 Symtab *symtab = m_objfile_sp->GetSymtab();
2765 if (symtab) {
2766 objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(
2767 objc_class_name, eSymbolTypeObjCClass, Symtab::eDebugNo,
2769 }
2770 }
2771 return objc_class_symbol;
2772}
2773
2774// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If
2775// they don't then we can end up looking through all class types for a complete
2776// type and never find the full definition. We need to know if this attribute
2777// is supported, so we determine this here and cache th result. We also need to
2778// worry about the debug map
2779// DWARF file
2780// if we are doing darwin DWARF in .o file debugging.
2786 else {
2787 DWARFDebugInfo &debug_info = DebugInfo();
2788 const uint32_t num_compile_units = GetNumCompileUnits();
2789 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
2790 DWARFUnit *dwarf_cu = debug_info.GetUnitAtIndex(cu_idx);
2791 if (dwarf_cu != cu &&
2794 break;
2795 }
2796 }
2797 }
2801 }
2803}
2804
2805// This function can be used when a DIE is found that is a forward declaration
2806// DIE and we want to try and find a type that has the complete definition.
2808 const DWARFDIE &die, ConstString type_name, bool must_be_implementation) {
2809
2810 TypeSP type_sp;
2811
2812 if (!type_name || (must_be_implementation && !GetObjCClassSymbol(type_name)))
2813 return type_sp;
2814
2815 m_index->GetCompleteObjCClass(
2816 type_name, must_be_implementation, [&](DWARFDIE type_die) {
2817 bool try_resolving_type = false;
2818
2819 // Don't try and resolve the DIE we are looking for with the DIE
2820 // itself!
2821 if (type_die != die) {
2822 switch (type_die.Tag()) {
2823 case DW_TAG_class_type:
2824 case DW_TAG_structure_type:
2825 try_resolving_type = true;
2826 break;
2827 default:
2828 break;
2829 }
2830 }
2831 if (!try_resolving_type)
2832 return true;
2833
2834 if (must_be_implementation &&
2836 try_resolving_type = type_die.GetAttributeValueAsUnsigned(
2837 DW_AT_APPLE_objc_complete_type, 0);
2838 if (!try_resolving_type)
2839 return true;
2840
2841 Type *resolved_type = ResolveType(type_die, false, true);
2842 if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED)
2843 return true;
2844
2846 "resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64
2847 " (cu 0x%8.8" PRIx64 ")\n",
2848 die.GetID(),
2849 m_objfile_sp->GetFileSpec().GetFilename().AsCString("<Unknown>"),
2850 type_die.GetID(), type_cu->GetID());
2851
2852 if (die)
2853 GetDIEToType()[die.GetDIE()] = resolved_type;
2854 type_sp = resolved_type->shared_from_this();
2855 return false;
2856 });
2857 return type_sp;
2858}
2859
2860// This function helps to ensure that the declaration contexts match for two
2861// different DIEs. Often times debug information will refer to a forward
2862// declaration of a type (the equivalent of "struct my_struct;". There will
2863// often be a declaration of that type elsewhere that has the full definition.
2864// When we go looking for the full type "my_struct", we will find one or more
2865// matches in the accelerator tables and we will then need to make sure the
2866// type was in the same declaration context as the original DIE. This function
2867// can efficiently compare two DIEs and will return true when the declaration
2868// context matches, and false when they don't.
2870 const DWARFDIE &die2) {
2871 if (die1 == die2)
2872 return true;
2873
2874 std::vector<DWARFDIE> decl_ctx_1;
2875 std::vector<DWARFDIE> decl_ctx_2;
2876 // The declaration DIE stack is a stack of the declaration context DIEs all
2877 // the way back to the compile unit. If a type "T" is declared inside a class
2878 // "B", and class "B" is declared inside a class "A" and class "A" is in a
2879 // namespace "lldb", and the namespace is in a compile unit, there will be a
2880 // stack of DIEs:
2881 //
2882 // [0] DW_TAG_class_type for "B"
2883 // [1] DW_TAG_class_type for "A"
2884 // [2] DW_TAG_namespace for "lldb"
2885 // [3] DW_TAG_compile_unit or DW_TAG_partial_unit for the source file.
2886 //
2887 // We grab both contexts and make sure that everything matches all the way
2888 // back to the compiler unit.
2889
2890 // First lets grab the decl contexts for both DIEs
2891 decl_ctx_1 = die1.GetDeclContextDIEs();
2892 decl_ctx_2 = die2.GetDeclContextDIEs();
2893 // Make sure the context arrays have the same size, otherwise we are done
2894 const size_t count1 = decl_ctx_1.size();
2895 const size_t count2 = decl_ctx_2.size();
2896 if (count1 != count2)
2897 return false;
2898
2899 // Make sure the DW_TAG values match all the way back up the compile unit. If
2900 // they don't, then we are done.
2901 DWARFDIE decl_ctx_die1;
2902 DWARFDIE decl_ctx_die2;
2903 size_t i;
2904 for (i = 0; i < count1; i++) {
2905 decl_ctx_die1 = decl_ctx_1[i];
2906 decl_ctx_die2 = decl_ctx_2[i];
2907 if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag())
2908 return false;
2909 }
2910#ifndef NDEBUG
2911
2912 // Make sure the top item in the decl context die array is always
2913 // DW_TAG_compile_unit or DW_TAG_partial_unit. If it isn't then
2914 // something went wrong in the DWARFDIE::GetDeclContextDIEs()
2915 // function.
2916 dw_tag_t cu_tag = decl_ctx_1[count1 - 1].Tag();
2918 assert(cu_tag == DW_TAG_compile_unit || cu_tag == DW_TAG_partial_unit);
2919
2920#endif
2921 // Always skip the compile unit when comparing by only iterating up to "count
2922 // - 1". Here we compare the names as we go.
2923 for (i = 0; i < count1 - 1; i++) {
2924 decl_ctx_die1 = decl_ctx_1[i];
2925 decl_ctx_die2 = decl_ctx_2[i];
2926 const char *name1 = decl_ctx_die1.GetName();
2927 const char *name2 = decl_ctx_die2.GetName();
2928 // If the string was from a DW_FORM_strp, then the pointer will often be
2929 // the same!
2930 if (name1 == name2)
2931 continue;
2932
2933 // Name pointers are not equal, so only compare the strings if both are not
2934 // NULL.
2935 if (name1 && name2) {
2936 // If the strings don't compare, we are done...
2937 if (strcmp(name1, name2) != 0)
2938 return false;
2939 } else {
2940 // One name was NULL while the other wasn't
2941 return false;
2942 }
2943 }
2944 // We made it through all of the checks and the declaration contexts are
2945 // equal.
2946 return true;
2947}
2948
2949TypeSP
2951 TypeSP type_sp;
2952
2953 if (die.GetName()) {
2954 const dw_tag_t tag = die.Tag();
2955
2956 Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
2957 if (log) {
2958 GetObjectFile()->GetModule()->LogMessage(
2959 log,
2960 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%"
2961 "s, name='{0}')",
2962 DW_TAG_value_to_name(tag), die.GetName());
2963 }
2964
2965 // Get the type system that we are looking to find a type for. We will
2966 // use this to ensure any matches we find are in a language that this
2967 // type system supports
2968 const LanguageType language = GetLanguage(*die.GetCU());
2969 TypeSystemSP type_system = nullptr;
2970 if (language != eLanguageTypeUnknown) {
2971 auto type_system_or_err = GetTypeSystemForLanguage(language);
2972 if (auto err = type_system_or_err.takeError()) {
2973 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
2974 "Cannot get TypeSystem for language {}",
2976 } else {
2977 type_system = *type_system_or_err;
2978 }
2979 }
2980
2981 // See comments below about -gsimple-template-names for why we attempt to
2982 // compute missing template parameter names.
2983 ConstString template_params;
2984 if (type_system) {
2985 DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
2986 if (dwarf_ast)
2987 template_params = dwarf_ast->GetDIEClassTemplateParams(die);
2988 }
2989
2990 m_index->GetTypes(GetDWARFDeclContext(die), [&](DWARFDIE type_die) {
2991 // Make sure type_die's language matches the type system we are
2992 // looking for. We don't want to find a "Foo" type from Java if we
2993 // are looking for a "Foo" type for C, C++, ObjC, or ObjC++.
2994 if (type_system &&
2995 !type_system->SupportsLanguage(GetLanguage(*type_die.GetCU())))
2996 return true;
2997 bool try_resolving_type = false;
2998
2999 // Don't try and resolve the DIE we are looking for with the DIE
3000 // itself!
3001 const dw_tag_t type_tag = type_die.Tag();
3002 // Make sure the tags match
3003 if (type_tag == tag) {
3004 // The tags match, lets try resolving this type
3005 try_resolving_type = true;
3006 } else {
3007 // The tags don't match, but we need to watch our for a forward
3008 // declaration for a struct and ("struct foo") ends up being a
3009 // class ("class foo { ... };") or vice versa.
3010 switch (type_tag) {
3011 case DW_TAG_class_type:
3012 // We had a "class foo", see if we ended up with a "struct foo
3013 // { ... };"
3014 try_resolving_type = (tag == DW_TAG_structure_type);
3015 break;
3016 case DW_TAG_structure_type:
3017 // We had a "struct foo", see if we ended up with a "class foo
3018 // { ... };"
3019 try_resolving_type = (tag == DW_TAG_class_type);
3020 break;
3021 default:
3022 // Tags don't match, don't event try to resolve using this type
3023 // whose name matches....
3024 break;
3025 }
3026 }
3027
3028 if (!try_resolving_type) {
3029 if (log) {
3030 GetObjectFile()->GetModule()->LogMessage(
3031 log,
3032 "SymbolFileDWARF::"
3033 "FindDefinitionTypeForDWARFDeclContext(tag={0}, "
3034 "name='{1}') ignoring die={2:x16} ({3})",
3035 DW_TAG_value_to_name(tag), die.GetName(), type_die.GetOffset(),
3036 type_die.GetName());
3037 }
3038 return true;
3039 }
3040
3041 DWARFDeclContext type_dwarf_decl_ctx = GetDWARFDeclContext(type_die);
3042
3043 if (log) {
3044 GetObjectFile()->GetModule()->LogMessage(
3045 log,
3046 "SymbolFileDWARF::"
3047 "FindDefinitionTypeForDWARFDeclContext(tag={0}, "
3048 "name='{1}') trying die={2:x16} ({3})",
3049 DW_TAG_value_to_name(tag), die.GetName(), type_die.GetOffset(),
3050 type_dwarf_decl_ctx.GetQualifiedName());
3051 }
3052
3053 // Make sure the decl contexts match all the way up
3054 if (GetDWARFDeclContext(die) != type_dwarf_decl_ctx)
3055 return true;
3056
3057 Type *resolved_type = ResolveType(type_die, false);
3058 if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED)
3059 return true;
3060
3061 // With -gsimple-template-names, the DIE name may not contain the template
3062 // parameters. If the declaration has template parameters but doesn't
3063 // contain '<', check that the child template parameters match.
3064 if (template_params) {
3065 llvm::StringRef test_base_name =
3066 GetTypeForDIE(type_die)->GetBaseName().GetStringRef();
3067 auto i = test_base_name.find('<');
3068
3069 // Full name from clang AST doesn't contain '<' so this type_die isn't
3070 // a template parameter, but we're expecting template parameters, so
3071 // bail.
3072 if (i == llvm::StringRef::npos)
3073 return true;
3074
3075 llvm::StringRef test_template_params =
3076 test_base_name.slice(i, test_base_name.size());
3077 // Bail if template parameters don't match.
3078 if (test_template_params != template_params.GetStringRef())
3079 return true;
3080 }
3081
3082 type_sp = resolved_type->shared_from_this();
3083 return false;
3084 });
3085 }
3086 return type_sp;
3087}
3088
3090 bool *type_is_new_ptr) {
3091 if (!die)
3092 return {};
3093
3094 auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));
3095 if (auto err = type_system_or_err.takeError()) {
3096 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
3097 "Unable to parse type");
3098 return {};
3099 }
3100 auto ts = *type_system_or_err;
3101 if (!ts)
3102 return {};
3103
3104 DWARFASTParser *dwarf_ast = ts->GetDWARFParser();
3105 if (!dwarf_ast)
3106 return {};
3107
3108 TypeSP type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, type_is_new_ptr);
3109 if (type_sp) {
3110 if (die.Tag() == DW_TAG_subprogram) {
3111 std::string scope_qualified_name(GetDeclContextForUID(die.GetID())
3113 .AsCString(""));
3114 if (scope_qualified_name.size()) {
3115 m_function_scope_qualified_name_map[scope_qualified_name].insert(
3116 *die.GetDIERef());
3117 }
3118 }
3119 }
3120
3121 return type_sp;
3122}
3123
3125 const DWARFDIE &orig_die,
3126 bool parse_siblings, bool parse_children) {
3127 size_t types_added = 0;
3128 DWARFDIE die = orig_die;
3129
3130 while (die) {
3131 const dw_tag_t tag = die.Tag();
3132 bool type_is_new = false;
3133
3134 Tag dwarf_tag = static_cast<Tag>(tag);
3135
3136 // TODO: Currently ParseTypeFromDWARF(...) which is called by ParseType(...)
3137 // does not handle DW_TAG_subrange_type. It is not clear if this is a bug or
3138 // not.
3139 if (isType(dwarf_tag) && tag != DW_TAG_subrange_type)
3140 ParseType(sc, die, &type_is_new);
3141
3142 if (type_is_new)
3143 ++types_added;
3144
3145 if (parse_children && die.HasChildren()) {
3146 if (die.Tag() == DW_TAG_subprogram) {
3147 SymbolContext child_sc(sc);
3148 child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
3149 types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true);
3150 } else
3151 types_added += ParseTypes(sc, die.GetFirstChild(), true, true);
3152 }
3153
3154 if (parse_siblings)
3155 die = die.GetSibling();
3156 else
3157 die.Clear();
3158 }
3159 return types_added;
3160}
3161
3163 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
3164 CompileUnit *comp_unit = func.GetCompileUnit();
3165 lldbassert(comp_unit);
3166
3167 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(comp_unit);
3168 if (!dwarf_cu)
3169 return 0;
3170
3171 size_t functions_added = 0;
3172 const dw_offset_t function_die_offset = DIERef(func.GetID()).die_offset();
3173 DWARFDIE function_die =
3174 dwarf_cu->GetNonSkeletonUnit().GetDIE(function_die_offset);
3175 if (function_die) {
3176 ParseBlocksRecursive(*comp_unit, &func.GetBlock(false), function_die,
3178 }
3179
3180 return functions_added;
3181}
3182
3184 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
3185 size_t types_added = 0;
3186 DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
3187 if (dwarf_cu) {
3188 DWARFDIE dwarf_cu_die = dwarf_cu->DIE();
3189 if (dwarf_cu_die && dwarf_cu_die.HasChildren()) {
3190 SymbolContext sc;
3191 sc.comp_unit = &comp_unit;
3192 types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true);
3193 }
3194 }
3195
3196 return types_added;
3197}
3198
3200 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
3201 if (sc.comp_unit != nullptr) {
3202 if (sc.function) {
3203 DWARFDIE function_die = GetDIE(sc.function->GetID());
3204
3205 dw_addr_t func_lo_pc = LLDB_INVALID_ADDRESS;
3206 DWARFRangeList ranges;
3207 if (function_die.GetDIE()->GetAttributeAddressRanges(
3208 function_die.GetCU(), ranges,
3209 /*check_hi_lo_pc=*/true))
3210 func_lo_pc = ranges.GetMinRangeBase(0);
3211 if (func_lo_pc != LLDB_INVALID_ADDRESS) {
3212 const size_t num_variables =
3213 ParseVariablesInFunctionContext(sc, function_die, func_lo_pc);
3214
3215 // Let all blocks know they have parse all their variables
3216 sc.function->GetBlock(false).SetDidParseVariables(true, true);
3217 return num_variables;
3218 }
3219 } else if (sc.comp_unit) {
3220 DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(sc.comp_unit->GetID());
3221
3222 if (dwarf_cu == nullptr)
3223 return 0;
3224
3225 uint32_t vars_added = 0;
3226 VariableListSP variables(sc.comp_unit->GetVariableList(false));
3227
3228 if (variables.get() == nullptr) {
3229 variables = std::make_shared<VariableList>();
3230 sc.comp_unit->SetVariableList(variables);
3231
3232 m_index->GetGlobalVariables(*dwarf_cu, [&](DWARFDIE die) {
3233 VariableSP var_sp(ParseVariableDIECached(sc, die));
3234 if (var_sp) {
3235 variables->AddVariableIfUnique(var_sp);
3236 ++vars_added;
3237 }
3238 return true;
3239 });
3240 }
3241 return vars_added;
3242 }
3243 }
3244 return 0;
3245}
3246
3248 const DWARFDIE &die) {
3249 if (!die)
3250 return nullptr;
3251
3252 DIEToVariableSP &die_to_variable = die.GetDWARF()->GetDIEToVariable();
3253
3254 VariableSP var_sp = die_to_variable[die.GetDIE()];
3255 if (var_sp)
3256 return var_sp;
3257
3258 var_sp = ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS);
3259 if (var_sp) {
3260 die_to_variable[die.GetDIE()] = var_sp;
3261 if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification))
3262 die_to_variable[spec_die.GetDIE()] = var_sp;
3263 }
3264 return var_sp;
3265}
3266
3268 const DWARFDIE &die,
3269 const lldb::addr_t func_low_pc) {
3270 if (die.GetDWARF() != this)
3271 return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc);
3272
3273 if (!die)
3274 return nullptr;
3275
3276 const dw_tag_t tag = die.Tag();
3277 ModuleSP module = GetObjectFile()->GetModule();
3278
3279 if (tag != DW_TAG_variable && tag != DW_TAG_constant &&
3280 (tag != DW_TAG_formal_parameter || !sc.function))
3281 return nullptr;
3282
3283 DWARFAttributes attributes;
3284 const size_t num_attributes = die.GetAttributes(attributes);
3285 const char *name = nullptr;
3286 const char *mangled = nullptr;
3287 Declaration decl;
3288 DWARFFormValue type_die_form;
3289 DWARFExpressionList location_list(module, DWARFExpression(), die.GetCU());
3290 bool is_external = false;
3291 bool is_artificial = false;
3292 DWARFFormValue const_value_form, location_form;
3293 Variable::RangeList scope_ranges;
3294
3295 for (size_t i = 0; i < num_attributes; ++i) {
3296 dw_attr_t attr = attributes.AttributeAtIndex(i);
3297 DWARFFormValue form_value;
3298
3299 if (!attributes.ExtractFormValueAtIndex(i, form_value))
3300 continue;
3301 switch (attr) {
3302 case DW_AT_decl_file:
3303 decl.SetFile(
3304 attributes.CompileUnitAtIndex(i)->GetFile(form_value.Unsigned()));
3305 break;
3306 case DW_AT_decl_line:
3307 decl.SetLine(form_value.Unsigned());
3308 break;
3309 case DW_AT_decl_column:
3310 decl.SetColumn(form_value.Unsigned());
3311 break;
3312 case DW_AT_name:
3313 name = form_value.AsCString();
3314 break;
3315 case DW_AT_linkage_name:
3316 case DW_AT_MIPS_linkage_name:
3317 mangled = form_value.AsCString();
3318 break;
3319 case DW_AT_type:
3320 type_die_form = form_value;
3321 break;
3322 case DW_AT_external:
3323 is_external = form_value.Boolean();
3324 break;
3325 case DW_AT_const_value:
3326 const_value_form = form_value;
3327 break;
3328 case DW_AT_location:
3329 location_form = form_value;
3330 break;
3331 case DW_AT_start_scope:
3332 // TODO: Implement this.
3333 break;
3334 case DW_AT_artificial:
3335 is_artificial = form_value.Boolean();
3336 break;
3337 case DW_AT_declaration:
3338 case DW_AT_description:
3339 case DW_AT_endianity:
3340 case DW_AT_segment:
3341 case DW_AT_specification:
3342 case DW_AT_visibility:
3343 default:
3344 case DW_AT_abstract_origin:
3345 case DW_AT_sibling:
3346 break;
3347 }
3348 }
3349
3350 // Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g.
3351 // for static constexpr member variables -- DW_AT_const_value will be
3352 // present in the class declaration and DW_AT_location in the DIE defining
3353 // the member.
3354 bool location_is_const_value_data = false;
3355 bool has_explicit_location = location_form.IsValid();
3356 bool use_type_size_for_value = false;
3357 if (location_form.IsValid()) {
3358 if (DWARFFormValue::IsBlockForm(location_form.Form())) {
3359 const DWARFDataExtractor &data = die.GetData();
3360
3361 uint32_t block_offset = location_form.BlockData() - data.GetDataStart();
3362 uint32_t block_length = location_form.Unsigned();
3363 location_list = DWARFExpressionList(
3364 module, DataExtractor(data, block_offset, block_length), die.GetCU());
3365 } else {
3366 DataExtractor data = die.GetCU()->GetLocationData();
3367 dw_offset_t offset = location_form.Unsigned();
3368 if (location_form.Form() == DW_FORM_loclistx)
3369 offset = die.GetCU()->GetLoclistOffset(offset).value_or(-1);
3370 if (data.ValidOffset(offset)) {
3371 data = DataExtractor(data, offset, data.GetByteSize() - offset);
3372 const DWARFUnit *dwarf_cu = location_form.GetUnit();
3373 if (DWARFExpression::ParseDWARFLocationList(dwarf_cu, data,
3374 &location_list))
3375 location_list.SetFuncFileAddress(func_low_pc);
3376 }
3377 }
3378 } else if (const_value_form.IsValid()) {
3379 location_is_const_value_data = true;
3380 // The constant value will be either a block, a data value or a
3381 // string.
3382 const DWARFDataExtractor &debug_info_data = die.GetData();
3383 if (DWARFFormValue::IsBlockForm(const_value_form.Form())) {
3384 // Retrieve the value as a block expression.
3385 uint32_t block_offset =
3386 const_value_form.BlockData() - debug_info_data.GetDataStart();
3387 uint32_t block_length = const_value_form.Unsigned();
3388 location_list = DWARFExpressionList(
3389 module, DataExtractor(debug_info_data, block_offset, block_length),
3390 die.GetCU());
3391 } else if (DWARFFormValue::IsDataForm(const_value_form.Form())) {
3392 // Constant value size does not have to match the size of the
3393 // variable. We will fetch the size of the type after we create
3394 // it.
3395 use_type_size_for_value = true;
3396 } else if (const char *str = const_value_form.AsCString()) {
3397 uint32_t string_length = strlen(str) + 1;
3398 location_list = DWARFExpressionList(
3399 module,
3400 DataExtractor(str, string_length, die.GetCU()->GetByteOrder(),
3401 die.GetCU()->GetAddressByteSize()),
3402 die.GetCU());
3403 }
3404 }
3405
3406 const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
3407 const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
3408 const dw_tag_t parent_tag = sc_parent_die.Tag();
3409 bool is_static_member = (parent_tag == DW_TAG_compile_unit ||
3410 parent_tag == DW_TAG_partial_unit) &&
3411 (parent_context_die.Tag() == DW_TAG_class_type ||
3412 parent_context_die.Tag() == DW_TAG_structure_type);
3413
3415 SymbolContextScope *symbol_context_scope = nullptr;
3416
3417 bool has_explicit_mangled = mangled != nullptr;
3418 if (!mangled) {
3419 // LLDB relies on the mangled name (DW_TAG_linkage_name or
3420 // DW_AT_MIPS_linkage_name) to generate fully qualified names
3421 // of global variables with commands like "frame var j". For
3422 // example, if j were an int variable holding a value 4 and
3423 // declared in a namespace B which in turn is contained in a
3424 // namespace A, the command "frame var j" returns
3425 // "(int) A::B::j = 4".
3426 // If the compiler does not emit a linkage name, we should be
3427 // able to generate a fully qualified name from the
3428 // declaration context.
3429 if ((parent_tag == DW_TAG_compile_unit ||
3430 parent_tag == DW_TAG_partial_unit) &&
3432 mangled =
3434 }
3435
3436 if (tag == DW_TAG_formal_parameter)
3438 else {
3439 // DWARF doesn't specify if a DW_TAG_variable is a local, global
3440 // or static variable, so we have to do a little digging:
3441 // 1) DW_AT_linkage_name implies static lifetime (but may be missing)
3442 // 2) An empty DW_AT_location is an (optimized-out) static lifetime var.
3443 // 3) DW_AT_location containing a DW_OP_addr implies static lifetime.
3444 // Clang likes to combine small global variables into the same symbol
3445 // with locations like: DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
3446 // so we need to look through the whole expression.
3447 bool is_static_lifetime =
3448 has_explicit_mangled ||
3449 (has_explicit_location && !location_list.IsValid());
3450 // Check if the location has a DW_OP_addr with any address value...
3451 lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
3452 if (!location_is_const_value_data) {
3453 bool op_error = false;
3454 const DWARFExpression* location = location_list.GetAlwaysValidExpr();
3455 if (location)
3456 location_DW_OP_addr = location->GetLocation_DW_OP_addr(
3457 location_form.GetUnit(), 0, op_error);
3458 if (op_error) {
3459 StreamString strm;
3460 location->DumpLocation(&strm, eDescriptionLevelFull, nullptr);
3461 GetObjectFile()->GetModule()->ReportError(
3462 "{0:x16}: {1} has an invalid location: {2}", die.GetOffset(),
3463 die.GetTagAsCString(), strm.GetData());
3464 }
3465 if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
3466 is_static_lifetime = true;
3467 }
3468 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
3469 if (debug_map_symfile)
3470 // Set the module of the expression to the linked module
3471 // instead of the object file so the relocated address can be
3472 // found there.
3473 location_list.SetModule(debug_map_symfile->GetObjectFile()->GetModule());
3474
3475 if (is_static_lifetime) {
3476 if (is_external)
3478 else
3480
3481 if (debug_map_symfile) {
3482 // When leaving the DWARF in the .o files on darwin, when we have a
3483 // global variable that wasn't initialized, the .o file might not
3484 // have allocated a virtual address for the global variable. In
3485 // this case it will have created a symbol for the global variable
3486 // that is undefined/data and external and the value will be the
3487 // byte size of the variable. When we do the address map in
3488 // SymbolFileDWARFDebugMap we rely on having an address, we need to
3489 // do some magic here so we can get the correct address for our
3490 // global variable. The address for all of these entries will be
3491 // zero, and there will be an undefined symbol in this object file,
3492 // and the executable will have a matching symbol with a good
3493 // address. So here we dig up the correct address and replace it in
3494 // the location for the variable, and set the variable's symbol
3495 // context scope to be that of the main executable so the file
3496 // address will resolve correctly.
3497 bool linked_oso_file_addr = false;
3498 if (is_external && location_DW_OP_addr == 0) {
3499 // we have a possible uninitialized extern global
3500 ConstString const_name(mangled ? mangled : name);
3501 ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
3502 if (debug_map_objfile) {
3503 Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
3504 if (debug_map_symtab) {
3505 Symbol *exe_symbol =
3506 debug_map_symtab->FindFirstSymbolWithNameAndType(
3509 if (exe_symbol) {
3510 if (exe_symbol->ValueIsAddress()) {
3511 const addr_t exe_file_addr =
3512 exe_symbol->GetAddressRef().GetFileAddress();
3513 if (exe_file_addr != LLDB_INVALID_ADDRESS) {
3514 DWARFExpression *location =
3515 location_list.GetMutableExpressionAtAddress();
3516 if (location->Update_DW_OP_addr(die.GetCU(),
3517 exe_file_addr)) {
3518 linked_oso_file_addr = true;
3519 symbol_context_scope = exe_symbol;
3520 }
3521 }
3522 }
3523 }
3524 }
3525 }
3526 }
3527
3528 if (!linked_oso_file_addr) {
3529 // The DW_OP_addr is not zero, but it contains a .o file address
3530 // which needs to be linked up correctly.
3531 const lldb::addr_t exe_file_addr =
3532 debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
3533 if (exe_file_addr != LLDB_INVALID_ADDRESS) {
3534 // Update the file address for this variable
3535 DWARFExpression *location =
3536 location_list.GetMutableExpressionAtAddress();
3537 location->Update_DW_OP_addr(die.GetCU(), exe_file_addr);
3538 } else {
3539 // Variable didn't make it into the final executable
3540 return nullptr;
3541 }
3542 }
3543 }
3544 } else {
3545 if (location_is_const_value_data &&
3546 die.GetDIE()->IsGlobalOrStaticScopeVariable())
3548 else {
3550 if (debug_map_symfile) {
3551 // We need to check for TLS addresses that we need to fixup
3552 if (location_list.ContainsThreadLocalStorage()) {
3553 location_list.LinkThreadLocalStorage(
3554 debug_map_symfile->GetObjectFile()->GetModule(),
3555 [this, debug_map_symfile](
3556 lldb::addr_t unlinked_file_addr) -> lldb::addr_t {
3557 return debug_map_symfile->LinkOSOFileAddress(
3558 this, unlinked_file_addr);
3559 });
3561 }
3562 }
3563 }
3564 }
3565 }
3566
3567 if (symbol_context_scope == nullptr) {
3568 switch (parent_tag) {
3569 case DW_TAG_subprogram:
3570 case DW_TAG_inlined_subroutine:
3571 case DW_TAG_lexical_block:
3572 if (sc.function) {
3573 symbol_context_scope =
3574 sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
3575 if (symbol_context_scope == nullptr)
3576 symbol_context_scope = sc.function;
3577 }
3578 break;
3579
3580 default:
3581 symbol_context_scope = sc.comp_unit;
3582 break;
3583 }
3584 }
3585
3586 if (!symbol_context_scope) {
3587 // Not ready to parse this variable yet. It might be a global or static
3588 // variable that is in a function scope and the function in the symbol
3589 // context wasn't filled in yet
3590 return nullptr;
3591 }
3592
3593 auto type_sp = std::make_shared<SymbolFileType>(
3594 *this, type_die_form.Reference().GetID());
3595
3596 if (use_type_size_for_value && type_sp->GetType()) {
3597 DWARFExpression *location = location_list.GetMutableExpressionAtAddress();
3598 location->UpdateValue(const_value_form.Unsigned(),
3599 type_sp->GetType()->GetByteSize(nullptr).value_or(0),
3600 die.GetCU()->GetAddressByteSize());
3601 }
3602
3603 return std::make_shared<Variable>(
3604 die.GetID(), name, mangled, type_sp, scope, symbol_context_scope,
3605 scope_ranges, &decl, location_list, is_external, is_artificial,
3606 location_is_const_value_data, is_static_member);
3607}
3608
3611 const DIERef &func_die_ref, dw_offset_t spec_block_die_offset) {
3612 // Give the concrete function die specified by "func_die_offset", find the
3613 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
3614 // to "spec_block_die_offset"
3615 return FindBlockContainingSpecification(DebugInfo().GetDIE(func_die_ref),
3616 spec_block_die_offset);
3617}
3618
3621 const DWARFDIE &die, dw_offset_t spec_block_die_offset) {
3622 if (die) {
3623 switch (die.Tag()) {
3624 case DW_TAG_subprogram:
3625 case DW_TAG_inlined_subroutine:
3626 case DW_TAG_lexical_block: {
3627 if (die.GetReferencedDIE(DW_AT_specification).GetOffset() ==
3628 spec_block_die_offset)
3629 return die;
3630
3631 if (die.GetReferencedDIE(DW_AT_abstract_origin).GetOffset() ==
3632 spec_block_die_offset)
3633 return die;
3634 } break;
3635 default:
3636 break;
3637 }
3638
3639 // Give the concrete function die specified by "func_die_offset", find the
3640 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
3641 // to "spec_block_die_offset"
3642 for (DWARFDIE child_die : die.children()) {
3643 DWARFDIE result_die =
3644 FindBlockContainingSpecification(child_die, spec_block_die_offset);
3645 if (result_die)
3646 return result_die;
3647 }
3648 }
3649
3650 return DWARFDIE();
3651}
3652
3654 const SymbolContext &sc, const DWARFDIE &die,
3655 VariableList &cc_variable_list) {
3656 if (!die)
3657 return;
3658
3659 dw_tag_t tag = die.Tag();
3660 if (tag != DW_TAG_variable && tag != DW_TAG_constant)
3661 return;
3662
3663 // Check to see if we have already parsed this variable or constant?
3664 VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];
3665 if (var_sp) {
3666 cc_variable_list.AddVariableIfUnique(var_sp);
3667 return;
3668 }
3669
3670 // We haven't parsed the variable yet, lets do that now. Also, let us include
3671 // the variable in the relevant compilation unit's variable list, if it
3672 // exists.
3673 VariableListSP variable_list_sp;
3674 DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
3675 dw_tag_t parent_tag = sc_parent_die.Tag();
3676 switch (parent_tag) {
3677 case DW_TAG_compile_unit:
3678 case DW_TAG_partial_unit:
3679 if (sc.comp_unit != nullptr) {
3680 variable_list_sp = sc.comp_unit->GetVariableList(false);
3681 } else {
3682 GetObjectFile()->GetModule()->ReportError(
3683 "parent {0:x8} {1} with no valid compile unit in "
3684 "symbol context for {2:x8} {3}.\n",
3685 sc_parent_die.GetID(), sc_parent_die.GetTagAsCString(), die.GetID(),
3686 die.GetTagAsCString());
3687 return;
3688 }
3689 break;
3690
3691 default:
3692 GetObjectFile()->GetModule()->ReportError(
3693 "didn't find appropriate parent DIE for variable list for {0:x8} "
3694 "{1}.\n",
3695 die.GetID(), die.GetTagAsCString());
3696 return;
3697 }
3698
3699 var_sp = ParseVariableDIECached(sc, die);
3700 if (!var_sp)
3701 return;
3702
3703 cc_variable_list.AddVariableIfUnique(var_sp);
3704 if (variable_list_sp)
3705 variable_list_sp->AddVariableIfUnique(var_sp);
3706}
3707
3710 DIEArray &&variable_dies) {
3711 // DW_TAG_inline_subroutine objects may omit DW_TAG_formal_parameter in
3712 // instances of the function when they are unused (i.e., the parameter's
3713 // location list would be empty). The current DW_TAG_inline_subroutine may
3714 // refer to another DW_TAG_subprogram that might actually have the definitions
3715 // of the parameters and we need to include these so they show up in the
3716 // variables for this function (for example, in a stack trace). Let us try to
3717 // find the abstract subprogram that might contain the parameter definitions
3718 // and merge with the concrete parameters.
3719
3720 // Nothing to merge if the block is not an inlined function.
3721 if (block_die.Tag() != DW_TAG_inlined_subroutine) {
3722 return std::move(variable_dies);
3723 }
3724
3725 // Nothing to merge if the block does not have abstract parameters.
3726 DWARFDIE abs_die = block_die.GetReferencedDIE(DW_AT_abstract_origin);
3727 if (!abs_die || abs_die.Tag() != DW_TAG_subprogram ||
3728 !abs_die.HasChildren()) {
3729 return std::move(variable_dies);
3730 }
3731
3732 // For each abstract parameter, if we have its concrete counterpart, insert
3733 // it. Otherwise, insert the abstract parameter.
3734 DIEArray::iterator concrete_it = variable_dies.begin();
3735 DWARFDIE abstract_child = abs_die.GetFirstChild();
3736 DIEArray merged;
3737 bool did_merge_abstract = false;
3738 for (; abstract_child; abstract_child = abstract_child.GetSibling()) {
3739 if (abstract_child.Tag() == DW_TAG_formal_parameter) {
3740 if (concrete_it == variable_dies.end() ||
3741 GetDIE(*concrete_it).Tag() != DW_TAG_formal_parameter) {
3742 // We arrived at the end of the concrete parameter list, so all
3743 // the remaining abstract parameters must have been omitted.
3744 // Let us insert them to the merged list here.
3745 merged.push_back(*abstract_child.GetDIERef());
3746 did_merge_abstract = true;
3747 continue;
3748 }
3749
3750 DWARFDIE origin_of_concrete =
3751 GetDIE(*concrete_it).GetReferencedDIE(DW_AT_abstract_origin);
3752 if (origin_of_concrete == abstract_child) {
3753 // The current abstract parameter is the origin of the current
3754 // concrete parameter, just push the concrete parameter.
3755 merged.push_back(*concrete_it);
3756 ++concrete_it;
3757 } else {
3758 // Otherwise, the parameter must have been omitted from the concrete
3759 // function, so insert the abstract one.
3760 merged.push_back(*abstract_child.GetDIERef());
3761 did_merge_abstract = true;
3762 }
3763 }
3764 }
3765
3766 // Shortcut if no merging happened.
3767 if (!did_merge_abstract)
3768 return std::move(variable_dies);
3769
3770 // We inserted all the abstract parameters (or their concrete counterparts).
3771 // Let us insert all the remaining concrete variables to the merged list.
3772 // During the insertion, let us check there are no remaining concrete
3773 // formal parameters. If that's the case, then just bailout from the merge -
3774 // the variable list is malformed.
3775 for (; concrete_it != variable_dies.end(); ++concrete_it) {
3776 if (GetDIE(*concrete_it).Tag() == DW_TAG_formal_parameter) {
3777 return std::move(variable_dies);
3778 }
3779 merged.push_back(*concrete_it);
3780 }
3781 return merged;
3782}
3783
3785 const SymbolContext &sc, const DWARFDIE &die,
3786 const lldb::addr_t func_low_pc) {
3787 if (!die || !sc.function)
3788 return 0;
3789
3790 DIEArray dummy_block_variables; // The recursive call should not add anything
3791 // to this vector because |die| should be a
3792 // subprogram, so all variables will be added
3793 // to the subprogram's list.
3794 return ParseVariablesInFunctionContextRecursive(sc, die, func_low_pc,
3795 dummy_block_variables);
3796}
3797
3798// This method parses all the variables in the blocks in the subtree of |die|,
3799// and inserts them to the variable list for all the nested blocks.
3800// The uninserted variables for the current block are accumulated in
3801// |accumulator|.
3803 const lldb_private::SymbolContext &sc, const DWARFDIE &die,
3804 lldb::addr_t func_low_pc, DIEArray &accumulator) {
3805 size_t vars_added = 0;
3806 dw_tag_t tag = die.Tag();
3807
3808 if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
3809 (tag == DW_TAG_formal_parameter)) {
3810 accumulator.push_back(*die.GetDIERef());
3811 }
3812
3813 switch (tag) {
3814 case DW_TAG_subprogram:
3815 case DW_TAG_inlined_subroutine:
3816 case DW_TAG_lexical_block: {
3817 // If we start a new block, compute a new block variable list and recurse.
3818 Block *block =
3819 sc.function->GetBlock(/*can_create=*/true).FindBlockByID(die.GetID());
3820 if (block == nullptr) {
3821 // This must be a specification or abstract origin with a
3822 // concrete block counterpart in the current function. We need
3823 // to find the concrete block so we can correctly add the
3824 // variable to it.
3825 const DWARFDIE concrete_block_die = FindBlockContainingSpecification(
3826 GetDIE(sc.function->GetID()), die.GetOffset());
3827 if (concrete_block_die)
3828 block = sc.function->GetBlock(/*can_create=*/true)
3829 .FindBlockByID(concrete_block_die.GetID());
3830 }
3831
3832 if (block == nullptr)
3833 return 0;
3834
3835 const bool can_create = false;
3836 VariableListSP block_variable_list_sp =
3837 block->GetBlockVariableList(can_create);
3838 if (block_variable_list_sp.get() == nullptr) {
3839 block_variable_list_sp = std::make_shared<VariableList>();
3840 block->SetVariableList(block_variable_list_sp);
3841 }
3842
3843 DIEArray block_variables;
3844 for (DWARFDIE child = die.GetFirstChild(); child;
3845 child = child.GetSibling()) {
3847 sc, child, func_low_pc, block_variables);
3848 }
3849 block_variables =
3850 MergeBlockAbstractParameters(die, std::move(block_variables));
3851 vars_added += PopulateBlockVariableList(*block_variable_list_sp, sc,
3852 block_variables, func_low_pc);
3853 break;
3854 }
3855
3856 default:
3857 // Recurse to children with the same variable accumulator.
3858 for (DWARFDIE child = die.GetFirstChild(); child;
3859 child = child.GetSibling()) {
3861 sc, child, func_low_pc, accumulator);
3862 }
3863 break;
3864 }
3865
3866 return vars_added;
3867}
3868
3870 VariableList &variable_list, const lldb_private::SymbolContext &sc,
3871 llvm::ArrayRef<DIERef> variable_dies, lldb::addr_t func_low_pc) {
3872 // Parse the variable DIEs and insert them to the list.
3873 for (auto &die : variable_dies) {
3874 if (VariableSP var_sp = ParseVariableDIE(sc, GetDIE(die), func_low_pc)) {
3875 variable_list.AddVariableIfUnique(var_sp);
3876 }
3877 }
3878 return variable_dies.size();
3879}
3880
3881/// Collect call site parameters in a DW_TAG_call_site DIE.
3883CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
3884 CallSiteParameterArray parameters;
3885 for (DWARFDIE child : call_site_die.children()) {
3886 if (child.Tag() != DW_TAG_call_site_parameter &&
3887 child.Tag() != DW_TAG_GNU_call_site_parameter)
3888 continue;
3889
3890 std::optional<DWARFExpressionList> LocationInCallee;
3891 std::optional<DWARFExpressionList> LocationInCaller;
3892
3893 DWARFAttributes attributes;
3894 const size_t num_attributes = child.GetAttributes(attributes);
3895
3896 // Parse the location at index \p attr_index within this call site parameter
3897 // DIE, or return std::nullopt on failure.
3898 auto parse_simple_location =
3899 [&](int attr_index) -> std::optional<DWARFExpressionList> {
3900 DWARFFormValue form_value;
3901 if (!attributes.ExtractFormValueAtIndex(attr_index, form_value))
3902 return {};
3903 if (!DWARFFormValue::IsBlockForm(form_value.Form()))
3904 return {};
3905 auto data = child.GetData();
3906 uint32_t block_offset = form_value.BlockData() - data.GetDataStart();
3907 uint32_t block_length = form_value.Unsigned();
3908 return DWARFExpressionList(
3909 module, DataExtractor(data, block_offset, block_length),
3910 child.GetCU());
3911 };
3912
3913 for (size_t i = 0; i < num_attributes; ++i) {
3914 dw_attr_t attr = attributes.AttributeAtIndex(i);
3915 if (attr == DW_AT_location)
3916 LocationInCallee = parse_simple_location(i);
3917 if (attr == DW_AT_call_value || attr == DW_AT_GNU_call_site_value)
3918 LocationInCaller = parse_simple_location(i);
3919 }
3920
3921 if (LocationInCallee && LocationInCaller) {
3922 CallSiteParameter param = {*LocationInCallee, *LocationInCaller};
3923 parameters.push_back(param);
3924 }
3925 }
3926 return parameters;
3927}
3928
3929/// Collect call graph edges present in a function DIE.
3930std::vector<std::unique_ptr<lldb_private::CallEdge>>
3931SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
3932 // Check if the function has a supported call site-related attribute.
3933 // TODO: In the future it may be worthwhile to support call_all_source_calls.
3934 bool has_call_edges =
3935 function_die.GetAttributeValueAsUnsigned(DW_AT_call_all_calls, 0) ||
3936 function_die.GetAttributeValueAsUnsigned(DW_AT_GNU_all_call_sites, 0);
3937 if (!has_call_edges)
3938 return {};
3939
3940 Log *log = GetLog(LLDBLog::Step);
3941 LLDB_LOG(log, "CollectCallEdges: Found call site info in {0}",
3942 function_die.GetPubname());
3943
3944 // Scan the DIE for TAG_call_site entries.
3945 // TODO: A recursive scan of all blocks in the subprogram is needed in order
3946 // to be DWARF5-compliant. This may need to be done lazily to be performant.
3947 // For now, assume that all entries are nested directly under the subprogram
3948 // (this is the kind of DWARF LLVM produces) and parse them eagerly.
3949 std::vector<std::unique_ptr<CallEdge>> call_edges;
3950 for (DWARFDIE child : function_die.children()) {
3951 if (child.Tag() != DW_TAG_call_site && child.Tag() != DW_TAG_GNU_call_site)
3952 continue;
3953
3954 std::optional<DWARFDIE> call_origin;
3955 std::optional<DWARFExpressionList> call_target;
3956 addr_t return_pc = LLDB_INVALID_ADDRESS;
3957 addr_t call_inst_pc = LLDB_INVALID_ADDRESS;
3959 bool tail_call = false;
3960
3961 // Second DW_AT_low_pc may come from DW_TAG_subprogram referenced by
3962 // DW_TAG_GNU_call_site's DW_AT_abstract_origin overwriting our 'low_pc'.
3963 // So do not inherit attributes from DW_AT_abstract_origin.
3964 DWARFAttributes attributes;
3965 const size_t num_attributes =
3966 child.GetAttributes(attributes, DWARFDIE::Recurse::no);
3967 for (size_t i = 0; i < num_attributes; ++i) {
3968 DWARFFormValue form_value;
3969 if (!attributes.ExtractFormValueAtIndex(i, form_value)) {
3970 LLDB_LOG(log, "CollectCallEdges: Could not extract TAG_call_site form");
3971 break;
3972 }
3973
3974 dw_attr_t attr = attributes.AttributeAtIndex(i);
3975
3976 if (attr == DW_AT_call_tail_call || attr == DW_AT_GNU_tail_call)
3977 tail_call = form_value.Boolean();
3978
3979 // Extract DW_AT_call_origin (the call target's DIE).
3980 if (attr == DW_AT_call_origin || attr == DW_AT_abstract_origin) {
3981 call_origin = form_value.Reference();
3982 if (!call_origin->IsValid()) {
3983 LLDB_LOG(log, "CollectCallEdges: Invalid call origin in {0}",
3984 function_die.GetPubname());
3985 break;
3986 }
3987 }
3988
3989 if (attr == DW_AT_low_pc)
3990 low_pc = form_value.Address();
3991
3992 // Extract DW_AT_call_return_pc (the PC the call returns to) if it's
3993 // available. It should only ever be unavailable for tail call edges, in
3994 // which case use LLDB_INVALID_ADDRESS.
3995 if (attr == DW_AT_call_return_pc)
3996 return_pc = form_value.Address();
3997
3998 // Extract DW_AT_call_pc (the PC at the call/branch instruction). It
3999 // should only ever be unavailable for non-tail calls, in which case use
4000 // LLDB_INVALID_ADDRESS.
4001 if (attr == DW_AT_call_pc)
4002 call_inst_pc = form_value.Address();
4003
4004 // Extract DW_AT_call_target (the location of the address of the indirect
4005 // call).
4006 if (attr == DW_AT_call_target || attr == DW_AT_GNU_call_site_target) {
4007 if (!DWARFFormValue::IsBlockForm(form_value.Form())) {
4008 LLDB_LOG(log,
4009 "CollectCallEdges: AT_call_target does not have block form");
4010 break;
4011 }
4012
4013 auto data = child.GetData();
4014 uint32_t block_offset = form_value.BlockData() - data.GetDataStart();
4015 uint32_t block_length = form_value.Unsigned();
4016 call_target = DWARFExpressionList(
4017 module, DataExtractor(data, block_offset, block_length),
4018 child.GetCU());
4019 }
4020 }
4021 if (!call_origin && !call_target) {
4022 LLDB_LOG(log, "CollectCallEdges: call site without any call target");
4023 continue;
4024 }
4025
4026 addr_t caller_address;
4027 CallEdge::AddrType caller_address_type;
4028 if (return_pc != LLDB_INVALID_ADDRESS) {
4029 caller_address = return_pc;
4030 caller_address_type = CallEdge::AddrType::AfterCall;
4031 } else if (low_pc != LLDB_INVALID_ADDRESS) {
4032 caller_address = low_pc;
4033 caller_address_type = CallEdge::AddrType::AfterCall;
4034 } else if (call_inst_pc != LLDB_INVALID_ADDRESS) {
4035 caller_address = call_inst_pc;
4036 caller_address_type = CallEdge::AddrType::Call;
4037 } else {
4038 LLDB_LOG(log, "CollectCallEdges: No caller address");
4039 continue;
4040 }
4041 // Adjust any PC forms. It needs to be fixed up if the main executable
4042 // contains a debug map (i.e. pointers to object files), because we need a
4043 // file address relative to the executable's text section.
4044 caller_address = FixupAddress(caller_address);
4045
4046 // Extract call site parameters.
4047 CallSiteParameterArray parameters =
4048 CollectCallSiteParameters(module, child);
4049
4050 std::unique_ptr<CallEdge> edge;
4051 if (call_origin) {
4052 LLDB_LOG(log,
4053 "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x}) "
4054 "(call-PC: {2:x})",
4055 call_origin->GetPubname(), return_pc, call_inst_pc);
4056 edge = std::make_unique<DirectCallEdge>(
4057 call_origin->GetMangledName(), caller_address_type, caller_address,
4058 tail_call, std::move(parameters));
4059 } else {
4060 if (log) {
4061 StreamString call_target_desc;
4062 call_target->GetDescription(&call_target_desc, eDescriptionLevelBrief,
4063 nullptr);
4064 LLDB_LOG(log, "CollectCallEdges: Found indirect call target: {0}",
4065 call_target_desc.GetString());
4066 }
4067 edge = std::make_unique<IndirectCallEdge>(
4068 *call_target, caller_address_type, caller_address, tail_call,
4069 std::move(parameters));
4070 }
4071
4072 if (log && parameters.size()) {
4073 for (const CallSiteParameter &param : parameters) {
4074 StreamString callee_loc_desc, caller_loc_desc;
4075 param.LocationInCallee.GetDescription(&callee_loc_desc,
4076 eDescriptionLevelBrief, nullptr);
4077 param.LocationInCaller.GetDescription(&caller_loc_desc,
4078 eDescriptionLevelBrief, nullptr);
4079 LLDB_LOG(log, "CollectCallEdges: \tparam: {0} => {1}",
4080 callee_loc_desc.GetString(), caller_loc_desc.GetString());
4081 }
4082 }
4083
4084 call_edges.push_back(std::move(edge));
4085 }
4086 return call_edges;
4087}
4088
4089std::vector<std::unique_ptr<lldb_private::CallEdge>>
4091 // ParseCallEdgesInFunction must be called at the behest of an exclusively
4092 // locked lldb::Function instance. Storage for parsed call edges is owned by
4093 // the lldb::Function instance: locking at the SymbolFile level would be too
4094 // late, because the act of storing results from ParseCallEdgesInFunction
4095 // would be racy.
4096 DWARFDIE func_die = GetDIE(func_id.GetID());
4097 if (func_die.IsValid())
4098 return CollectCallEdges(GetObjectFile()->GetModule(), func_die);
4099 return {};
4100}
4101
4104 m_index->Dump(s);
4105}
4106
4109 if (!ts_or_err)
4110 return;
4111 auto ts = *ts_or_err;
4112 TypeSystemClang *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
4113 if (!clang)
4114 return;
4115 clang->Dump(s.AsRawOstream());
4116}
4117
4119 if (m_debug_map_symfile == nullptr) {
4120 lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());
4121 if (module_sp) {
4122 m_debug_map_symfile = llvm::cast<SymbolFileDWARFDebugMap>(
4123 module_sp->GetSymbolFile()->GetBackingSymbolFile());
4124 }
4125 }
4126 return m_debug_map_symfile;
4127}
4128
4129const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
4130 llvm::call_once(m_dwp_symfile_once_flag, [this]() {
4131 ModuleSpec module_spec;
4132 module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec();
4133 module_spec.GetSymbolFileSpec() =
4134 FileSpec(m_objfile_sp->GetModule()->GetFileSpec().GetPath() + ".dwp");
4135
4136 FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
4137 FileSpec dwp_filespec =
4138 Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
4139 if (FileSystem::Instance().Exists(dwp_filespec)) {
4140 DataBufferSP dwp_file_data_sp;
4141 lldb::offset_t dwp_file_data_offset = 0;
4142 ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin(
4143 GetObjectFile()->GetModule(), &dwp_filespec, 0,
4144 FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp,
4145 dwp_file_data_offset);
4146 if (!dwp_obj_file)
4147 return;
4148 m_dwp_symfile = std::make_shared<SymbolFileDWARFDwo>(
4149 *this, dwp_obj_file, DIERef::k_file_index_mask);
4150 }
4151 });
4152 return m_dwp_symfile;
4153}
4154
4155llvm::Expected<lldb::TypeSystemSP>
4158}
4159
4161 auto type_system_or_err = GetTypeSystem(unit);
4162 if (auto err = type_system_or_err.takeError()) {
4163 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
4164 "Unable to get DWARFASTParser");
4165 return nullptr;
4166 }
4167 if (auto ts = *type_system_or_err)
4168 return ts->GetDWARFParser();
4169 return nullptr;
4170}
4171
4173 if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()))
4174 return dwarf_ast->GetDeclForUIDFromDWARF(die);
4175 return CompilerDecl();
4176}
4177
4179 if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()))
4180 return dwarf_ast->GetDeclContextForUIDFromDWARF(die);
4181 return CompilerDeclContext();
4182}
4183
4186 if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()))
4187 return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
4188 return CompilerDeclContext();
4189}
4190
4192 if (!die.IsValid())
4193 return {};
4194 DWARFDeclContext dwarf_decl_ctx =
4195 die.GetDIE()->GetDWARFDeclContext(die.GetCU());
4196 return dwarf_decl_ctx;
4197}
4198
4200 // Note: user languages between lo_user and hi_user must be handled
4201 // explicitly here.
4202 switch (val) {
4203 case DW_LANG_Mips_Assembler:
4205 default:
4206 return static_cast<LanguageType>(val);
4207 }
4208}
4209
4212}
4213
4215 auto lang = (llvm::dwarf::SourceLanguage)unit.GetDWARFLanguageType();
4216 if (llvm::dwarf::isCPlusPlus(lang))
4217 lang = DW_LANG_C_plus_plus;
4218 return LanguageTypeFromDWARF(lang);
4219}
4220
4222 if (m_index)
4223 return m_index->GetIndexTime();
4224 return {};
4225}
4226
4228 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
4229 CompileUnit *cu = frame.GetSymbolContext(eSymbolContextCompUnit).comp_unit;
4230 if (!cu)
4231 return Status();
4232
4233 DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(cu);
4234 if (!dwarf_cu)
4235 return Status();
4236
4237 // Check if we have a skeleton compile unit that had issues trying to load
4238 // its .dwo/.dwp file. First pares the Unit DIE to make sure we see any .dwo
4239 // related errors.
4240 dwarf_cu->ExtractUnitDIEIfNeeded();
4241 const Status &dwo_error = dwarf_cu->GetDwoError();
4242 if (dwo_error.Fail())
4243 return dwo_error;
4244
4245 // Don't return an error for assembly files as they typically don't have
4246 // varaible information.
4247 if (dwarf_cu->GetDWARFLanguageType() == DW_LANG_Mips_Assembler)
4248 return Status();
4249
4250 // Check if this compile unit has any variable DIEs. If it doesn't then there
4251 // is not variable information for the entire compile unit.
4252 if (dwarf_cu->HasAny({DW_TAG_variable, DW_TAG_formal_parameter}))
4253 return Status();
4254
4255 return Status("no variable information is available in debug info for this "
4256 "compile unit");
4257}
static llvm::raw_ostream & error(Stream &strm)
std::vector< DIERef > DIEArray
Definition: DIERef.h:133
#define DEBUG_PRINTF(fmt,...)
static PluginProperties & GetGlobalPluginProperties()
#define lldbassert(x)
Definition: LLDBAssert.h:15
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:337
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:360
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:31
static double elapsed(const StatsTimepoint &start, const StatsTimepoint &end)
Definition: Statistics.cpp:36
static PluginProperties & GetGlobalPluginProperties()
static ConstString GetDWARFMachOSegmentName()
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 bool ParseLLVMLineTablePrologue(lldb_private::DWARFContext &context, llvm::DWARFDebugLine::Prologue &prologue, dw_offset_t line_offset, dw_offset_t unit_offset)
static std::optional< uint64_t > GetDWOId(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die)
Return the DW_AT_(GNU_)dwo_id.
static std::optional< std::string > GetFileByIndex(const llvm::DWARFDebugLine::Prologue &prologue, size_t idx, llvm::StringRef compile_dir, FileSpec::Style style)
static FileSpecList ParseSupportFilesFromPrologue(const lldb::ModuleSP &module, const llvm::DWARFDebugLine::Prologue &prologue, FileSpec::Style style, llvm::StringRef compile_dir={})
static const llvm::DWARFDebugLine::LineTable * ParseLLVMLineTable(lldb_private::DWARFContext &context, llvm::DWARFDebugLine &line, 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)
Definition: SymbolFile.h:37
#define LLDB_SCOPED_TIMER()
Definition: Timer.h:83
#define LLDB_SCOPED_TIMERF(...)
Definition: Timer.h:86
Identifies a DWARF debug info entry within a given Module.
Definition: DIERef.h:28
static constexpr uint64_t k_file_index_mask
Definition: DIERef.h:117
std::optional< uint32_t > file_index() const
Definition: DIERef.h:57
@ DebugInfo
Definition: DIERef.h:30
dw_offset_t die_offset() const
Definition: DIERef.h:65
lldb_private::ClangASTImporter & GetClangASTImporter()
virtual lldb_private::Function * ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit, const DWARFDIE &die, const lldb_private::AddressRange &range)=0
virtual lldb_private::ConstString GetDIEClassTemplateParams(const DWARFDIE &die)=0
virtual void EnsureAllDIEsInDeclContextHaveBeenParsed(lldb_private::CompilerDeclContext decl_context)=0
virtual lldb_private::ConstString ConstructDemangledNameFromDWARF(const DWARFDIE &die)=0
virtual lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die, bool *type_is_new_ptr)=0
virtual lldb_private::CompilerDeclContext GetDeclContextForUIDFromDWARF(const DWARFDIE &die)=0
static std::optional< lldb_private::SymbolFile::ArrayInfo > ParseChildArrayInfo(const DWARFDIE &parent_die, const lldb_private::ExecutionContext *exe_ctx=nullptr)
dw_attr_t AttributeAtIndex(uint32_t i) const
DWARFUnit * CompileUnitAtIndex(uint32_t i) const
bool ExtractFormValueAtIndex(uint32_t i, DWARFFormValue &form_value) const
dw_tag_t Tag() const
const char * GetTagAsCString() const
bool HasChildren() const
size_t GetAttributes(DWARFAttributes &attributes, Recurse recurse=Recurse::yes) const
DWARFDebugInfoEntry * GetDIE() const
Definition: DWARFBaseDIE.h:57
const lldb_private::DWARFDataExtractor & GetData() const
bool IsValid() const
Definition: DWARFBaseDIE.h:46
void Clear()
Definition: DWARFBaseDIE.h:70
const char * GetAttributeValueAsString(const dw_attr_t attr, const char *fail_value) const
DWARFUnit * GetCU() const
Definition: DWARFBaseDIE.h:55
std::optional< DIERef > GetDIERef() const
lldb::ModuleSP GetModule() const
SymbolFileDWARF * GetDWARF() 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()
std::vector< DWARFDIE > GetDeclContextDIEs() const
Definition: DWARFDIE.cpp:362
void GetName(lldb_private::Stream &s) const
Definition: DWARFDIE.cpp:218
DWARFDIE GetFirstChild() const
Definition: DWARFDIE.cpp:94
DWARFDIE GetParent() const
Definition: DWARFDIE.cpp:86
void GetDeclContext(llvm::SmallVectorImpl< lldb_private::CompilerContext > &context) const
Return this DIE's decl context as it is needed to look up types in Clang's -gmodules debug info forma...
Definition: DWARFDIE.cpp:376
const char * GetMangledName() const
Definition: DWARFDIE.cpp:199
DWARFDIE GetDIE(dw_offset_t die_offset) const
Definition: DWARFDIE.cpp:118
llvm::iterator_range< child_iterator > children() const
The range of all the children of this DIE.
Definition: DWARFDIE.cpp:454
DWARFDIE LookupDeepestBlock(lldb::addr_t file_addr) const
Definition: DWARFDIE.cpp:139
DWARFDIE GetReferencedDIE(const dw_attr_t attr) const
Definition: DWARFDIE.cpp:110
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, lldb_private::DWARFExpressionList *frame_base) const
Definition: DWARFDIE.cpp:440
const char * GetPubname() const
Definition: DWARFDIE.cpp:206
DWARFDIE GetSibling() const
Definition: DWARFDIE.cpp:102
void GetUnsupportedForms(std::set< dw_form_t > &invalid_forms) 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 * 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 lldb_private::DWARFDataExtractor &debug_macro_data, const lldb_private::DWARFDataExtractor &debug_str_data, const bool offset_is_64_bit, lldb::offset_t *sect_offset, SymbolFileDWARF *sym_file_dwarf, lldb_private::DebugMacrosSP &debug_macros_sp)
bool OffsetIs64Bit() const
static DWARFDebugMacroHeader ParseHeader(const lldb_private::DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset)
const char * GetQualifiedName() const
lldb_private::ConstString GetQualifiedNameAsConstString() const
DWARFDIE Reference() const
bool IsValid() const
dw_form_t Form() const
const char * AsCString() const
uint64_t Unsigned() const
static bool IsDataForm(const dw_form_t form)
const uint8_t * BlockData() const
dw_addr_t Address() const
const DWARFUnit * GetUnit() const
static bool IsBlockForm(const dw_form_t form)
bool Boolean() const
SymbolFileDWARFDwo * GetDwoSymbolFile()
Definition: DWARFUnit.cpp:850
std::optional< uint64_t > GetLoclistOffset(uint32_t Index)
Definition: DWARFUnit.h:245
void * GetUserData() const
Definition: DWARFUnit.cpp:677
lldb_private::FileSpec::Style GetPathStyle()
Definition: DWARFUnit.cpp:771
SymbolFileDWARF & GetSymbolFileDWARF() const
Definition: DWARFUnit.h:200
bool GetIsOptimized()
Definition: DWARFUnit.cpp:757
void ExtractUnitDIEIfNeeded()
Definition: DWARFUnit.cpp:71
void SetDwoError(const lldb_private::Status &error)
Set the fission .dwo file specific error for this compile unit.
Definition: DWARFUnit.h:289
dw_offset_t GetLineTableOffset()
Definition: DWARFUnit.cpp:445
bool IsDWOUnit()
Definition: DWARFUnit.h:95
bool Supports_DW_AT_APPLE_objc_complete_type()
Definition: DWARFUnit.cpp:681
DWARFBaseDIE GetUnitDIEOnly()
Definition: DWARFUnit.h:178
uint16_t GetVersion() const
Definition: DWARFUnit.h:155
const lldb_private::Status & GetDwoError() const
Get the fission .dwo file specific error for this compile unit.
Definition: DWARFUnit.h:281
void SetUserData(void *d)
Definition: DWARFUnit.cpp:679
lldb_private::DWARFDataExtractor GetLocationData() const
Definition: DWARFUnit.cpp:523
uint8_t GetAddressByteSize() const
Definition: DWARFUnit.h:158
uint64_t GetDWARFLanguageType()
Definition: DWARFUnit.cpp:745
DWARFDIE DIE()
Definition: DWARFUnit.h:180
DWARFUnit & GetNonSkeletonUnit()
Definition: DWARFUnit.cpp:662
DWARFDIE GetDIE(dw_offset_t die_offset)
Definition: DWARFUnit.cpp:641
die_iterator_range dies()
Definition: DWARFUnit.h:217
lldb::ByteOrder GetByteOrder() const
Definition: DWARFUnit.cpp:623
const lldb_private::FileSpec & GetCompilationDirectory()
Definition: DWARFUnit.cpp:777
std::optional< uint64_t > GetDWOId()
Definition: DWARFUnit.cpp:367
bool HasAny(llvm::ArrayRef< dw_tag_t > tags)
Returns true if any DIEs in the unit match any DW_TAG values in tags.
Definition: DWARFUnit.cpp:1083
lldb_private::FileSpec GetFile(size_t file_idx)
Definition: DWARFUnit.cpp:789
dw_offset_t GetOffset() const
Definition: DWARFUnit.h:134
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)
UniqueDWARFASTTypeMap & GetUniqueDWARFASTTypeMap()
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(lldb_private::Address &addr)
Convert addr from a .o file address, to an executable address.
lldb_private::CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override
static lldb_private::CompilerDeclContext GetContainingDeclContext(const DWARFDIE &die)
virtual lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(const DWARFDIE &die, lldb_private::ConstString type_name, bool must_be_implementation)
static bool SupportedVersion(uint16_t version)
std::optional< uint32_t > GetDWARFUnitIndex(uint32_t cu_idx)
virtual DIEToVariableSP & GetDIEToVariable()
llvm::DenseMap< const DWARFDebugInfoEntry *, lldb::VariableSP > DIEToVariableSP
lldb_private::CompileUnit * GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu)
DWARFDebugRanges * GetDebugRanges()
void BuildCuTranslationTable()
size_t ParseVariablesForContext(const lldb_private::SymbolContext &sc) override
DWARFDIE FindBlockContainingSpecification(const DIERef &func_die_ref, dw_offset_t spec_block_die_offset)
void Dump(lldb_private::Stream &s) override
size_t ParseVariablesInFunctionContext(const lldb_private::SymbolContext &sc, const DWARFDIE &die, const lldb::addr_t func_low_pc)
bool HasForwardDeclForClangType(const lldb_private::CompilerType &compiler_type)
void UpdateExternalModuleListIfNeeded()
DebugMacrosMap m_debug_macros_map
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).
const lldb_private::FileSpecList & GetTypeUnitSupportFiles(DWARFTypeUnit &tu)
bool ResolveFunction(const DWARFDIE &die, bool include_inlines, lldb_private::SymbolContextList &sc_list)
static char ID
LLVM RTTI support.
size_t ParseVariablesInFunctionContextRecursive(const lldb_private::SymbolContext &sc, const DWARFDIE &die, lldb::addr_t func_low_pc, DIEArray &accumulator)
DWARFDebugAbbrev * DebugAbbrev()
lldb_private::Type * ResolveType(const DWARFDIE &die, bool assert_not_being_parsed=true, bool resolve_function_context=false)
ExternalTypeModuleMap m_external_type_modules
std::unique_ptr< DWARFDebugAbbrev > m_abbr
size_t PopulateBlockVariableList(lldb_private::VariableList &variable_list, const lldb_private::SymbolContext &sc, llvm::ArrayRef< DIERef > variable_dies, lldb::addr_t func_low_pc)
lldb_private::Function * ParseFunction(lldb_private::CompileUnit &comp_unit, const DWARFDIE &die)
lldb::ModuleSP GetExternalModule(lldb_private::ConstString name)
void InitializeFirstCodeAddressRecursive(const lldb_private::SectionList &section_list)
const std::shared_ptr< SymbolFileDWARFDwo > & GetDwpSymbolFile()
friend class DWARFDIE
size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override
std::recursive_mutex & GetModuleMutex() const override
Symbols file subclasses should override this to return the Module that owns the TypeSystem that this ...
virtual DWARFCompileUnit * GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
std::optional< ArrayInfo > GetDynamicArrayInfoForUID(lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) override
If type_uid points to an array type, return its characteristics.
lldb_private::CompilerDeclContext FindNamespace(lldb_private::ConstString name, const lldb_private::CompilerDeclContext &parent_decl_ctx) override
lldb_private::RangeDataVector< lldb::addr_t, lldb::addr_t, lldb_private::Variable * > GlobalVariableMap
uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) override
bool CompleteType(lldb_private::CompilerType &compiler_type) override
GlobalVariableMap & GetGlobalAranges()
lldb::TypeSP GetTypeForDIE(const DWARFDIE &die, bool resolve_function_context=false)
NameToOffsetMap m_function_scope_qualified_name_map
bool ParseImportedModules(const lldb_private::SymbolContext &sc, std::vector< lldb_private::SourceModule > &imported_modules) override
size_t ParseBlocksRecursive(lldb_private::Function &func) override
lldb::LanguageType ParseLanguage(lldb_private::CompileUnit &comp_unit) override
lldb_private::ConstString ConstructFunctionDemangledName(const DWARFDIE &die)
std::unique_ptr< GlobalVariableMap > m_global_aranges_up
bool ForEachExternalModule(lldb_private::CompileUnit &, llvm::DenseSet< lldb_private::SymbolFile * > &, llvm::function_ref< bool(lldb_private::Module &)>) override
lldb_private::FileSpec GetFile(DWARFUnit &unit, size_t file_idx)
size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override
virtual DWARFDIE GetDIE(const DIERef &die_ref)
SymbolFileDWARF(lldb::ObjectFileSP objfile_sp, lldb_private::SectionList *dwo_section_list)
static void Initialize()
void InitializeFirstCodeAddress()
bool DeclContextMatchesThisSymbolFile(const lldb_private::CompilerDeclContext &decl_ctx)
lldb::TypeSP ParseType(const lldb_private::SymbolContext &sc, const DWARFDIE &die, bool *type_is_new)
static bool DIEInDeclContext(const lldb_private::CompilerDeclContext &parent_decl_ctx, const DWARFDIE &die)
static lldb_private::CompilerDecl GetDecl(const DWARFDIE &die)
static void DebuggerInitialize(lldb_private::Debugger &debugger)
virtual void LoadSectionData(lldb::SectionType sect_type, lldb_private::DWARFDataExtractor &data)
void FindTypes(lldb_private::ConstString name, const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet< lldb_private::SymbolFile * > &searched_symbol_files, lldb_private::TypeMap &types) override
uint32_t CalculateNumCompileUnits() override
static llvm::StringRef GetPluginNameStatic()
llvm::DenseMap< dw_offset_t, lldb_private::FileSpecList > m_type_unit_support_files
lldb_private::Type * ResolveTypeUID(lldb::user_id_t type_uid) override
static lldb::LanguageType GetLanguage(DWARFUnit &unit)
bool ClassOrStructIsVirtual(const DWARFDIE &die)
std::shared_ptr< SymbolFileDWARFDwo > m_dwp_symfile
std::unique_ptr< DWARFDebugRanges > m_ranges
void FindGlobalVariables(lldb_private::ConstString name, const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, lldb_private::VariableList &variables) override
bool GetFunction(const DWARFDIE &die, lldb_private::SymbolContext &sc)
static lldb_private::SymbolFile * CreateInstance(lldb::ObjectFileSP objfile_sp)
lldb_private::XcodeSDK ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override
Return the Xcode SDK comp_unit was compiled against.
lldb_private::StatsDuration m_parse_time
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
SymbolFileDWARFDebugMap * GetDebugMapSymfile()
std::shared_ptr< SymbolFileDWARFDwo > GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die)
bool m_fetched_external_modules
lldb::addr_t m_first_code_address
DWARF does not provide a good way for traditional (concatenating) linkers to invalidate debug info de...
static DWARFDeclContext GetDWARFDeclContext(const DWARFDIE &die)
~SymbolFileDWARF() override
lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override
Return the time it took to index the debug information in the object file.
lldb_private::DWARFContext m_context
DWARFDebugInfo & DebugInfo()
lldb_private::Status CalculateFrameVariableError(lldb_private::StackFrame &frame) override
Subclasses will override this function to for GetFrameVariableError().
virtual lldb::TypeSP FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die)
static llvm::StringRef GetPluginDescriptionStatic()
std::vector< std::unique_ptr< lldb_private::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...
DIEArray MergeBlockAbstractParameters(const DWARFDIE &block_die, DIEArray &&variable_dies)
DWARFDIE GetDeclContextDIEContainingDIE(const DWARFDIE &die)
void ResolveFunctionAndBlock(lldb::addr_t file_vm_addr, bool lookup_block, lldb_private::SymbolContext &sc)
Resolve functions and (possibly) blocks for the given file address and a compile unit.
llvm::once_flag m_info_once_flag
void InitializeObject() override
Initialize the SymbolFile object.
static llvm::Expected< lldb::TypeSystemSP > GetTypeSystem(DWARFUnit &unit)
std::vector< uint32_t > m_lldb_cu_to_dwarf_unit
lldb_private::Symbol * GetObjCClassSymbol(lldb_private::ConstString objc_class_name)
void GetMangledNamesForFunction(const std::string &scope_qualified_name, std::vector< lldb_private::ConstString > &mangled_names) override
std::atomic_flag m_dwo_warning_issued
void PreloadSymbols() override
lldb::VariableSP ParseVariableDIE(const lldb_private::SymbolContext &sc, const DWARFDIE &die, const lldb::addr_t func_low_pc)
lldb_private::TypeList & GetTypeList() override
std::unique_ptr< lldb_private::DWARFIndex > m_index
std::vector< std::unique_ptr< lldb_private::CallEdge > > ParseCallEdgesInFunction(lldb_private::UserID func_id) override
llvm::once_flag m_dwp_symfile_once_flag
lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu)
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override
llvm::SetVector< lldb_private::Type * > TypeSet
static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val)
void DumpClangAST(lldb_private::Stream &s) override
bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit, lldb_private::FileSpecList &support_files) override
static DWARFDIE GetParentSymbolContextDIE(const DWARFDIE &die)
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...
static void Terminate()
llvm::Expected< lldb::TypeSystemSP > GetTypeSystemForLanguage(lldb::LanguageType language) override
lldb_private::CompilerDecl GetDeclForUID(lldb::user_id_t uid) override
std::unique_ptr< DWARFDebugInfo > m_info
virtual void GetObjCMethods(lldb_private::ConstString class_name, llvm::function_ref< bool(DWARFDIE die)> callback)
virtual DIEToTypePtr & GetDIEToType()
void GetTypes(lldb_private::SymbolContextScope *sc_scope, lldb::TypeClass type_mask, lldb_private::TypeList &type_list) override
lldb_private::CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override
void ParseAndAppendGlobalVariable(const lldb_private::SymbolContext &sc, const DWARFDIE &die, lldb_private::VariableList &cc_variable_list)
virtual ClangTypeToDIE & GetForwardDeclClangTypeToDie()
lldb::ModuleWP m_debug_map_module_wp
lldb::VariableSP ParseVariableDIECached(const lldb_private::SymbolContext &sc, const DWARFDIE &die)
SymbolFileDWARFDebugMap * m_debug_map_symfile
bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override
UniqueDWARFASTTypeMap m_unique_ast_type_map
void ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override
bool DIEDeclContextsMatch(const DWARFDIE &die1, const DWARFDIE &die2)
bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override
lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type
static lldb_private::CompilerDeclContext GetDeclContext(const DWARFDIE &die)
bool ParseIsOptimized(lldb_private::CompileUnit &comp_unit) override
virtual UniqueDWARFASTTypeMap & GetUniqueDWARFASTTypeMap()
void FindFunctions(const lldb_private::Module::LookupInfo &lookup_info, const lldb_private::CompilerDeclContext &parent_decl_ctx, bool include_inlines, lldb_private::SymbolContextList &sc_list) override
A section + offset based address range class.
Definition: AddressRange.h:25
Address & GetBaseAddress()
Get accessor for the base address of the range.
Definition: AddressRange.h:209
void SetByteSize(lldb::addr_t byte_size)
Set accessor for the byte size of this range.
Definition: AddressRange.h:237
A section + offset based address class.
Definition: Address.h:59
bool ResolveAddressUsingFileSections(lldb::addr_t addr, const SectionList *sections)
Resolve a file virtual address using a section list.
Definition: Address.cpp:248
lldb::SectionSP GetSection() const
Get const accessor for the section.
Definition: Address.h:429
void Clear()
Clear the object's state.
Definition: Address.h:178
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:291
lldb::addr_t GetOffset() const
Get the section relative offset value.
Definition: Address.h:319
bool IsValid() const
Check if the object state is valid.
Definition: Address.h:345
static std::unique_ptr< AppleDWARFIndex > Create(Module &module, DWARFDataExtractor apple_names, DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types, DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str)
A class that describes a single lexical block.
Definition: Block.h:41
lldb::VariableListSP GetBlockVariableList(bool can_create)
Get the variable list for this block only.
Definition: Block.cpp:399
Block * FindBlockByID(lldb::user_id_t block_id)
Definition: Block.cpp:112
void SetVariableList(lldb::VariableListSP &variable_list_sp)
Set accessor for the variable list.
Definition: Block.h:331
bool GetStartAddress(Address &addr)
Definition: Block.cpp:317
void SetDidParseVariables(bool b, bool set_children)
Definition: Block.cpp:496
void AddRange(const Range &range)
Add a new offset range to this block.
Definition: Block.cpp:335
void FinalizeRanges()
Definition: Block.cpp:330
void AddChild(const lldb::BlockSP &child_block_sp)
Add a child to this object.
Definition: Block.cpp:385
void SetInlinedFunctionInfo(const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr)
Set accessor for any inlined function information.
Definition: Block.cpp:392
static bool ExtractContextAndIdentifier(const char *name, llvm::StringRef &context, llvm::StringRef &identifier)
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.
Definition: CompileUnit.h:41
void SetVariableList(lldb::VariableListSP &variable_list_sp)
Set accessor for the variable list.
lldb::VariableListSP GetVariableList(bool can_create)
Get the variable list for a compile unit.
void SetDebugMacros(const DebugMacrosSP &debug_macros)
void SetSupportFiles(const FileSpecList &support_files)
const FileSpec & GetPrimaryFile() const
Return the primary source file associated with this compile unit.
Definition: CompileUnit.h:227
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.
const FileSpecList & GetSupportFiles()
Get the compile unit's support file list.
lldb::LanguageType GetLanguage()
LineTable * GetLineTable()
Get the line table for the compile unit.
Represents a generic declaration context in a program.
bool IsContainedInLookup(CompilerDeclContext other) const
Check if the given other decl context is contained in the lookup of this decl context (for example be...
Represents a generic declaration such as a function declaration.
Definition: CompilerDecl.h:28
std::shared_ptr< TypeSystemType > dyn_cast_or_null()
Return a shared_ptr<TypeSystemType> if dyn_cast succeeds.
Definition: CompilerType.h:68
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
TypeSystemSPWrapper GetTypeSystem() const
Accessors.
lldb::opaque_compiler_type_t GetOpaqueQualType() const
Definition: CompilerType.h:234
A uniqued constant string class.
Definition: ConstString.h:39
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:192
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:303
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:201
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:215
const DWARFDataExtractor & getOrLoadLineData()
const DWARFDataExtractor & getOrLoadStrData()
llvm::DWARFContext & GetAsLLVM()
const DWARFDataExtractor & getOrLoadRangesData()
const DWARFDataExtractor & getOrLoadAbbrevData()
const DWARFDataExtractor & getOrLoadMacroData()
llvm::DWARFDataExtractor GetAsLLVM() const
"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
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 DWARFUnit *dwarf_cu, uint32_t op_addr_idx, bool &error) const
If a location is not a location list, return true if the location contains a DW_OP_addr () opcode in ...
void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size, uint8_t addr_byte_size)
bool Update_DW_OP_addr(const DWARFUnit *dwarf_cu, lldb::addr_t file_addr)
static bool ParseDWARFLocationList(const DWARFUnit *dwarf_cu, const DataExtractor &data, DWARFExpressionList *loc_list)
An data extractor class.
Definition: DataExtractor.h:48
void Clear()
Clears the object state.
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
const uint8_t * GetDataStart() const
Get the data start pointer.
bool ValidOffset(lldb::offset_t offset) const
Test the validity of offset.
static llvm::Expected< std::unique_ptr< DebugNamesDWARFIndex > > Create(Module &module, DWARFDataExtractor debug_names, DWARFDataExtractor debug_str, SymbolFileDWARF &dwarf)
A class to manage flag bits.
Definition: Debugger.h:78
A class that describes the declaration location of a lldb object.
Definition: Declaration.h:24
void SetLine(uint32_t line)
Set accessor for the declaration line number.
Definition: Declaration.h:168
void SetColumn(uint16_t column)
Set accessor for the declaration column number.
Definition: Declaration.h:175
void SetFile(const FileSpec &file_spec)
Set accessor for the declaration file specification.
Definition: Declaration.h:161
A class that measures elapsed time in an exception safe way.
Definition: Statistics.h:68
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
A file utility class.
Definition: FileSpec.h:56
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition: FileSpec.cpp:173
void AppendPathComponent(llvm::StringRef component)
Definition: FileSpec.cpp:453
static bool Match(const FileSpec &pattern, const FileSpec &file)
Match FileSpec pattern against FileSpec file.
Definition: FileSpec.cpp:300
bool IsRelative() const
Returns true if the filespec represents a relative path.
Definition: FileSpec.cpp:493
void MakeAbsolute(const FileSpec &dir)
Make the FileSpec absolute by treating it relative to dir.
Definition: FileSpec.cpp:516
void PrependPathComponent(llvm::StringRef component)
Definition: FileSpec.cpp:439
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:366
llvm::sys::path::Style Style
Definition: FileSpec.h:58
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
static FileSystem & Instance()
A class that describes a function.
Definition: Function.h:409
const AddressRange & GetAddressRange()
Definition: Function.h:457
lldb::ModuleSP CalculateSymbolContextModule() override
Definition: Function.cpp:408
CompileUnit * GetCompileUnit()
Get accessor for the compile unit that owns this function.
Definition: Function.cpp:360
Block & GetBlock(bool can_create)
Get accessor for the block list.
Definition: Function.cpp:345
static const char * GetNameForLanguageType(lldb::LanguageType language)
Definition: Language.cpp:216
static bool LanguageIsCPlusPlus(lldb::LanguageType language)
Definition: Language.cpp:249
A line table class.
Definition: LineTable.h:40
static std::unique_ptr< LineSequence > CreateLineSequenceContainer()
Definition: LineTable.cpp:65
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.
Definition: LineTable.cpp:188
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)
Definition: LineTable.cpp:69
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
Definition: ModuleChild.cpp:24
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)
Definition: ModuleList.cpp:786
FileSpec & GetFileSpec()
Definition: ModuleSpec.h:53
ArchSpec & GetArchitecture()
Definition: ModuleSpec.h:89
FileSpec & GetSymbolFileSpec()
Definition: ModuleSpec.h:77
A class that encapsulates name lookup information.
Definition: Module.h:950
lldb::FunctionNameType GetNameTypeMask() const
Definition: Module.h:965
void SetLookupName(ConstString name)
Definition: Module.h:963
ConstString GetLookupName() const
Definition: Module.h:961
A class that describes an executable image and its associated object and symbol files.
Definition: Module.h:88
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:62
Symtab * GetSymtab()
Gets the symbol table for the currently selected architecture (and object for archives).
Definition: ObjectFile.cpp:725
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.
@ eTypeDebugInfo
An object file that contains only debug information.
Definition: ObjectFile.h:73
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool CreateSettingForSymbolFilePlugin(Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, ConstString description, bool is_global_property)
static lldb::OptionValuePropertiesSP GetSettingForSymbolFilePlugin(Debugger &debugger, ConstString setting_name)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A Progress indicator helper class.
Definition: Progress.h:56
RangeData< B, S, T > Entry
Definition: RangeMap.h:443
BaseType GetMaxRangeEnd(BaseType fail_value) const
Definition: RangeMap.h:272
Entry & GetEntryRef(size_t i)
Definition: RangeMap.h:303
BaseType GetMinRangeBase(BaseType fail_value) const
Definition: RangeMap.h:261
size_t GetSize() const
Definition: RangeMap.h:295
llvm::StringRef GetText() const
Access the regular expression text.
unsigned long long ULongLong(unsigned long long fail_value=0) const
Definition: Scalar.cpp:334
lldb::SectionSP FindSectionByName(ConstString section_dstr) const
Definition: Section.cpp:546
lldb::SectionSP FindSectionByType(lldb::SectionType sect_type, bool check_children, size_t start_idx=0) const
Definition: Section.cpp:586
SectionList & GetChildren()
Definition: Section.h:132