1 //===-- SymbolFileDWARF.cpp -----------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "SymbolFileDWARF.h"
11 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
12 #include "llvm/Support/Casting.h"
13 #include "llvm/Support/FileUtilities.h"
14 #include "llvm/Support/Format.h"
15 #include "llvm/Support/Threading.h"
17 #include "lldb/Core/Module.h"
18 #include "lldb/Core/ModuleList.h"
19 #include "lldb/Core/ModuleSpec.h"
20 #include "lldb/Core/PluginManager.h"
21 #include "lldb/Core/Progress.h"
22 #include "lldb/Core/Section.h"
23 #include "lldb/Core/Value.h"
24 #include "lldb/Utility/ArchSpec.h"
25 #include "lldb/Utility/LLDBLog.h"
26 #include "lldb/Utility/RegularExpression.h"
27 #include "lldb/Utility/Scalar.h"
28 #include "lldb/Utility/StreamString.h"
29 #include "lldb/Utility/StructuredData.h"
30 #include "lldb/Utility/Timer.h"
32 #include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
33 #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
35 #include "lldb/Host/FileSystem.h"
36 #include "lldb/Host/Host.h"
38 #include "lldb/Interpreter/OptionValueFileSpecList.h"
39 #include "lldb/Interpreter/OptionValueProperties.h"
41 #include "Plugins/ExpressionParser/Clang/ClangUtil.h"
42 #include "Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h"
43 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
44 #include "lldb/Symbol/Block.h"
45 #include "lldb/Symbol/CompileUnit.h"
46 #include "lldb/Symbol/CompilerDecl.h"
47 #include "lldb/Symbol/CompilerDeclContext.h"
48 #include "lldb/Symbol/DebugMacros.h"
49 #include "lldb/Symbol/LineTable.h"
50 #include "lldb/Symbol/ObjectFile.h"
51 #include "lldb/Symbol/SymbolFile.h"
52 #include "lldb/Symbol/TypeMap.h"
53 #include "lldb/Symbol/TypeSystem.h"
54 #include "lldb/Symbol/VariableList.h"
56 #include "lldb/Target/Language.h"
57 #include "lldb/Target/Target.h"
59 #include "AppleDWARFIndex.h"
60 #include "DWARFASTParser.h"
61 #include "DWARFASTParserClang.h"
62 #include "DWARFCompileUnit.h"
63 #include "DWARFDebugAranges.h"
64 #include "DWARFDebugInfo.h"
65 #include "DWARFDebugMacro.h"
66 #include "DWARFDeclContext.h"
67 #include "DWARFFormValue.h"
68 #include "DWARFTypeUnit.h"
69 #include "DWARFUnit.h"
70 #include "DebugNamesDWARFIndex.h"
71 #include "LogChannelDWARF.h"
72 #include "ManualDWARFIndex.h"
73 #include "SymbolFileDWARFDebugMap.h"
74 #include "SymbolFileDWARFDwo.h"
76 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
77 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
78 #include "llvm/Support/FileSystem.h"
79 #include "llvm/Support/FormatVariadic.h"
89 //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
91 #ifdef ENABLE_DEBUG_PRINTF
93 #define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
95 #define DEBUG_PRINTF(fmt, ...)
99 using namespace lldb_private
;
100 using namespace lldb_private::dwarf
;
101 using namespace lldb_private::plugin::dwarf
;
103 LLDB_PLUGIN_DEFINE(SymbolFileDWARF
)
105 char SymbolFileDWARF::ID
;
109 #define LLDB_PROPERTIES_symbolfiledwarf
110 #include "SymbolFileDWARFProperties.inc"
113 #define LLDB_PROPERTIES_symbolfiledwarf
114 #include "SymbolFileDWARFPropertiesEnum.inc"
117 class PluginProperties
: public Properties
{
119 static llvm::StringRef
GetSettingName() {
120 return SymbolFileDWARF::GetPluginNameStatic();
124 m_collection_sp
= std::make_shared
<OptionValueProperties
>(GetSettingName());
125 m_collection_sp
->Initialize(g_symbolfiledwarf_properties
);
128 bool IgnoreFileIndexes() const {
129 return GetPropertyAtIndexAs
<bool>(ePropertyIgnoreIndexes
, false);
135 bool IsStructOrClassTag(llvm::dwarf::Tag Tag
) {
136 return Tag
== llvm::dwarf::Tag::DW_TAG_class_type
||
137 Tag
== llvm::dwarf::Tag::DW_TAG_structure_type
;
140 static PluginProperties
&GetGlobalPluginProperties() {
141 static PluginProperties g_settings
;
145 static const llvm::DWARFDebugLine::LineTable
*
146 ParseLLVMLineTable(DWARFContext
&context
, llvm::DWARFDebugLine
&line
,
147 dw_offset_t line_offset
, dw_offset_t unit_offset
) {
148 Log
*log
= GetLog(DWARFLog::DebugInfo
);
150 llvm::DWARFDataExtractor data
= context
.getOrLoadLineData().GetAsLLVMDWARF();
151 llvm::DWARFContext
&ctx
= context
.GetAsLLVM();
152 llvm::Expected
<const llvm::DWARFDebugLine::LineTable
*> line_table
=
153 line
.getOrParseLineTable(
154 data
, line_offset
, ctx
, nullptr, [&](llvm::Error e
) {
157 "SymbolFileDWARF::ParseLineTable failed to parse: {0}");
161 LLDB_LOG_ERROR(log
, line_table
.takeError(),
162 "SymbolFileDWARF::ParseLineTable failed to parse: {0}");
168 static bool ParseLLVMLineTablePrologue(DWARFContext
&context
,
169 llvm::DWARFDebugLine::Prologue
&prologue
,
170 dw_offset_t line_offset
,
171 dw_offset_t unit_offset
) {
172 Log
*log
= GetLog(DWARFLog::DebugInfo
);
174 llvm::DWARFDataExtractor data
= context
.getOrLoadLineData().GetAsLLVMDWARF();
175 llvm::DWARFContext
&ctx
= context
.GetAsLLVM();
176 uint64_t offset
= line_offset
;
177 llvm::Error error
= prologue
.parse(
181 LLDB_LOG_ERROR(log
, std::move(e
),
182 "SymbolFileDWARF::ParseSupportFiles failed to parse "
183 "line table prologue: {0}");
187 LLDB_LOG_ERROR(log
, std::move(error
),
188 "SymbolFileDWARF::ParseSupportFiles failed to parse line "
189 "table prologue: {0}");
195 static std::optional
<std::string
>
196 GetFileByIndex(const llvm::DWARFDebugLine::Prologue
&prologue
, size_t idx
,
197 llvm::StringRef compile_dir
, FileSpec::Style style
) {
198 // Try to get an absolute path first.
199 std::string abs_path
;
200 auto absolute
= llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath
;
201 if (prologue
.getFileNameByIndex(idx
, compile_dir
, absolute
, abs_path
, style
))
202 return std::move(abs_path
);
204 // Otherwise ask for a relative path.
205 std::string rel_path
;
206 auto relative
= llvm::DILineInfoSpecifier::FileLineInfoKind::RawValue
;
207 if (!prologue
.getFileNameByIndex(idx
, compile_dir
, relative
, rel_path
, style
))
209 return std::move(rel_path
);
212 static void ParseSupportFilesFromPrologue(
213 SupportFileList
&support_files
, const lldb::ModuleSP
&module
,
214 const llvm::DWARFDebugLine::Prologue
&prologue
, FileSpec::Style style
,
215 llvm::StringRef compile_dir
= {}) {
216 // Handle the case where there are no files first to avoid having to special
218 if (prologue
.FileNames
.empty())
221 // Before DWARF v5, the line table indexes were one based.
222 const bool is_one_based
= prologue
.getVersion() < 5;
223 const size_t file_names
= prologue
.FileNames
.size();
224 const size_t first_file_idx
= is_one_based
? 1 : 0;
225 const size_t last_file_idx
= is_one_based
? file_names
: file_names
- 1;
227 // Add a dummy entry to ensure the support file list indices match those we
228 // get from the debug info and line tables.
230 support_files
.Append(FileSpec());
232 for (size_t idx
= first_file_idx
; idx
<= last_file_idx
; ++idx
) {
233 std::string remapped_file
;
234 if (auto file_path
= GetFileByIndex(prologue
, idx
, compile_dir
, style
)) {
235 auto entry
= prologue
.getFileNameEntry(idx
);
236 auto source
= entry
.Source
.getAsCString();
238 consumeError(source
.takeError());
240 llvm::StringRef
source_ref(*source
);
241 if (!source_ref
.empty()) {
242 /// Wrap a path for an in-DWARF source file. Lazily write it
243 /// to disk when Materialize() is called.
244 struct LazyDWARFSourceFile
: public SupportFile
{
245 LazyDWARFSourceFile(const FileSpec
&fs
, llvm::StringRef source
,
246 FileSpec::Style style
)
247 : SupportFile(fs
), source(source
), style(style
) {}
249 /// The file contents buffer.
250 llvm::StringRef source
;
251 /// Deletes the temporary file at the end.
252 std::unique_ptr
<llvm::FileRemover
> remover
;
253 FileSpec::Style style
;
255 /// Write the file contents to a temporary file.
256 const FileSpec
&Materialize() override
{
259 llvm::SmallString
<0> name
;
261 auto orig_name
= m_file_spec
.GetFilename().GetStringRef();
262 auto ec
= llvm::sys::fs::createTemporaryFile(
263 "", llvm::sys::path::filename(orig_name
, style
), fd
, name
);
265 LLDB_LOG(GetLog(DWARFLog::DebugInfo
),
266 "Could not create temporary file");
269 remover
= std::make_unique
<llvm::FileRemover
>(name
);
270 NativeFile
file(fd
, File::eOpenOptionWriteOnly
, true);
271 size_t num_bytes
= source
.size();
272 file
.Write(source
.data(), num_bytes
);
273 tmp_file
.SetPath(name
);
277 support_files
.Append(std::make_unique
<LazyDWARFSourceFile
>(
278 FileSpec(*file_path
), *source
, style
));
282 if (auto remapped
= module
->RemapSourceFile(llvm::StringRef(*file_path
)))
283 remapped_file
= *remapped
;
285 remapped_file
= std::move(*file_path
);
289 if (prologue
.ContentTypes
.HasMD5
) {
290 const llvm::DWARFDebugLine::FileNameEntry
&file_name_entry
=
291 prologue
.getFileNameEntry(idx
);
292 checksum
= file_name_entry
.Checksum
;
295 // Unconditionally add an entry, so the indices match up.
296 support_files
.EmplaceBack(FileSpec(remapped_file
, style
), checksum
);
300 void SymbolFileDWARF::Initialize() {
301 LogChannelDWARF::Initialize();
302 PluginManager::RegisterPlugin(GetPluginNameStatic(),
303 GetPluginDescriptionStatic(), CreateInstance
,
305 SymbolFileDWARFDebugMap::Initialize();
308 void SymbolFileDWARF::DebuggerInitialize(Debugger
&debugger
) {
309 if (!PluginManager::GetSettingForSymbolFilePlugin(
310 debugger
, PluginProperties::GetSettingName())) {
311 const bool is_global_setting
= true;
312 PluginManager::CreateSettingForSymbolFilePlugin(
313 debugger
, GetGlobalPluginProperties().GetValueProperties(),
314 "Properties for the dwarf symbol-file plug-in.", is_global_setting
);
318 void SymbolFileDWARF::Terminate() {
319 SymbolFileDWARFDebugMap::Terminate();
320 PluginManager::UnregisterPlugin(CreateInstance
);
321 LogChannelDWARF::Terminate();
324 llvm::StringRef
SymbolFileDWARF::GetPluginDescriptionStatic() {
325 return "DWARF and DWARF3 debug symbol file reader.";
328 SymbolFile
*SymbolFileDWARF::CreateInstance(ObjectFileSP objfile_sp
) {
329 return new SymbolFileDWARF(std::move(objfile_sp
),
330 /*dwo_section_list*/ nullptr);
333 TypeList
&SymbolFileDWARF::GetTypeList() {
334 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
335 if (SymbolFileDWARFDebugMap
*debug_map_symfile
= GetDebugMapSymfile())
336 return debug_map_symfile
->GetTypeList();
337 return SymbolFileCommon::GetTypeList();
339 void SymbolFileDWARF::GetTypes(const DWARFDIE
&die
, dw_offset_t min_die_offset
,
340 dw_offset_t max_die_offset
, uint32_t type_mask
,
343 const dw_offset_t die_offset
= die
.GetOffset();
345 if (die_offset
>= max_die_offset
)
348 if (die_offset
>= min_die_offset
) {
349 const dw_tag_t tag
= die
.Tag();
351 bool add_type
= false;
354 case DW_TAG_array_type
:
355 add_type
= (type_mask
& eTypeClassArray
) != 0;
357 case DW_TAG_unspecified_type
:
358 case DW_TAG_base_type
:
359 add_type
= (type_mask
& eTypeClassBuiltin
) != 0;
361 case DW_TAG_class_type
:
362 add_type
= (type_mask
& eTypeClassClass
) != 0;
364 case DW_TAG_structure_type
:
365 add_type
= (type_mask
& eTypeClassStruct
) != 0;
367 case DW_TAG_union_type
:
368 add_type
= (type_mask
& eTypeClassUnion
) != 0;
370 case DW_TAG_enumeration_type
:
371 add_type
= (type_mask
& eTypeClassEnumeration
) != 0;
373 case DW_TAG_subroutine_type
:
374 case DW_TAG_subprogram
:
375 case DW_TAG_inlined_subroutine
:
376 add_type
= (type_mask
& eTypeClassFunction
) != 0;
378 case DW_TAG_pointer_type
:
379 add_type
= (type_mask
& eTypeClassPointer
) != 0;
381 case DW_TAG_rvalue_reference_type
:
382 case DW_TAG_reference_type
:
383 add_type
= (type_mask
& eTypeClassReference
) != 0;
386 add_type
= (type_mask
& eTypeClassTypedef
) != 0;
388 case DW_TAG_ptr_to_member_type
:
389 add_type
= (type_mask
& eTypeClassMemberPointer
) != 0;
396 const bool assert_not_being_parsed
= true;
397 Type
*type
= ResolveTypeUID(die
, assert_not_being_parsed
);
399 type_set
.insert(type
);
403 for (DWARFDIE child_die
: die
.children()) {
404 GetTypes(child_die
, min_die_offset
, max_die_offset
, type_mask
, type_set
);
409 void SymbolFileDWARF::GetTypes(SymbolContextScope
*sc_scope
,
410 TypeClass type_mask
, TypeList
&type_list
)
413 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
416 CompileUnit
*comp_unit
= nullptr;
418 comp_unit
= sc_scope
->CalculateSymbolContextCompileUnit();
420 const auto &get
= [&](DWARFUnit
*unit
) {
423 unit
= &unit
->GetNonSkeletonUnit();
424 GetTypes(unit
->DIE(), unit
->GetOffset(), unit
->GetNextUnitOffset(),
425 type_mask
, type_set
);
428 get(GetDWARFCompileUnit(comp_unit
));
430 DWARFDebugInfo
&info
= DebugInfo();
431 const size_t num_cus
= info
.GetNumUnits();
432 for (size_t cu_idx
= 0; cu_idx
< num_cus
; ++cu_idx
)
433 get(info
.GetUnitAtIndex(cu_idx
));
436 std::set
<CompilerType
> compiler_type_set
;
437 for (Type
*type
: type_set
) {
438 CompilerType compiler_type
= type
->GetForwardCompilerType();
439 if (compiler_type_set
.find(compiler_type
) == compiler_type_set
.end()) {
440 compiler_type_set
.insert(compiler_type
);
441 type_list
.Insert(type
->shared_from_this());
446 // Gets the first parent that is a lexical block, function or inlined
447 // subroutine, or compile unit.
449 SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE
&child_die
) {
451 for (die
= child_die
.GetParent(); die
; die
= die
.GetParent()) {
452 dw_tag_t tag
= die
.Tag();
455 case DW_TAG_compile_unit
:
456 case DW_TAG_partial_unit
:
457 case DW_TAG_subprogram
:
458 case DW_TAG_inlined_subroutine
:
459 case DW_TAG_lexical_block
:
468 SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp
,
469 SectionList
*dwo_section_list
)
470 : SymbolFileCommon(std::move(objfile_sp
)), m_debug_map_module_wp(),
471 m_debug_map_symfile(nullptr),
472 m_context(m_objfile_sp
->GetModule()->GetSectionList(), dwo_section_list
),
473 m_fetched_external_modules(false),
474 m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate
) {}
476 SymbolFileDWARF::~SymbolFileDWARF() = default;
478 static ConstString
GetDWARFMachOSegmentName() {
479 static ConstString
g_dwarf_section_name("__DWARF");
480 return g_dwarf_section_name
;
483 llvm::DenseMap
<lldb::opaque_compiler_type_t
, DIERef
> &
484 SymbolFileDWARF::GetForwardDeclCompilerTypeToDIE() {
485 if (SymbolFileDWARFDebugMap
*debug_map_symfile
= GetDebugMapSymfile())
486 return debug_map_symfile
->GetForwardDeclCompilerTypeToDIE();
487 return m_forward_decl_compiler_type_to_die
;
490 UniqueDWARFASTTypeMap
&SymbolFileDWARF::GetUniqueDWARFASTTypeMap() {
491 SymbolFileDWARFDebugMap
*debug_map_symfile
= GetDebugMapSymfile();
492 if (debug_map_symfile
)
493 return debug_map_symfile
->GetUniqueDWARFASTTypeMap();
495 return m_unique_ast_type_map
;
498 llvm::Expected
<lldb::TypeSystemSP
>
499 SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language
) {
500 if (SymbolFileDWARFDebugMap
*debug_map_symfile
= GetDebugMapSymfile())
501 return debug_map_symfile
->GetTypeSystemForLanguage(language
);
503 auto type_system_or_err
=
504 m_objfile_sp
->GetModule()->GetTypeSystemForLanguage(language
);
505 if (type_system_or_err
)
506 if (auto ts
= *type_system_or_err
)
507 ts
->SetSymbolFile(this);
508 return type_system_or_err
;
511 void SymbolFileDWARF::InitializeObject() {
512 Log
*log
= GetLog(DWARFLog::DebugInfo
);
514 InitializeFirstCodeAddress();
516 if (!GetGlobalPluginProperties().IgnoreFileIndexes()) {
517 StreamString module_desc
;
518 GetObjectFile()->GetModule()->GetDescription(module_desc
.AsRawOstream(),
519 lldb::eDescriptionLevelBrief
);
520 DWARFDataExtractor apple_names
, apple_namespaces
, apple_types
, apple_objc
;
521 LoadSectionData(eSectionTypeDWARFAppleNames
, apple_names
);
522 LoadSectionData(eSectionTypeDWARFAppleNamespaces
, apple_namespaces
);
523 LoadSectionData(eSectionTypeDWARFAppleTypes
, apple_types
);
524 LoadSectionData(eSectionTypeDWARFAppleObjC
, apple_objc
);
526 if (apple_names
.GetByteSize() > 0 || apple_namespaces
.GetByteSize() > 0 ||
527 apple_types
.GetByteSize() > 0 || apple_objc
.GetByteSize() > 0) {
528 m_index
= AppleDWARFIndex::Create(
529 *GetObjectFile()->GetModule(), apple_names
, apple_namespaces
,
530 apple_types
, apple_objc
, m_context
.getOrLoadStrData());
536 DWARFDataExtractor debug_names
;
537 LoadSectionData(eSectionTypeDWARFDebugNames
, debug_names
);
538 if (debug_names
.GetByteSize() > 0) {
539 Progress
progress("Loading DWARF5 index", module_desc
.GetData());
540 llvm::Expected
<std::unique_ptr
<DebugNamesDWARFIndex
>> index_or
=
541 DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(),
543 m_context
.getOrLoadStrData(), *this);
545 m_index
= std::move(*index_or
);
548 LLDB_LOG_ERROR(log
, index_or
.takeError(),
549 "Unable to read .debug_names data: {0}");
554 std::make_unique
<ManualDWARFIndex
>(*GetObjectFile()->GetModule(), *this);
557 void SymbolFileDWARF::InitializeFirstCodeAddress() {
558 InitializeFirstCodeAddressRecursive(
559 *m_objfile_sp
->GetModule()->GetSectionList());
560 if (m_first_code_address
== LLDB_INVALID_ADDRESS
)
561 m_first_code_address
= 0;
564 void SymbolFileDWARF::InitializeFirstCodeAddressRecursive(
565 const lldb_private::SectionList
§ion_list
) {
566 for (SectionSP section_sp
: section_list
) {
567 if (section_sp
->GetChildren().GetSize() > 0) {
568 InitializeFirstCodeAddressRecursive(section_sp
->GetChildren());
569 } else if (section_sp
->GetType() == eSectionTypeCode
) {
570 m_first_code_address
=
571 std::min(m_first_code_address
, section_sp
->GetFileAddress());
576 bool SymbolFileDWARF::SupportedVersion(uint16_t version
) {
577 return version
>= 2 && version
<= 5;
580 static std::set
<dw_form_t
>
581 GetUnsupportedForms(llvm::DWARFDebugAbbrev
*debug_abbrev
) {
585 std::set
<dw_form_t
> unsupported_forms
;
586 for (const auto &[_
, decl_set
] : *debug_abbrev
)
587 for (const auto &decl
: decl_set
)
588 for (const auto &attr
: decl
.attributes())
589 if (!DWARFFormValue::FormIsSupported(attr
.Form
))
590 unsupported_forms
.insert(attr
.Form
);
592 return unsupported_forms
;
595 uint32_t SymbolFileDWARF::CalculateAbilities() {
596 uint32_t abilities
= 0;
597 if (m_objfile_sp
!= nullptr) {
598 const Section
*section
= nullptr;
599 const SectionList
*section_list
= m_objfile_sp
->GetSectionList();
600 if (section_list
== nullptr)
603 uint64_t debug_abbrev_file_size
= 0;
604 uint64_t debug_info_file_size
= 0;
605 uint64_t debug_line_file_size
= 0;
607 section
= section_list
->FindSectionByName(GetDWARFMachOSegmentName()).get();
610 section_list
= §ion
->GetChildren();
613 section_list
->FindSectionByType(eSectionTypeDWARFDebugInfo
, true).get();
614 if (section
!= nullptr) {
615 debug_info_file_size
= section
->GetFileSize();
618 section_list
->FindSectionByType(eSectionTypeDWARFDebugAbbrev
, true)
621 debug_abbrev_file_size
= section
->GetFileSize();
623 llvm::DWARFDebugAbbrev
*abbrev
= DebugAbbrev();
624 std::set
<dw_form_t
> unsupported_forms
= GetUnsupportedForms(abbrev
);
625 if (!unsupported_forms
.empty()) {
627 error
.Printf("unsupported DW_FORM value%s:",
628 unsupported_forms
.size() > 1 ? "s" : "");
629 for (auto form
: unsupported_forms
)
630 error
.Printf(" %#x", form
);
631 m_objfile_sp
->GetModule()->ReportWarning("{0}", error
.GetString());
636 section_list
->FindSectionByType(eSectionTypeDWARFDebugLine
, true)
639 debug_line_file_size
= section
->GetFileSize();
641 llvm::StringRef symfile_dir
=
642 m_objfile_sp
->GetFileSpec().GetDirectory().GetStringRef();
643 if (symfile_dir
.contains_insensitive(".dsym")) {
644 if (m_objfile_sp
->GetType() == ObjectFile::eTypeDebugInfo
) {
645 // We have a dSYM file that didn't have a any debug info. If the
646 // string table has a size of 1, then it was made from an
647 // executable with no debug info, or from an executable that was
650 section_list
->FindSectionByType(eSectionTypeDWARFDebugStr
, true)
652 if (section
&& section
->GetFileSize() == 1) {
653 m_objfile_sp
->GetModule()->ReportWarning(
654 "empty dSYM file detected, dSYM was created with an "
655 "executable with no debug info.");
661 constexpr uint64_t MaxDebugInfoSize
= (1ull) << DW_DIE_OFFSET_MAX_BITSIZE
;
662 if (debug_info_file_size
>= MaxDebugInfoSize
) {
663 m_objfile_sp
->GetModule()->ReportWarning(
664 "SymbolFileDWARF can't load this DWARF. It's larger then {0:x+16}",
669 if (debug_abbrev_file_size
> 0 && debug_info_file_size
> 0)
670 abilities
|= CompileUnits
| Functions
| Blocks
| GlobalVariables
|
671 LocalVariables
| VariableTypes
;
673 if (debug_line_file_size
> 0)
674 abilities
|= LineTables
;
679 void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type
,
680 DWARFDataExtractor
&data
) {
681 ModuleSP
module_sp(m_objfile_sp
->GetModule());
682 const SectionList
*section_list
= module_sp
->GetSectionList();
686 SectionSP
section_sp(section_list
->FindSectionByType(sect_type
, true));
691 m_objfile_sp
->ReadSectionData(section_sp
.get(), data
);
694 llvm::DWARFDebugAbbrev
*SymbolFileDWARF::DebugAbbrev() {
698 const DWARFDataExtractor
&debug_abbrev_data
= m_context
.getOrLoadAbbrevData();
699 if (debug_abbrev_data
.GetByteSize() == 0)
702 ElapsedTime
elapsed(m_parse_time
);
704 std::make_unique
<llvm::DWARFDebugAbbrev
>(debug_abbrev_data
.GetAsLLVM());
705 llvm::Error error
= abbr
->parse();
707 Log
*log
= GetLog(DWARFLog::DebugInfo
);
708 LLDB_LOG_ERROR(log
, std::move(error
),
709 "Unable to read .debug_abbrev section: {0}");
713 m_abbr
= std::move(abbr
);
717 DWARFDebugInfo
&SymbolFileDWARF::DebugInfo() {
718 llvm::call_once(m_info_once_flag
, [&] {
721 m_info
= std::make_unique
<DWARFDebugInfo
>(*this, m_context
);
726 DWARFCompileUnit
*SymbolFileDWARF::GetDWARFCompileUnit(CompileUnit
*comp_unit
) {
730 // The compile unit ID is the index of the DWARF unit.
731 DWARFUnit
*dwarf_cu
= DebugInfo().GetUnitAtIndex(comp_unit
->GetID());
732 if (dwarf_cu
&& dwarf_cu
->GetLLDBCompUnit() == nullptr)
733 dwarf_cu
->SetLLDBCompUnit(comp_unit
);
735 // It must be DWARFCompileUnit when it created a CompileUnit.
736 return llvm::cast_or_null
<DWARFCompileUnit
>(dwarf_cu
);
739 /// Make an absolute path out of \p file_spec and remap it using the
740 /// module's source remapping dictionary.
741 static void MakeAbsoluteAndRemap(FileSpec
&file_spec
, DWARFUnit
&dwarf_cu
,
742 const ModuleSP
&module_sp
) {
745 // If we have a full path to the compile unit, we don't need to
746 // resolve the file. This can be expensive e.g. when the source
747 // files are NFS mounted.
748 file_spec
.MakeAbsolute(dwarf_cu
.GetCompilationDirectory());
750 if (auto remapped_file
= module_sp
->RemapSourceFile(file_spec
.GetPath()))
751 file_spec
.SetFile(*remapped_file
, FileSpec::Style::native
);
754 /// Return the DW_AT_(GNU_)dwo_name.
755 static const char *GetDWOName(DWARFCompileUnit
&dwarf_cu
,
756 const DWARFDebugInfoEntry
&cu_die
) {
757 const char *dwo_name
=
758 cu_die
.GetAttributeValueAsString(&dwarf_cu
, DW_AT_GNU_dwo_name
, nullptr);
761 cu_die
.GetAttributeValueAsString(&dwarf_cu
, DW_AT_dwo_name
, nullptr);
765 lldb::CompUnitSP
SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit
&dwarf_cu
) {
767 CompileUnit
*comp_unit
= dwarf_cu
.GetLLDBCompUnit();
769 // We already parsed this compile unit, had out a shared pointer to it
770 cu_sp
= comp_unit
->shared_from_this();
772 if (GetDebugMapSymfile()) {
773 // Let the debug map create the compile unit
774 cu_sp
= m_debug_map_symfile
->GetCompileUnit(this, dwarf_cu
);
775 dwarf_cu
.SetLLDBCompUnit(cu_sp
.get());
777 ModuleSP
module_sp(m_objfile_sp
->GetModule());
779 auto initialize_cu
= [&](lldb::SupportFileSP support_file_sp
,
780 LanguageType cu_language
,
781 SupportFileList
&&support_files
= {}) {
782 BuildCuTranslationTable();
783 cu_sp
= std::make_shared
<CompileUnit
>(
784 module_sp
, &dwarf_cu
, support_file_sp
,
785 *GetDWARFUnitIndex(dwarf_cu
.GetID()), cu_language
,
786 eLazyBoolCalculate
, std::move(support_files
));
788 dwarf_cu
.SetLLDBCompUnit(cu_sp
.get());
790 SetCompileUnitAtIndex(dwarf_cu
.GetID(), cu_sp
);
793 auto lazy_initialize_cu
= [&]() {
794 // If the version is < 5, we can't do lazy initialization.
795 if (dwarf_cu
.GetVersion() < 5)
798 // If there is no DWO, there is no reason to initialize
799 // lazily; we will do eager initialization in that case.
800 if (GetDebugMapSymfile())
802 const DWARFBaseDIE cu_die
= dwarf_cu
.GetUnitDIEOnly();
805 if (!GetDWOName(dwarf_cu
, *cu_die
.GetDIE()))
808 // With DWARFv5 we can assume that the first support
809 // file is also the name of the compile unit. This
810 // allows us to avoid loading the non-skeleton unit,
811 // which may be in a separate DWO file.
812 SupportFileList support_files
;
813 if (!ParseSupportFiles(dwarf_cu
, module_sp
, support_files
))
815 if (support_files
.GetSize() == 0)
817 initialize_cu(support_files
.GetSupportFileAtIndex(0),
818 eLanguageTypeUnknown
, std::move(support_files
));
822 if (!lazy_initialize_cu()) {
823 // Eagerly initialize compile unit
824 const DWARFBaseDIE cu_die
=
825 dwarf_cu
.GetNonSkeletonUnit().GetUnitDIEOnly();
827 LanguageType cu_language
= SymbolFileDWARF::LanguageTypeFromDWARF(
828 dwarf_cu
.GetDWARFLanguageType());
830 FileSpec
cu_file_spec(cu_die
.GetName(), dwarf_cu
.GetPathStyle());
832 // Path needs to be remapped in this case. In the support files
833 // case ParseSupportFiles takes care of the remapping.
834 MakeAbsoluteAndRemap(cu_file_spec
, dwarf_cu
, module_sp
);
836 initialize_cu(std::make_shared
<SupportFile
>(cu_file_spec
),
846 void SymbolFileDWARF::BuildCuTranslationTable() {
847 if (!m_lldb_cu_to_dwarf_unit
.empty())
850 DWARFDebugInfo
&info
= DebugInfo();
851 if (!info
.ContainsTypeUnits()) {
852 // We can use a 1-to-1 mapping. No need to build a translation table.
855 for (uint32_t i
= 0, num
= info
.GetNumUnits(); i
< num
; ++i
) {
856 if (auto *cu
= llvm::dyn_cast
<DWARFCompileUnit
>(info
.GetUnitAtIndex(i
))) {
857 cu
->SetID(m_lldb_cu_to_dwarf_unit
.size());
858 m_lldb_cu_to_dwarf_unit
.push_back(i
);
863 std::optional
<uint32_t> SymbolFileDWARF::GetDWARFUnitIndex(uint32_t cu_idx
) {
864 BuildCuTranslationTable();
865 if (m_lldb_cu_to_dwarf_unit
.empty())
867 if (cu_idx
>= m_lldb_cu_to_dwarf_unit
.size())
869 return m_lldb_cu_to_dwarf_unit
[cu_idx
];
872 uint32_t SymbolFileDWARF::CalculateNumCompileUnits() {
873 BuildCuTranslationTable();
874 return m_lldb_cu_to_dwarf_unit
.empty() ? DebugInfo().GetNumUnits()
875 : m_lldb_cu_to_dwarf_unit
.size();
878 CompUnitSP
SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx
) {
879 ASSERT_MODULE_LOCK(this);
880 if (std::optional
<uint32_t> dwarf_idx
= GetDWARFUnitIndex(cu_idx
)) {
881 if (auto *dwarf_cu
= llvm::cast_or_null
<DWARFCompileUnit
>(
882 DebugInfo().GetUnitAtIndex(*dwarf_idx
)))
883 return ParseCompileUnit(*dwarf_cu
);
888 Function
*SymbolFileDWARF::ParseFunction(CompileUnit
&comp_unit
,
889 const DWARFDIE
&die
) {
890 ASSERT_MODULE_LOCK(this);
894 auto type_system_or_err
= GetTypeSystemForLanguage(GetLanguage(*die
.GetCU()));
895 if (auto err
= type_system_or_err
.takeError()) {
896 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols
), std::move(err
),
897 "Unable to parse function: {0}");
900 auto ts
= *type_system_or_err
;
903 DWARFASTParser
*dwarf_ast
= ts
->GetDWARFParser();
907 AddressRanges ranges
;
908 ModuleSP
module_sp(die
.GetModule());
909 for (const auto &range
: die
.GetDIE()->GetAttributeAddressRanges(
910 die
.GetCU(), /*check_hi_lo_pc=*/true)) {
911 if (range
.base
< m_first_code_address
)
913 if (Address
base_addr(range
.base
, module_sp
->GetSectionList());
914 base_addr
.IsValid() && FixupAddress(base_addr
))
915 ranges
.emplace_back(std::move(base_addr
), range
.size
);
920 return dwarf_ast
->ParseFunctionFromDWARF(comp_unit
, die
, std::move(ranges
));
924 SymbolFileDWARF::ConstructFunctionDemangledName(const DWARFDIE
&die
) {
925 ASSERT_MODULE_LOCK(this);
926 if (!die
.IsValid()) {
927 return ConstString();
930 auto type_system_or_err
= GetTypeSystemForLanguage(GetLanguage(*die
.GetCU()));
931 if (auto err
= type_system_or_err
.takeError()) {
932 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols
), std::move(err
),
933 "Unable to construct demangled name for function: {0}");
934 return ConstString();
937 auto ts
= *type_system_or_err
;
939 LLDB_LOG(GetLog(LLDBLog::Symbols
), "Type system no longer live");
940 return ConstString();
942 DWARFASTParser
*dwarf_ast
= ts
->GetDWARFParser();
944 return ConstString();
946 return dwarf_ast
->ConstructDemangledNameFromDWARF(die
);
949 lldb::addr_t
SymbolFileDWARF::FixupAddress(lldb::addr_t file_addr
) {
950 SymbolFileDWARFDebugMap
*debug_map_symfile
= GetDebugMapSymfile();
951 if (debug_map_symfile
)
952 return debug_map_symfile
->LinkOSOFileAddress(this, file_addr
);
956 bool SymbolFileDWARF::FixupAddress(Address
&addr
) {
957 SymbolFileDWARFDebugMap
*debug_map_symfile
= GetDebugMapSymfile();
958 if (debug_map_symfile
) {
959 return debug_map_symfile
->LinkOSOAddress(addr
);
961 // This is a normal DWARF file, no address fixups need to happen
964 lldb::LanguageType
SymbolFileDWARF::ParseLanguage(CompileUnit
&comp_unit
) {
965 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
966 DWARFUnit
*dwarf_cu
= GetDWARFCompileUnit(&comp_unit
);
968 return GetLanguage(dwarf_cu
->GetNonSkeletonUnit());
970 return eLanguageTypeUnknown
;
973 XcodeSDK
SymbolFileDWARF::ParseXcodeSDK(CompileUnit
&comp_unit
) {
974 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
975 DWARFUnit
*dwarf_cu
= GetDWARFCompileUnit(&comp_unit
);
978 const DWARFBaseDIE cu_die
= dwarf_cu
->GetNonSkeletonUnit().GetUnitDIEOnly();
981 const char *sdk
= cu_die
.GetAttributeValueAsString(DW_AT_APPLE_sdk
, nullptr);
984 const char *sysroot
=
985 cu_die
.GetAttributeValueAsString(DW_AT_LLVM_sysroot
, "");
986 // Register the sysroot path remapping with the module belonging to
987 // the CU as well as the one belonging to the symbol file. The two
988 // would be different if this is an OSO object and module is the
989 // corresponding debug map, in which case both should be updated.
990 ModuleSP module_sp
= comp_unit
.GetModule();
992 module_sp
->RegisterXcodeSDK(sdk
, sysroot
);
994 ModuleSP local_module_sp
= m_objfile_sp
->GetModule();
995 if (local_module_sp
&& local_module_sp
!= module_sp
)
996 local_module_sp
->RegisterXcodeSDK(sdk
, sysroot
);
1001 size_t SymbolFileDWARF::ParseFunctions(CompileUnit
&comp_unit
) {
1002 LLDB_SCOPED_TIMER();
1003 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
1004 DWARFUnit
*dwarf_cu
= GetDWARFCompileUnit(&comp_unit
);
1008 size_t functions_added
= 0;
1009 dwarf_cu
= &dwarf_cu
->GetNonSkeletonUnit();
1010 for (DWARFDebugInfoEntry
&entry
: dwarf_cu
->dies()) {
1011 if (entry
.Tag() != DW_TAG_subprogram
)
1014 DWARFDIE
die(dwarf_cu
, &entry
);
1015 if (comp_unit
.FindFunctionByUID(die
.GetID()))
1017 if (ParseFunction(comp_unit
, die
))
1021 return functions_added
;
1024 bool SymbolFileDWARF::ForEachExternalModule(
1025 CompileUnit
&comp_unit
,
1026 llvm::DenseSet
<lldb_private::SymbolFile
*> &visited_symbol_files
,
1027 llvm::function_ref
<bool(Module
&)> lambda
) {
1028 // Only visit each symbol file once.
1029 if (!visited_symbol_files
.insert(this).second
)
1032 UpdateExternalModuleListIfNeeded();
1033 for (auto &p
: m_external_type_modules
) {
1034 ModuleSP module
= p
.second
;
1038 // Invoke the action and potentially early-exit.
1039 if (lambda(*module
))
1042 for (std::size_t i
= 0; i
< module
->GetNumCompileUnits(); ++i
) {
1043 auto cu
= module
->GetCompileUnitAtIndex(i
);
1044 bool early_exit
= cu
->ForEachExternalModule(visited_symbol_files
, lambda
);
1052 bool SymbolFileDWARF::ParseSupportFiles(CompileUnit
&comp_unit
,
1053 SupportFileList
&support_files
) {
1054 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
1055 DWARFUnit
*dwarf_cu
= GetDWARFCompileUnit(&comp_unit
);
1059 if (!ParseSupportFiles(*dwarf_cu
, comp_unit
.GetModule(), support_files
))
1065 bool SymbolFileDWARF::ParseSupportFiles(DWARFUnit
&dwarf_cu
,
1066 const ModuleSP
&module
,
1067 SupportFileList
&support_files
) {
1069 dw_offset_t offset
= dwarf_cu
.GetLineTableOffset();
1070 if (offset
== DW_INVALID_OFFSET
)
1073 ElapsedTime
elapsed(m_parse_time
);
1074 llvm::DWARFDebugLine::Prologue prologue
;
1075 if (!ParseLLVMLineTablePrologue(m_context
, prologue
, offset
,
1076 dwarf_cu
.GetOffset()))
1079 std::string comp_dir
= dwarf_cu
.GetCompilationDirectory().GetPath();
1080 ParseSupportFilesFromPrologue(support_files
, module
, prologue
,
1081 dwarf_cu
.GetPathStyle(), comp_dir
);
1085 FileSpec
SymbolFileDWARF::GetFile(DWARFUnit
&unit
, size_t file_idx
) {
1086 if (auto *dwarf_cu
= llvm::dyn_cast
<DWARFCompileUnit
>(&unit
)) {
1087 if (CompileUnit
*lldb_cu
= GetCompUnitForDWARFCompUnit(*dwarf_cu
))
1088 return lldb_cu
->GetSupportFiles().GetFileSpecAtIndex(file_idx
);
1092 auto &tu
= llvm::cast
<DWARFTypeUnit
>(unit
);
1093 if (const SupportFileList
*support_files
= GetTypeUnitSupportFiles(tu
))
1094 return support_files
->GetFileSpecAtIndex(file_idx
);
1098 const SupportFileList
*
1099 SymbolFileDWARF::GetTypeUnitSupportFiles(DWARFTypeUnit
&tu
) {
1100 static SupportFileList empty_list
;
1102 dw_offset_t offset
= tu
.GetLineTableOffset();
1103 if (offset
== DW_INVALID_OFFSET
||
1104 offset
== llvm::DenseMapInfo
<dw_offset_t
>::getEmptyKey() ||
1105 offset
== llvm::DenseMapInfo
<dw_offset_t
>::getTombstoneKey())
1108 // Many type units can share a line table, so parse the support file list
1109 // once, and cache it based on the offset field.
1110 auto iter_bool
= m_type_unit_support_files
.try_emplace(offset
);
1111 std::unique_ptr
<SupportFileList
> &list
= iter_bool
.first
->second
;
1112 if (iter_bool
.second
) {
1113 list
= std::make_unique
<SupportFileList
>();
1114 uint64_t line_table_offset
= offset
;
1115 llvm::DWARFDataExtractor data
=
1116 m_context
.getOrLoadLineData().GetAsLLVMDWARF();
1117 llvm::DWARFContext
&ctx
= m_context
.GetAsLLVM();
1118 llvm::DWARFDebugLine::Prologue prologue
;
1119 auto report
= [](llvm::Error error
) {
1120 Log
*log
= GetLog(DWARFLog::DebugInfo
);
1121 LLDB_LOG_ERROR(log
, std::move(error
),
1122 "SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse "
1123 "the line table prologue: {0}");
1125 ElapsedTime
elapsed(m_parse_time
);
1126 llvm::Error error
= prologue
.parse(data
, &line_table_offset
, report
, ctx
);
1128 report(std::move(error
));
1130 ParseSupportFilesFromPrologue(*list
, GetObjectFile()->GetModule(),
1131 prologue
, tu
.GetPathStyle());
1136 bool SymbolFileDWARF::ParseIsOptimized(CompileUnit
&comp_unit
) {
1137 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
1138 DWARFUnit
*dwarf_cu
= GetDWARFCompileUnit(&comp_unit
);
1140 return dwarf_cu
->GetNonSkeletonUnit().GetIsOptimized();
1144 bool SymbolFileDWARF::ParseImportedModules(
1145 const lldb_private::SymbolContext
&sc
,
1146 std::vector
<SourceModule
> &imported_modules
) {
1147 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
1148 assert(sc
.comp_unit
);
1149 DWARFUnit
*dwarf_cu
= GetDWARFCompileUnit(sc
.comp_unit
);
1152 if (!ClangModulesDeclVendor::LanguageSupportsClangModules(
1153 sc
.comp_unit
->GetLanguage()))
1155 UpdateExternalModuleListIfNeeded();
1157 const DWARFDIE die
= dwarf_cu
->DIE();
1161 for (DWARFDIE child_die
: die
.children()) {
1162 if (child_die
.Tag() != DW_TAG_imported_declaration
)
1165 DWARFDIE module_die
= child_die
.GetReferencedDIE(DW_AT_import
);
1166 if (module_die
.Tag() != DW_TAG_module
)
1169 if (const char *name
=
1170 module_die
.GetAttributeValueAsString(DW_AT_name
, nullptr)) {
1171 SourceModule module
;
1172 module
.path
.push_back(ConstString(name
));
1174 DWARFDIE parent_die
= module_die
;
1175 while ((parent_die
= parent_die
.GetParent())) {
1176 if (parent_die
.Tag() != DW_TAG_module
)
1178 if (const char *name
=
1179 parent_die
.GetAttributeValueAsString(DW_AT_name
, nullptr))
1180 module
.path
.push_back(ConstString(name
));
1182 std::reverse(module
.path
.begin(), module
.path
.end());
1183 if (const char *include_path
= module_die
.GetAttributeValueAsString(
1184 DW_AT_LLVM_include_path
, nullptr)) {
1185 FileSpec
include_spec(include_path
, dwarf_cu
->GetPathStyle());
1186 MakeAbsoluteAndRemap(include_spec
, *dwarf_cu
,
1187 m_objfile_sp
->GetModule());
1188 module
.search_path
= ConstString(include_spec
.GetPath());
1190 if (const char *sysroot
= dwarf_cu
->DIE().GetAttributeValueAsString(
1191 DW_AT_LLVM_sysroot
, nullptr))
1192 module
.sysroot
= ConstString(sysroot
);
1193 imported_modules
.push_back(module
);
1199 bool SymbolFileDWARF::ParseLineTable(CompileUnit
&comp_unit
) {
1200 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
1201 if (comp_unit
.GetLineTable() != nullptr)
1204 DWARFUnit
*dwarf_cu
= GetDWARFCompileUnit(&comp_unit
);
1208 dw_offset_t offset
= dwarf_cu
->GetLineTableOffset();
1209 if (offset
== DW_INVALID_OFFSET
)
1212 ElapsedTime
elapsed(m_parse_time
);
1213 llvm::DWARFDebugLine line
;
1214 const llvm::DWARFDebugLine::LineTable
*line_table
=
1215 ParseLLVMLineTable(m_context
, line
, offset
, dwarf_cu
->GetOffset());
1220 // FIXME: Rather than parsing the whole line table and then copying it over
1221 // into LLDB, we should explore using a callback to populate the line table
1222 // while we parse to reduce memory usage.
1223 std::vector
<std::unique_ptr
<LineSequence
>> sequences
;
1224 // The Sequences view contains only valid line sequences. Don't iterate over
1225 // the Rows directly.
1226 for (const llvm::DWARFDebugLine::Sequence
&seq
: line_table
->Sequences
) {
1227 // Ignore line sequences that do not start after the first code address.
1228 // All addresses generated in a sequence are incremental so we only need
1229 // to check the first one of the sequence. Check the comment at the
1230 // m_first_code_address declaration for more details on this.
1231 if (seq
.LowPC
< m_first_code_address
)
1233 std::unique_ptr
<LineSequence
> sequence
=
1234 LineTable::CreateLineSequenceContainer();
1235 for (unsigned idx
= seq
.FirstRowIndex
; idx
< seq
.LastRowIndex
; ++idx
) {
1236 const llvm::DWARFDebugLine::Row
&row
= line_table
->Rows
[idx
];
1237 LineTable::AppendLineEntryToSequence(
1238 sequence
.get(), row
.Address
.Address
, row
.Line
, row
.Column
, row
.File
,
1239 row
.IsStmt
, row
.BasicBlock
, row
.PrologueEnd
, row
.EpilogueBegin
,
1242 sequences
.push_back(std::move(sequence
));
1245 std::unique_ptr
<LineTable
> line_table_up
=
1246 std::make_unique
<LineTable
>(&comp_unit
, std::move(sequences
));
1248 if (SymbolFileDWARFDebugMap
*debug_map_symfile
= GetDebugMapSymfile()) {
1249 // We have an object file that has a line table with addresses that are not
1250 // linked. We need to link the line table and convert the addresses that
1251 // are relative to the .o file into addresses for the main executable.
1252 comp_unit
.SetLineTable(
1253 debug_map_symfile
->LinkOSOLineTable(this, line_table_up
.get()));
1255 comp_unit
.SetLineTable(line_table_up
.release());
1261 lldb_private::DebugMacrosSP
1262 SymbolFileDWARF::ParseDebugMacros(lldb::offset_t
*offset
) {
1263 auto iter
= m_debug_macros_map
.find(*offset
);
1264 if (iter
!= m_debug_macros_map
.end())
1265 return iter
->second
;
1267 ElapsedTime
elapsed(m_parse_time
);
1268 const DWARFDataExtractor
&debug_macro_data
= m_context
.getOrLoadMacroData();
1269 if (debug_macro_data
.GetByteSize() == 0)
1270 return DebugMacrosSP();
1272 lldb_private::DebugMacrosSP
debug_macros_sp(new lldb_private::DebugMacros());
1273 m_debug_macros_map
[*offset
] = debug_macros_sp
;
1275 const DWARFDebugMacroHeader
&header
=
1276 DWARFDebugMacroHeader::ParseHeader(debug_macro_data
, offset
);
1277 DWARFDebugMacroEntry::ReadMacroEntries(
1278 debug_macro_data
, m_context
.getOrLoadStrData(), header
.OffsetIs64Bit(),
1279 offset
, this, debug_macros_sp
);
1281 return debug_macros_sp
;
1284 bool SymbolFileDWARF::ParseDebugMacros(CompileUnit
&comp_unit
) {
1285 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
1287 DWARFUnit
*dwarf_cu
= GetDWARFCompileUnit(&comp_unit
);
1288 if (dwarf_cu
== nullptr)
1291 const DWARFBaseDIE dwarf_cu_die
= dwarf_cu
->GetUnitDIEOnly();
1295 lldb::offset_t sect_offset
=
1296 dwarf_cu_die
.GetAttributeValueAsUnsigned(DW_AT_macros
, DW_INVALID_OFFSET
);
1297 if (sect_offset
== DW_INVALID_OFFSET
)
1298 sect_offset
= dwarf_cu_die
.GetAttributeValueAsUnsigned(DW_AT_GNU_macros
,
1300 if (sect_offset
== DW_INVALID_OFFSET
)
1303 comp_unit
.SetDebugMacros(ParseDebugMacros(§_offset
));
1308 size_t SymbolFileDWARF::ParseBlocksRecursive(
1309 lldb_private::CompileUnit
&comp_unit
, Block
*parent_block
,
1310 const DWARFDIE
&orig_die
, addr_t subprogram_low_pc
, uint32_t depth
) {
1311 size_t blocks_added
= 0;
1312 DWARFDIE die
= orig_die
;
1314 dw_tag_t tag
= die
.Tag();
1317 case DW_TAG_inlined_subroutine
:
1318 case DW_TAG_subprogram
:
1319 case DW_TAG_lexical_block
: {
1320 Block
*block
= nullptr;
1321 if (tag
== DW_TAG_subprogram
) {
1322 // Skip any DW_TAG_subprogram DIEs that are inside of a normal or
1323 // inlined functions. These will be parsed on their own as separate
1329 block
= parent_block
;
1331 BlockSP
block_sp(new Block(die
.GetID()));
1332 parent_block
->AddChild(block_sp
);
1333 block
= block_sp
.get();
1335 DWARFRangeList ranges
;
1336 const char *name
= nullptr;
1337 const char *mangled_name
= nullptr;
1339 std::optional
<int> decl_file
;
1340 std::optional
<int> decl_line
;
1341 std::optional
<int> decl_column
;
1342 std::optional
<int> call_file
;
1343 std::optional
<int> call_line
;
1344 std::optional
<int> call_column
;
1345 if (die
.GetDIENamesAndRanges(name
, mangled_name
, ranges
, decl_file
,
1346 decl_line
, decl_column
, call_file
, call_line
,
1347 call_column
, nullptr)) {
1348 if (tag
== DW_TAG_subprogram
) {
1349 assert(subprogram_low_pc
== LLDB_INVALID_ADDRESS
);
1350 subprogram_low_pc
= ranges
.GetMinRangeBase(0);
1351 } else if (tag
== DW_TAG_inlined_subroutine
) {
1352 // We get called here for inlined subroutines in two ways. The first
1353 // time is when we are making the Function object for this inlined
1354 // concrete instance. Since we're creating a top level block at
1355 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we
1356 // need to adjust the containing address. The second time is when we
1357 // are parsing the blocks inside the function that contains the
1358 // inlined concrete instance. Since these will be blocks inside the
1359 // containing "real" function the offset will be for that function.
1360 if (subprogram_low_pc
== LLDB_INVALID_ADDRESS
) {
1361 subprogram_low_pc
= ranges
.GetMinRangeBase(0);
1365 const size_t num_ranges
= ranges
.GetSize();
1366 for (size_t i
= 0; i
< num_ranges
; ++i
) {
1367 const DWARFRangeList::Entry
&range
= ranges
.GetEntryRef(i
);
1368 const addr_t range_base
= range
.GetRangeBase();
1369 if (range_base
>= subprogram_low_pc
)
1370 block
->AddRange(Block::Range(range_base
- subprogram_low_pc
,
1371 range
.GetByteSize()));
1373 GetObjectFile()->GetModule()->ReportError(
1374 "{0:x8}: adding range [{1:x16}-{2:x16}) which has a base "
1375 "that is less than the function's low PC {3:x16}. Please file "
1376 "a bug and attach the file at the "
1377 "start of this error message",
1378 block
->GetID(), range_base
, range
.GetRangeEnd(),
1382 block
->FinalizeRanges();
1384 if (tag
!= DW_TAG_subprogram
&&
1385 (name
!= nullptr || mangled_name
!= nullptr)) {
1386 std::unique_ptr
<Declaration
> decl_up
;
1387 if (decl_file
|| decl_line
|| decl_column
)
1388 decl_up
= std::make_unique
<Declaration
>(
1389 comp_unit
.GetSupportFiles().GetFileSpecAtIndex(
1390 decl_file
? *decl_file
: 0),
1391 decl_line
? *decl_line
: 0, decl_column
? *decl_column
: 0);
1393 std::unique_ptr
<Declaration
> call_up
;
1394 if (call_file
|| call_line
|| call_column
)
1395 call_up
= std::make_unique
<Declaration
>(
1396 comp_unit
.GetSupportFiles().GetFileSpecAtIndex(
1397 call_file
? *call_file
: 0),
1398 call_line
? *call_line
: 0, call_column
? *call_column
: 0);
1400 block
->SetInlinedFunctionInfo(name
, mangled_name
, decl_up
.get(),
1406 if (die
.HasChildren()) {
1408 ParseBlocksRecursive(comp_unit
, block
, die
.GetFirstChild(),
1409 subprogram_low_pc
, depth
+ 1);
1417 // Only parse siblings of the block if we are not at depth zero. A depth of
1418 // zero indicates we are currently parsing the top level DW_TAG_subprogram
1424 die
= die
.GetSibling();
1426 return blocks_added
;
1429 bool SymbolFileDWARF::ClassOrStructIsVirtual(const DWARFDIE
&parent_die
) {
1431 for (DWARFDIE die
: parent_die
.children()) {
1432 dw_tag_t tag
= die
.Tag();
1433 bool check_virtuality
= false;
1435 case DW_TAG_inheritance
:
1436 case DW_TAG_subprogram
:
1437 check_virtuality
= true;
1442 if (check_virtuality
) {
1443 if (die
.GetAttributeValueAsUnsigned(DW_AT_virtuality
, 0) != 0)
1451 void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx
) {
1452 auto *type_system
= decl_ctx
.GetTypeSystem();
1453 if (type_system
!= nullptr)
1454 type_system
->GetDWARFParser()->EnsureAllDIEsInDeclContextHaveBeenParsed(
1459 SymbolFileDWARF::GetDIE(lldb::user_id_t uid
) { return GetDIE(DIERef(uid
)); }
1461 CompilerDecl
SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid
) {
1462 // This method can be called without going through the symbol vendor so we
1463 // need to lock the module.
1464 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
1465 // Anytime we have a lldb::user_id_t, we must get the DIE by calling
1466 // SymbolFileDWARF::GetDIE(). See comments inside the
1467 // SymbolFileDWARF::GetDIE() for details.
1468 if (DWARFDIE die
= GetDIE(type_uid
))
1469 return GetDecl(die
);
1470 return CompilerDecl();
1474 SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid
) {
1475 // This method can be called without going through the symbol vendor so we
1476 // need to lock the module.
1477 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
1478 // Anytime we have a lldb::user_id_t, we must get the DIE by calling
1479 // SymbolFileDWARF::GetDIE(). See comments inside the
1480 // SymbolFileDWARF::GetDIE() for details.
1481 if (DWARFDIE die
= GetDIE(type_uid
))
1482 return GetDeclContext(die
);
1483 return CompilerDeclContext();
1487 SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid
) {
1488 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
1489 // Anytime we have a lldb::user_id_t, we must get the DIE by calling
1490 // SymbolFileDWARF::GetDIE(). See comments inside the
1491 // SymbolFileDWARF::GetDIE() for details.
1492 if (DWARFDIE die
= GetDIE(type_uid
))
1493 return GetContainingDeclContext(die
);
1494 return CompilerDeclContext();
1497 std::vector
<CompilerContext
>
1498 SymbolFileDWARF::GetCompilerContextForUID(lldb::user_id_t type_uid
) {
1499 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
1500 // Anytime we have a lldb::user_id_t, we must get the DIE by calling
1501 // SymbolFileDWARF::GetDIE(). See comments inside the
1502 // SymbolFileDWARF::GetDIE() for details.
1503 if (DWARFDIE die
= GetDIE(type_uid
))
1504 return die
.GetDeclContext();
1508 Type
*SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid
) {
1509 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
1510 // Anytime we have a lldb::user_id_t, we must get the DIE by calling
1511 // SymbolFileDWARF::GetDIE(). See comments inside the
1512 // SymbolFileDWARF::GetDIE() for details.
1513 if (DWARFDIE type_die
= GetDIE(type_uid
))
1514 return type_die
.ResolveType();
1519 std::optional
<SymbolFile::ArrayInfo
> SymbolFileDWARF::GetDynamicArrayInfoForUID(
1520 lldb::user_id_t type_uid
, const lldb_private::ExecutionContext
*exe_ctx
) {
1521 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
1522 if (DWARFDIE type_die
= GetDIE(type_uid
))
1523 return DWARFASTParser::ParseChildArrayInfo(type_die
, exe_ctx
);
1525 return std::nullopt
;
1528 Type
*SymbolFileDWARF::ResolveTypeUID(const DIERef
&die_ref
) {
1529 return ResolveType(GetDIE(die_ref
), true);
1532 Type
*SymbolFileDWARF::ResolveTypeUID(const DWARFDIE
&die
,
1533 bool assert_not_being_parsed
) {
1535 Log
*log
= GetLog(DWARFLog::DebugInfo
);
1537 GetObjectFile()->GetModule()->LogMessage(
1539 "SymbolFileDWARF::ResolveTypeUID (die = {0:x16}) {1} ({2}) '{3}'",
1540 die
.GetOffset(), DW_TAG_value_to_name(die
.Tag()), die
.Tag(),
1543 // We might be coming in in the middle of a type tree (a class within a
1544 // class, an enum within a class), so parse any needed parent DIEs before
1545 // we get to this one...
1546 DWARFDIE decl_ctx_die
= GetDeclContextDIEContainingDIE(die
);
1549 switch (decl_ctx_die
.Tag()) {
1550 case DW_TAG_structure_type
:
1551 case DW_TAG_union_type
:
1552 case DW_TAG_class_type
: {
1553 // Get the type, which could be a forward declaration
1555 GetObjectFile()->GetModule()->LogMessage(
1557 "SymbolFileDWARF::ResolveTypeUID (die = {0:x16}) {1} ({2}) "
1558 "'{3}' resolve parent forward type for {4:x16})",
1559 die
.GetOffset(), DW_TAG_value_to_name(die
.Tag()), die
.Tag(),
1560 die
.GetName(), decl_ctx_die
.GetOffset());
1568 return ResolveType(die
);
1573 // This function is used when SymbolFileDWARFDebugMap owns a bunch of
1574 // SymbolFileDWARF objects to detect if this DWARF file is the one that can
1575 // resolve a compiler_type.
1576 bool SymbolFileDWARF::HasForwardDeclForCompilerType(
1577 const CompilerType
&compiler_type
) {
1578 CompilerType compiler_type_no_qualifiers
=
1579 ClangUtil::RemoveFastQualifiers(compiler_type
);
1580 if (GetForwardDeclCompilerTypeToDIE().count(
1581 compiler_type_no_qualifiers
.GetOpaqueQualType())) {
1584 auto type_system
= compiler_type
.GetTypeSystem();
1585 auto clang_type_system
= type_system
.dyn_cast_or_null
<TypeSystemClang
>();
1586 if (!clang_type_system
)
1588 DWARFASTParserClang
*ast_parser
=
1589 static_cast<DWARFASTParserClang
*>(clang_type_system
->GetDWARFParser());
1590 return ast_parser
->GetClangASTImporter().CanImport(compiler_type
);
1593 bool SymbolFileDWARF::CompleteType(CompilerType
&compiler_type
) {
1594 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
1595 auto clang_type_system
=
1596 compiler_type
.GetTypeSystem().dyn_cast_or_null
<TypeSystemClang
>();
1597 if (clang_type_system
) {
1598 DWARFASTParserClang
*ast_parser
=
1599 static_cast<DWARFASTParserClang
*>(clang_type_system
->GetDWARFParser());
1601 ast_parser
->GetClangASTImporter().CanImport(compiler_type
))
1602 return ast_parser
->GetClangASTImporter().CompleteType(compiler_type
);
1605 // We have a struct/union/class/enum that needs to be fully resolved.
1606 CompilerType compiler_type_no_qualifiers
=
1607 ClangUtil::RemoveFastQualifiers(compiler_type
);
1608 auto die_it
= GetForwardDeclCompilerTypeToDIE().find(
1609 compiler_type_no_qualifiers
.GetOpaqueQualType());
1610 if (die_it
== GetForwardDeclCompilerTypeToDIE().end()) {
1611 // We have already resolved this type...
1615 DWARFDIE decl_die
= GetDIE(die_it
->getSecond());
1616 // Once we start resolving this type, remove it from the forward
1617 // declaration map in case anyone's child members or other types require this
1618 // type to get resolved.
1619 GetForwardDeclCompilerTypeToDIE().erase(die_it
);
1620 DWARFDIE def_die
= FindDefinitionDIE(decl_die
);
1622 SymbolFileDWARFDebugMap
*debug_map_symfile
= GetDebugMapSymfile();
1623 if (debug_map_symfile
) {
1624 // We weren't able to find a full declaration in this DWARF, see
1625 // if we have a declaration anywhere else...
1626 def_die
= debug_map_symfile
->FindDefinitionDIE(decl_die
);
1630 // If we don't have definition DIE, CompleteTypeFromDWARF will forcefully
1631 // complete this type.
1635 DWARFASTParser
*dwarf_ast
= GetDWARFParser(*def_die
.GetCU());
1638 Type
*type
= GetDIEToType().lookup(decl_die
.GetDIE());
1639 if (decl_die
!= def_die
) {
1640 GetDIEToType()[def_die
.GetDIE()] = type
;
1641 DWARFASTParserClang
*ast_parser
=
1642 static_cast<DWARFASTParserClang
*>(dwarf_ast
);
1643 ast_parser
->MapDeclDIEToDefDIE(decl_die
, def_die
);
1646 Log
*log
= GetLog(DWARFLog::DebugInfo
| DWARFLog::TypeCompletion
);
1648 GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
1649 log
, "{0:x8}: {1} ({2}) '{3}' resolving forward declaration...",
1650 def_die
.GetID(), DW_TAG_value_to_name(def_die
.Tag()), def_die
.Tag(),
1651 type
->GetName().AsCString());
1652 assert(compiler_type
);
1653 return dwarf_ast
->CompleteTypeFromDWARF(def_die
, type
, compiler_type
);
1656 Type
*SymbolFileDWARF::ResolveType(const DWARFDIE
&die
,
1657 bool assert_not_being_parsed
,
1658 bool resolve_function_context
) {
1660 Type
*type
= GetTypeForDIE(die
, resolve_function_context
).get();
1662 if (assert_not_being_parsed
) {
1663 if (type
!= DIE_IS_BEING_PARSED
)
1666 GetObjectFile()->GetModule()->ReportError(
1667 "Parsing a die that is being parsed die: {0:x16}: {1} ({2}) {3}",
1668 die
.GetOffset(), DW_TAG_value_to_name(die
.Tag()), die
.Tag(),
1678 SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit
&dwarf_cu
) {
1680 if (dwarf_cu
.IsDWOUnit()) {
1681 DWARFCompileUnit
*non_dwo_cu
= dwarf_cu
.GetSkeletonUnit();
1683 return non_dwo_cu
->GetSymbolFileDWARF().GetCompUnitForDWARFCompUnit(
1686 // Check if the symbol vendor already knows about this compile unit?
1687 CompileUnit
*lldb_cu
= dwarf_cu
.GetLLDBCompUnit();
1690 // The symbol vendor doesn't know about this compile unit, we need to parse
1691 // and add it to the symbol vendor object.
1692 return ParseCompileUnit(dwarf_cu
).get();
1695 void SymbolFileDWARF::GetObjCMethods(
1696 ConstString class_name
, llvm::function_ref
<bool(DWARFDIE die
)> callback
) {
1697 m_index
->GetObjCMethods(class_name
, callback
);
1700 bool SymbolFileDWARF::GetFunction(const DWARFDIE
&die
, SymbolContext
&sc
) {
1703 if (die
&& llvm::isa
<DWARFCompileUnit
>(die
.GetCU())) {
1704 // Check if the symbol vendor already knows about this compile unit?
1706 GetCompUnitForDWARFCompUnit(llvm::cast
<DWARFCompileUnit
>(*die
.GetCU()));
1708 sc
.function
= sc
.comp_unit
->FindFunctionByUID(die
.GetID()).get();
1709 if (sc
.function
== nullptr)
1710 sc
.function
= ParseFunction(*sc
.comp_unit
, die
);
1713 sc
.module_sp
= sc
.function
->CalculateSymbolContextModule();
1721 lldb::ModuleSP
SymbolFileDWARF::GetExternalModule(ConstString name
) {
1722 UpdateExternalModuleListIfNeeded();
1723 const auto &pos
= m_external_type_modules
.find(name
);
1724 if (pos
== m_external_type_modules
.end())
1725 return lldb::ModuleSP();
1729 SymbolFileDWARF
*SymbolFileDWARF::GetDIERefSymbolFile(const DIERef
&die_ref
) {
1730 // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we
1731 // must make sure we use the correct DWARF file when resolving things. On
1732 // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
1733 // SymbolFileDWARF classes, one for each .o file. We can often end up with
1734 // references to other DWARF objects and we must be ready to receive a
1735 // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
1738 std::optional
<uint32_t> file_index
= die_ref
.file_index();
1740 // If the file index matches, then we have the right SymbolFileDWARF already.
1741 // This will work for both .dwo file and DWARF in .o files for mac. Also if
1742 // both the file indexes are invalid, then we have a match.
1743 if (GetFileIndex() == file_index
)
1747 // We have a SymbolFileDWARFDebugMap, so let it find the right file
1748 if (SymbolFileDWARFDebugMap
*debug_map
= GetDebugMapSymfile())
1749 return debug_map
->GetSymbolFileByOSOIndex(*file_index
);
1751 // Handle the .dwp file case correctly
1752 if (*file_index
== DIERef::k_file_index_mask
)
1753 return GetDwpSymbolFile().get(); // DWP case
1755 // Handle the .dwo file case correctly
1756 return DebugInfo().GetUnitAtIndex(*die_ref
.file_index())
1757 ->GetDwoSymbolFile(); // DWO case
1763 SymbolFileDWARF::GetDIE(const DIERef
&die_ref
) {
1764 if (die_ref
.die_offset() == DW_INVALID_OFFSET
)
1767 // This method can be called without going through the symbol vendor so we
1768 // need to lock the module.
1769 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
1770 SymbolFileDWARF
*symbol_file
= GetDIERefSymbolFile(die_ref
);
1772 return symbol_file
->DebugInfo().GetDIE(die_ref
.section(),
1773 die_ref
.die_offset());
1777 /// Return the DW_AT_(GNU_)dwo_id.
1778 static std::optional
<uint64_t> GetDWOId(DWARFCompileUnit
&dwarf_cu
,
1779 const DWARFDebugInfoEntry
&cu_die
) {
1780 std::optional
<uint64_t> dwo_id
=
1781 cu_die
.GetAttributeValueAsOptionalUnsigned(&dwarf_cu
, DW_AT_GNU_dwo_id
);
1784 return cu_die
.GetAttributeValueAsOptionalUnsigned(&dwarf_cu
, DW_AT_dwo_id
);
1787 std::optional
<uint64_t> SymbolFileDWARF::GetDWOId() {
1788 if (GetNumCompileUnits() == 1) {
1789 if (auto comp_unit
= GetCompileUnitAtIndex(0))
1790 if (DWARFCompileUnit
*cu
= GetDWARFCompileUnit(comp_unit
.get()))
1791 if (DWARFDebugInfoEntry
*cu_die
= cu
->DIE().GetDIE())
1792 return ::GetDWOId(*cu
, *cu_die
);
1797 DWARFUnit
*SymbolFileDWARF::GetSkeletonUnit(DWARFUnit
*dwo_unit
) {
1798 return DebugInfo().GetSkeletonUnit(dwo_unit
);
1801 std::shared_ptr
<SymbolFileDWARFDwo
>
1802 SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
1803 DWARFUnit
&unit
, const DWARFDebugInfoEntry
&cu_die
) {
1804 // If this is a Darwin-style debug map (non-.dSYM) symbol file,
1805 // never attempt to load ELF-style DWO files since the -gmodules
1806 // support uses the same DWO mechanism to specify full debug info
1807 // files for modules. This is handled in
1808 // UpdateExternalModuleListIfNeeded().
1809 if (GetDebugMapSymfile())
1812 DWARFCompileUnit
*dwarf_cu
= llvm::dyn_cast
<DWARFCompileUnit
>(&unit
);
1813 // Only compile units can be split into two parts and we should only
1814 // look for a DWO file if there is a valid DWO ID.
1815 if (!dwarf_cu
|| !dwarf_cu
->GetDWOId().has_value())
1818 const char *dwo_name
= GetDWOName(*dwarf_cu
, cu_die
);
1820 unit
.SetDwoError(Status::FromErrorStringWithFormatv(
1821 "missing DWO name in skeleton DIE {0:x16}", cu_die
.GetOffset()));
1825 if (std::shared_ptr
<SymbolFileDWARFDwo
> dwp_sp
= GetDwpSymbolFile())
1828 FileSpec
dwo_file(dwo_name
);
1829 FileSystem::Instance().Resolve(dwo_file
);
1832 const FileSpecList
&debug_file_search_paths
=
1833 Target::GetDefaultDebugFileSearchPaths();
1834 size_t num_search_paths
= debug_file_search_paths
.GetSize();
1836 // It's relative, e.g. "foo.dwo", but we just to happen to be right next to
1837 // it. Or it's absolute.
1838 found
= FileSystem::Instance().Exists(dwo_file
);
1840 const char *comp_dir
=
1841 cu_die
.GetAttributeValueAsString(dwarf_cu
, DW_AT_comp_dir
, nullptr);
1843 // It could be a relative path that also uses DW_AT_COMP_DIR.
1845 dwo_file
.SetFile(comp_dir
, FileSpec::Style::native
);
1846 if (!dwo_file
.IsRelative()) {
1847 FileSystem::Instance().Resolve(dwo_file
);
1848 dwo_file
.AppendPathComponent(dwo_name
);
1849 found
= FileSystem::Instance().Exists(dwo_file
);
1851 FileSpecList dwo_paths
;
1853 // if DW_AT_comp_dir is relative, it should be relative to the location
1854 // of the executable, not to the location from which the debugger was
1856 FileSpec relative_to_binary
= dwo_file
;
1857 relative_to_binary
.PrependPathComponent(
1858 m_objfile_sp
->GetFileSpec().GetDirectory().GetStringRef());
1859 FileSystem::Instance().Resolve(relative_to_binary
);
1860 relative_to_binary
.AppendPathComponent(dwo_name
);
1861 dwo_paths
.Append(relative_to_binary
);
1863 // Or it's relative to one of the user specified debug directories.
1864 for (size_t idx
= 0; idx
< num_search_paths
; ++idx
) {
1865 FileSpec dirspec
= debug_file_search_paths
.GetFileSpecAtIndex(idx
);
1866 dirspec
.AppendPathComponent(comp_dir
);
1867 FileSystem::Instance().Resolve(dirspec
);
1868 if (!FileSystem::Instance().IsDirectory(dirspec
))
1871 dirspec
.AppendPathComponent(dwo_name
);
1872 dwo_paths
.Append(dirspec
);
1875 size_t num_possible
= dwo_paths
.GetSize();
1876 for (size_t idx
= 0; idx
< num_possible
&& !found
; ++idx
) {
1877 FileSpec dwo_spec
= dwo_paths
.GetFileSpecAtIndex(idx
);
1878 if (FileSystem::Instance().Exists(dwo_spec
)) {
1879 dwo_file
= dwo_spec
;
1885 Log
*log
= GetLog(LLDBLog::Symbols
);
1887 "unable to locate relative .dwo debug file \"%s\" for "
1888 "skeleton DIE 0x%016" PRIx64
" without valid DW_AT_comp_dir "
1890 dwo_name
, cu_die
.GetOffset());
1895 // Try adding the DW_AT_dwo_name ( e.g. "c/d/main-main.dwo"), and just the
1896 // filename ("main-main.dwo") to binary dir and search paths.
1897 FileSpecList dwo_paths
;
1898 FileSpec
dwo_name_spec(dwo_name
);
1899 llvm::StringRef filename_only
= dwo_name_spec
.GetFilename();
1901 FileSpec
binary_directory(
1902 m_objfile_sp
->GetFileSpec().GetDirectory().GetStringRef());
1903 FileSystem::Instance().Resolve(binary_directory
);
1905 if (dwo_name_spec
.IsRelative()) {
1906 FileSpec
dwo_name_binary_directory(binary_directory
);
1907 dwo_name_binary_directory
.AppendPathComponent(dwo_name
);
1908 dwo_paths
.Append(dwo_name_binary_directory
);
1911 FileSpec
filename_binary_directory(binary_directory
);
1912 filename_binary_directory
.AppendPathComponent(filename_only
);
1913 dwo_paths
.Append(filename_binary_directory
);
1915 for (size_t idx
= 0; idx
< num_search_paths
; ++idx
) {
1916 FileSpec dirspec
= debug_file_search_paths
.GetFileSpecAtIndex(idx
);
1917 FileSystem::Instance().Resolve(dirspec
);
1918 if (!FileSystem::Instance().IsDirectory(dirspec
))
1921 FileSpec
dwo_name_dirspec(dirspec
);
1922 dwo_name_dirspec
.AppendPathComponent(dwo_name
);
1923 dwo_paths
.Append(dwo_name_dirspec
);
1925 FileSpec
filename_dirspec(dirspec
);
1926 filename_dirspec
.AppendPathComponent(filename_only
);
1927 dwo_paths
.Append(filename_dirspec
);
1930 size_t num_possible
= dwo_paths
.GetSize();
1931 for (size_t idx
= 0; idx
< num_possible
&& !found
; ++idx
) {
1932 FileSpec dwo_spec
= dwo_paths
.GetFileSpecAtIndex(idx
);
1933 if (FileSystem::Instance().Exists(dwo_spec
)) {
1934 dwo_file
= dwo_spec
;
1941 FileSpec
error_dwo_path(dwo_name
);
1942 FileSystem::Instance().Resolve(error_dwo_path
);
1943 if (error_dwo_path
.IsRelative() && comp_dir
!= nullptr) {
1944 error_dwo_path
.PrependPathComponent(comp_dir
);
1945 FileSystem::Instance().Resolve(error_dwo_path
);
1947 unit
.SetDwoError(Status::FromErrorStringWithFormatv(
1948 "unable to locate .dwo debug file \"{0}\" for skeleton DIE "
1950 error_dwo_path
.GetPath().c_str(), cu_die
.GetOffset()));
1952 if (m_dwo_warning_issued
.test_and_set(std::memory_order_relaxed
) == false) {
1953 GetObjectFile()->GetModule()->ReportWarning(
1954 "unable to locate separate debug file (dwo, dwp). Debugging will be "
1960 const lldb::offset_t file_offset
= 0;
1961 DataBufferSP dwo_file_data_sp
;
1962 lldb::offset_t dwo_file_data_offset
= 0;
1963 ObjectFileSP dwo_obj_file
= ObjectFile::FindPlugin(
1964 GetObjectFile()->GetModule(), &dwo_file
, file_offset
,
1965 FileSystem::Instance().GetByteSize(dwo_file
), dwo_file_data_sp
,
1966 dwo_file_data_offset
);
1967 if (dwo_obj_file
== nullptr) {
1968 unit
.SetDwoError(Status::FromErrorStringWithFormatv(
1969 "unable to load object file for .dwo debug file \"{0}\" for "
1971 dwo_name
, cu_die
.GetOffset()));
1975 return std::make_shared
<SymbolFileDWARFDwo
>(*this, dwo_obj_file
,
1979 void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
1980 if (m_fetched_external_modules
)
1982 m_fetched_external_modules
= true;
1983 DWARFDebugInfo
&debug_info
= DebugInfo();
1985 // Follow DWO skeleton unit breadcrumbs.
1986 const uint32_t num_compile_units
= GetNumCompileUnits();
1987 for (uint32_t cu_idx
= 0; cu_idx
< num_compile_units
; ++cu_idx
) {
1989 llvm::dyn_cast
<DWARFCompileUnit
>(debug_info
.GetUnitAtIndex(cu_idx
));
1993 const DWARFBaseDIE die
= dwarf_cu
->GetUnitDIEOnly();
1994 if (!die
|| die
.HasChildren() || !die
.GetDIE())
1997 const char *name
= die
.GetAttributeValueAsString(DW_AT_name
, nullptr);
2001 ConstString
const_name(name
);
2002 ModuleSP
&module_sp
= m_external_type_modules
[const_name
];
2006 const char *dwo_path
= GetDWOName(*dwarf_cu
, *die
.GetDIE());
2010 ModuleSpec dwo_module_spec
;
2011 dwo_module_spec
.GetFileSpec().SetFile(dwo_path
, FileSpec::Style::native
);
2012 if (dwo_module_spec
.GetFileSpec().IsRelative()) {
2013 const char *comp_dir
=
2014 die
.GetAttributeValueAsString(DW_AT_comp_dir
, nullptr);
2016 dwo_module_spec
.GetFileSpec().SetFile(comp_dir
,
2017 FileSpec::Style::native
);
2018 FileSystem::Instance().Resolve(dwo_module_spec
.GetFileSpec());
2019 dwo_module_spec
.GetFileSpec().AppendPathComponent(dwo_path
);
2022 dwo_module_spec
.GetArchitecture() =
2023 m_objfile_sp
->GetModule()->GetArchitecture();
2025 // When LLDB loads "external" modules it looks at the presence of
2026 // DW_AT_dwo_name. However, when the already created module
2027 // (corresponding to .dwo itself) is being processed, it will see
2028 // the presence of DW_AT_dwo_name (which contains the name of dwo
2029 // file) and will try to call ModuleList::GetSharedModule
2030 // again. In some cases (i.e., for empty files) Clang 4.0
2031 // generates a *.dwo file which has DW_AT_dwo_name, but no
2032 // DW_AT_comp_dir. In this case the method
2033 // ModuleList::GetSharedModule will fail and the warning will be
2034 // printed. However, as one can notice in this case we don't
2035 // actually need to try to load the already loaded module
2036 // (corresponding to .dwo) so we simply skip it.
2037 if (m_objfile_sp
->GetFileSpec().GetFileNameExtension() == ".dwo" &&
2038 llvm::StringRef(m_objfile_sp
->GetFileSpec().GetPath())
2039 .ends_with(dwo_module_spec
.GetFileSpec().GetPath())) {
2043 Status error
= ModuleList::GetSharedModule(dwo_module_spec
, module_sp
,
2044 nullptr, nullptr, nullptr);
2046 // ReportWarning also rate-limits based on the warning string,
2047 // but in a -gmodules build, each object file has a similar DAG
2048 // of module dependencies that would all be listed here.
2049 GetObjectFile()->GetModule()->ReportWarning(
2050 "{0}", error
.AsCString("unknown error"));
2051 GetObjectFile()->GetModule()->ReportWarning(
2052 "Unable to locate module needed for external types.\n"
2053 "Debugging will be degraded due to missing types. Rebuilding the "
2054 "project will regenerate the needed module files.");
2058 // Verify the DWO hash.
2059 // FIXME: Technically "0" is a valid hash.
2060 std::optional
<uint64_t> dwo_id
= ::GetDWOId(*dwarf_cu
, *die
.GetDIE());
2065 llvm::dyn_cast_or_null
<SymbolFileDWARF
>(module_sp
->GetSymbolFile());
2068 std::optional
<uint64_t> dwo_dwo_id
= dwo_symfile
->GetDWOId();
2072 if (dwo_id
!= dwo_dwo_id
) {
2073 GetObjectFile()->GetModule()->ReportWarning(
2074 "Module {0} is out-of-date (hash mismatch).\n"
2075 "Type information from this module may be incomplete or inconsistent "
2076 "with the rest of the program. Rebuilding the project will "
2077 "regenerate the needed module files.",
2078 dwo_module_spec
.GetFileSpec().GetPath());
2083 SymbolFileDWARF::GlobalVariableMap
&SymbolFileDWARF::GetGlobalAranges() {
2084 if (!m_global_aranges_up
) {
2085 m_global_aranges_up
= std::make_unique
<GlobalVariableMap
>();
2087 ModuleSP module_sp
= GetObjectFile()->GetModule();
2089 const size_t num_cus
= module_sp
->GetNumCompileUnits();
2090 for (size_t i
= 0; i
< num_cus
; ++i
) {
2091 CompUnitSP cu_sp
= module_sp
->GetCompileUnitAtIndex(i
);
2093 VariableListSP globals_sp
= cu_sp
->GetVariableList(true);
2095 const size_t num_globals
= globals_sp
->GetSize();
2096 for (size_t g
= 0; g
< num_globals
; ++g
) {
2097 VariableSP var_sp
= globals_sp
->GetVariableAtIndex(g
);
2098 if (var_sp
&& !var_sp
->GetLocationIsConstantValueData()) {
2099 const DWARFExpressionList
&location
=
2100 var_sp
->LocationExpressionList();
2101 ExecutionContext exe_ctx
;
2102 llvm::Expected
<Value
> location_result
= location
.Evaluate(
2103 &exe_ctx
, nullptr, LLDB_INVALID_ADDRESS
, nullptr, nullptr);
2104 if (location_result
) {
2105 if (location_result
->GetValueType() ==
2106 Value::ValueType::FileAddress
) {
2107 lldb::addr_t file_addr
=
2108 location_result
->GetScalar().ULongLong();
2109 lldb::addr_t byte_size
= 1;
2110 if (var_sp
->GetType())
2112 var_sp
->GetType()->GetByteSize(nullptr).value_or(0);
2113 m_global_aranges_up
->Append(GlobalVariableMap::Entry(
2114 file_addr
, byte_size
, var_sp
.get()));
2117 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols
),
2118 location_result
.takeError(),
2119 "location expression failed to execute: {0}");
2127 m_global_aranges_up
->Sort();
2129 return *m_global_aranges_up
;
2132 void SymbolFileDWARF::ResolveFunctionAndBlock(lldb::addr_t file_vm_addr
,
2134 SymbolContext
&sc
) {
2135 assert(sc
.comp_unit
);
2136 DWARFCompileUnit
&cu
=
2137 GetDWARFCompileUnit(sc
.comp_unit
)->GetNonSkeletonUnit();
2138 DWARFDIE function_die
= cu
.LookupAddress(file_vm_addr
);
2141 sc
.function
= sc
.comp_unit
->FindFunctionByUID(function_die
.GetID()).get();
2142 if (sc
.function
== nullptr)
2143 sc
.function
= ParseFunction(*sc
.comp_unit
, function_die
);
2145 if (sc
.function
&& lookup_block
)
2146 block_die
= function_die
.LookupDeepestBlock(file_vm_addr
);
2149 if (!sc
.function
|| !lookup_block
)
2152 Block
&block
= sc
.function
->GetBlock(true);
2154 sc
.block
= block
.FindBlockByID(block_die
.GetID());
2156 sc
.block
= block
.FindBlockByID(function_die
.GetID());
2159 uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address
&so_addr
,
2160 SymbolContextItem resolve_scope
,
2161 SymbolContext
&sc
) {
2162 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
2163 LLDB_SCOPED_TIMERF("SymbolFileDWARF::"
2164 "ResolveSymbolContext (so_addr = { "
2165 "section = %p, offset = 0x%" PRIx64
2166 " }, resolve_scope = 0x%8.8x)",
2167 static_cast<void *>(so_addr
.GetSection().get()),
2168 so_addr
.GetOffset(), resolve_scope
);
2169 uint32_t resolved
= 0;
2171 (eSymbolContextCompUnit
| eSymbolContextFunction
| eSymbolContextBlock
|
2172 eSymbolContextLineEntry
| eSymbolContextVariable
)) {
2173 lldb::addr_t file_vm_addr
= so_addr
.GetFileAddress();
2175 DWARFDebugInfo
&debug_info
= DebugInfo();
2176 const DWARFDebugAranges
&aranges
= debug_info
.GetCompileUnitAranges();
2177 const dw_offset_t cu_offset
= aranges
.FindAddress(file_vm_addr
);
2178 if (cu_offset
== DW_INVALID_OFFSET
) {
2179 // Global variables are not in the compile unit address ranges. The only
2180 // way to currently find global variables is to iterate over the
2181 // .debug_pubnames or the __apple_names table and find all items in there
2182 // that point to DW_TAG_variable DIEs and then find the address that
2184 if (resolve_scope
& eSymbolContextVariable
) {
2185 GlobalVariableMap
&map
= GetGlobalAranges();
2186 const GlobalVariableMap::Entry
*entry
=
2187 map
.FindEntryThatContains(file_vm_addr
);
2188 if (entry
&& entry
->data
) {
2189 Variable
*variable
= entry
->data
;
2190 SymbolContextScope
*scc
= variable
->GetSymbolContextScope();
2192 scc
->CalculateSymbolContext(&sc
);
2193 sc
.variable
= variable
;
2195 return sc
.GetResolvedMask();
2199 uint32_t cu_idx
= DW_INVALID_INDEX
;
2200 if (auto *dwarf_cu
= llvm::dyn_cast_or_null
<DWARFCompileUnit
>(
2201 debug_info
.GetUnitAtOffset(DIERef::Section::DebugInfo
, cu_offset
,
2203 sc
.comp_unit
= GetCompUnitForDWARFCompUnit(*dwarf_cu
);
2205 resolved
|= eSymbolContextCompUnit
;
2207 bool force_check_line_table
= false;
2208 if (resolve_scope
& (eSymbolContextFunction
| eSymbolContextBlock
)) {
2209 ResolveFunctionAndBlock(file_vm_addr
,
2210 resolve_scope
& eSymbolContextBlock
, sc
);
2212 resolved
|= eSymbolContextFunction
;
2214 // We might have had a compile unit that had discontiguous address
2215 // ranges where the gaps are symbols that don't have any debug
2216 // info. Discontiguous compile unit address ranges should only
2217 // happen when there aren't other functions from other compile
2218 // units in these gaps. This helps keep the size of the aranges
2220 force_check_line_table
= true;
2223 resolved
|= eSymbolContextBlock
;
2226 if ((resolve_scope
& eSymbolContextLineEntry
) ||
2227 force_check_line_table
) {
2228 LineTable
*line_table
= sc
.comp_unit
->GetLineTable();
2229 if (line_table
!= nullptr) {
2230 // And address that makes it into this function should be in terms
2231 // of this debug file if there is no debug map, or it will be an
2232 // address in the .o file which needs to be fixed up to be in
2233 // terms of the debug map executable. Either way, calling
2234 // FixupAddress() will work for us.
2235 Address
exe_so_addr(so_addr
);
2236 if (FixupAddress(exe_so_addr
)) {
2237 if (line_table
->FindLineEntryByAddress(exe_so_addr
,
2239 resolved
|= eSymbolContextLineEntry
;
2245 if (force_check_line_table
&& !(resolved
& eSymbolContextLineEntry
)) {
2246 // We might have had a compile unit that had discontiguous address
2247 // ranges where the gaps are symbols that don't have any debug info.
2248 // Discontiguous compile unit address ranges should only happen when
2249 // there aren't other functions from other compile units in these
2250 // gaps. This helps keep the size of the aranges down.
2251 sc
.comp_unit
= nullptr;
2252 resolved
&= ~eSymbolContextCompUnit
;
2255 GetObjectFile()->GetModule()->ReportWarning(
2256 "{0:x16}: compile unit {1} failed to create a valid "
2257 "lldb_private::CompileUnit class.",
2266 uint32_t SymbolFileDWARF::ResolveSymbolContext(
2267 const SourceLocationSpec
&src_location_spec
,
2268 SymbolContextItem resolve_scope
, SymbolContextList
&sc_list
) {
2269 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
2270 const bool check_inlines
= src_location_spec
.GetCheckInlines();
2271 const uint32_t prev_size
= sc_list
.GetSize();
2272 if (resolve_scope
& eSymbolContextCompUnit
) {
2273 for (uint32_t cu_idx
= 0, num_cus
= GetNumCompileUnits(); cu_idx
< num_cus
;
2275 CompileUnit
*dc_cu
= ParseCompileUnitAtIndex(cu_idx
).get();
2279 bool file_spec_matches_cu_file_spec
= FileSpec::Match(
2280 src_location_spec
.GetFileSpec(), dc_cu
->GetPrimaryFile());
2281 if (check_inlines
|| file_spec_matches_cu_file_spec
) {
2282 dc_cu
->ResolveSymbolContext(src_location_spec
, resolve_scope
, sc_list
);
2288 return sc_list
.GetSize() - prev_size
;
2291 void SymbolFileDWARF::PreloadSymbols() {
2292 // Get the symbol table for the symbol file prior to taking the module lock
2293 // so that it is available without needing to take the module lock. The DWARF
2294 // indexing might end up needing to relocate items when DWARF sections are
2295 // loaded as they might end up getting the section contents which can call
2296 // ObjectFileELF::RelocateSection() which in turn will ask for the symbol
2297 // table and can cause deadlocks.
2299 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
2303 std::recursive_mutex
&SymbolFileDWARF::GetModuleMutex() const {
2304 lldb::ModuleSP
module_sp(m_debug_map_module_wp
.lock());
2306 return module_sp
->GetMutex();
2307 return GetObjectFile()->GetModule()->GetMutex();
2310 bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
2311 const lldb_private::CompilerDeclContext
&decl_ctx
) {
2312 if (!decl_ctx
.IsValid()) {
2313 // Invalid namespace decl which means we aren't matching only things in
2314 // this symbol file, so return true to indicate it matches this symbol
2319 TypeSystem
*decl_ctx_type_system
= decl_ctx
.GetTypeSystem();
2320 auto type_system_or_err
= GetTypeSystemForLanguage(
2321 decl_ctx_type_system
->GetMinimumLanguage(nullptr));
2322 if (auto err
= type_system_or_err
.takeError()) {
2323 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols
), std::move(err
),
2324 "Unable to match namespace decl using TypeSystem: {0}");
2328 if (decl_ctx_type_system
== type_system_or_err
->get())
2329 return true; // The type systems match, return true
2331 // The namespace AST was valid, and it does not match...
2332 Log
*log
= GetLog(DWARFLog::Lookups
);
2335 GetObjectFile()->GetModule()->LogMessage(
2336 log
, "Valid namespace does not match symbol file");
2341 void SymbolFileDWARF::FindGlobalVariables(
2342 ConstString name
, const CompilerDeclContext
&parent_decl_ctx
,
2343 uint32_t max_matches
, VariableList
&variables
) {
2344 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
2345 Log
*log
= GetLog(DWARFLog::Lookups
);
2348 GetObjectFile()->GetModule()->LogMessage(
2350 "SymbolFileDWARF::FindGlobalVariables (name=\"{0}\", "
2351 "parent_decl_ctx={1:p}, max_matches={2}, variables)",
2352 name
.GetCString(), static_cast<const void *>(&parent_decl_ctx
),
2355 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx
))
2358 // Remember how many variables are in the list before we search.
2359 const uint32_t original_size
= variables
.GetSize();
2361 llvm::StringRef basename
;
2362 llvm::StringRef context
;
2363 bool name_is_mangled
= Mangled::GetManglingScheme(name
.GetStringRef()) !=
2364 Mangled::eManglingSchemeNone
;
2366 if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name
.GetCString(),
2368 basename
= name
.GetStringRef();
2370 // Loop invariant: Variables up to this index have been checked for context
2372 uint32_t pruned_idx
= original_size
;
2375 m_index
->GetGlobalVariables(ConstString(basename
), [&](DWARFDIE die
) {
2377 sc
.module_sp
= m_objfile_sp
->GetModule();
2378 assert(sc
.module_sp
);
2380 if (die
.Tag() != DW_TAG_variable
&& die
.Tag() != DW_TAG_member
)
2383 auto *dwarf_cu
= llvm::dyn_cast
<DWARFCompileUnit
>(die
.GetCU());
2386 sc
.comp_unit
= GetCompUnitForDWARFCompUnit(*dwarf_cu
);
2388 if (parent_decl_ctx
) {
2389 if (DWARFASTParser
*dwarf_ast
= GetDWARFParser(*die
.GetCU())) {
2390 CompilerDeclContext actual_parent_decl_ctx
=
2391 dwarf_ast
->GetDeclContextContainingUIDFromDWARF(die
);
2393 /// If the actual namespace is inline (i.e., had a DW_AT_export_symbols)
2394 /// and a child (possibly through other layers of inline namespaces)
2395 /// of the namespace referred to by 'basename', allow the lookup to
2397 if (!actual_parent_decl_ctx
||
2398 (actual_parent_decl_ctx
!= parent_decl_ctx
&&
2399 !parent_decl_ctx
.IsContainedInLookup(actual_parent_decl_ctx
)))
2404 ParseAndAppendGlobalVariable(sc
, die
, variables
);
2405 while (pruned_idx
< variables
.GetSize()) {
2406 VariableSP var_sp
= variables
.GetVariableAtIndex(pruned_idx
);
2407 if (name_is_mangled
||
2408 var_sp
->GetName().GetStringRef().contains(name
.GetStringRef()))
2411 variables
.RemoveVariableAtIndex(pruned_idx
);
2414 return variables
.GetSize() - original_size
< max_matches
;
2417 // Return the number of variable that were appended to the list
2418 const uint32_t num_matches
= variables
.GetSize() - original_size
;
2419 if (log
&& num_matches
> 0) {
2420 GetObjectFile()->GetModule()->LogMessage(
2422 "SymbolFileDWARF::FindGlobalVariables (name=\"{0}\", "
2423 "parent_decl_ctx={1:p}, max_matches={2}, variables) => {3}",
2424 name
.GetCString(), static_cast<const void *>(&parent_decl_ctx
),
2425 max_matches
, num_matches
);
2429 void SymbolFileDWARF::FindGlobalVariables(const RegularExpression
®ex
,
2430 uint32_t max_matches
,
2431 VariableList
&variables
) {
2432 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
2433 Log
*log
= GetLog(DWARFLog::Lookups
);
2436 GetObjectFile()->GetModule()->LogMessage(
2438 "SymbolFileDWARF::FindGlobalVariables (regex=\"{0}\", "
2439 "max_matches={1}, variables)",
2440 regex
.GetText().str().c_str(), max_matches
);
2443 // Remember how many variables are in the list before we search.
2444 const uint32_t original_size
= variables
.GetSize();
2447 m_index
->GetGlobalVariables(regex
, [&](DWARFDIE die
) {
2449 sc
.module_sp
= m_objfile_sp
->GetModule();
2450 assert(sc
.module_sp
);
2452 DWARFCompileUnit
*dwarf_cu
= llvm::dyn_cast
<DWARFCompileUnit
>(die
.GetCU());
2455 sc
.comp_unit
= GetCompUnitForDWARFCompUnit(*dwarf_cu
);
2457 ParseAndAppendGlobalVariable(sc
, die
, variables
);
2459 return variables
.GetSize() - original_size
< max_matches
;
2463 bool SymbolFileDWARF::ResolveFunction(const DWARFDIE
&orig_die
,
2464 bool include_inlines
,
2465 SymbolContextList
&sc_list
) {
2471 // If we were passed a die that is not a function, just return false...
2472 if (!(orig_die
.Tag() == DW_TAG_subprogram
||
2473 (include_inlines
&& orig_die
.Tag() == DW_TAG_inlined_subroutine
)))
2476 DWARFDIE die
= orig_die
;
2477 DWARFDIE inlined_die
;
2478 if (die
.Tag() == DW_TAG_inlined_subroutine
) {
2482 die
= die
.GetParent();
2485 if (die
.Tag() == DW_TAG_subprogram
)
2491 assert(die
&& die
.Tag() == DW_TAG_subprogram
);
2492 if (GetFunction(die
, sc
)) {
2494 // Parse all blocks if needed
2496 Block
&function_block
= sc
.function
->GetBlock(true);
2497 sc
.block
= function_block
.FindBlockByID(inlined_die
.GetID());
2498 if (sc
.block
== nullptr)
2499 sc
.block
= function_block
.FindBlockByID(inlined_die
.GetOffset());
2500 if (sc
.block
== nullptr || !sc
.block
->GetStartAddress(addr
))
2504 addr
= sc
.function
->GetAddressRange().GetBaseAddress();
2514 bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext
&decl_ctx
,
2515 const DWARFDIE
&die
,
2516 bool only_root_namespaces
) {
2517 // If we have no parent decl context to match this DIE matches, and if the
2518 // parent decl context isn't valid, we aren't trying to look for any
2519 // particular decl context so any die matches.
2520 if (!decl_ctx
.IsValid()) {
2521 // ...But if we are only checking root decl contexts, confirm that the
2522 // 'die' is a top-level context.
2523 if (only_root_namespaces
)
2524 return die
.GetParent().Tag() == llvm::dwarf::DW_TAG_compile_unit
;
2530 if (DWARFASTParser
*dwarf_ast
= GetDWARFParser(*die
.GetCU())) {
2531 if (CompilerDeclContext actual_decl_ctx
=
2532 dwarf_ast
->GetDeclContextContainingUIDFromDWARF(die
))
2533 return decl_ctx
.IsContainedInLookup(actual_decl_ctx
);
2539 void SymbolFileDWARF::FindFunctions(const Module::LookupInfo
&lookup_info
,
2540 const CompilerDeclContext
&parent_decl_ctx
,
2541 bool include_inlines
,
2542 SymbolContextList
&sc_list
) {
2543 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
2544 ConstString name
= lookup_info
.GetLookupName();
2545 FunctionNameType name_type_mask
= lookup_info
.GetNameTypeMask();
2547 // eFunctionNameTypeAuto should be pre-resolved by a call to
2548 // Module::LookupInfo::LookupInfo()
2549 assert((name_type_mask
& eFunctionNameTypeAuto
) == 0);
2551 Log
*log
= GetLog(DWARFLog::Lookups
);
2554 GetObjectFile()->GetModule()->LogMessage(
2556 "SymbolFileDWARF::FindFunctions (name=\"{0}\", name_type_mask={1:x}, "
2558 name
.GetCString(), name_type_mask
);
2561 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx
))
2564 // If name is empty then we won't find anything.
2568 // Remember how many sc_list are in the list before we search in case we are
2569 // appending the results to a variable list.
2571 const uint32_t original_size
= sc_list
.GetSize();
2573 llvm::DenseSet
<const DWARFDebugInfoEntry
*> resolved_dies
;
2575 m_index
->GetFunctions(lookup_info
, *this, parent_decl_ctx
, [&](DWARFDIE die
) {
2576 if (resolved_dies
.insert(die
.GetDIE()).second
)
2577 ResolveFunction(die
, include_inlines
, sc_list
);
2580 // With -gsimple-template-names, a templated type's DW_AT_name will not
2581 // contain the template parameters. Try again stripping '<' and anything
2582 // after, filtering out entries with template parameters that don't match.
2584 const llvm::StringRef name_ref
= name
.GetStringRef();
2585 auto it
= name_ref
.find('<');
2586 if (it
!= llvm::StringRef::npos
) {
2587 const llvm::StringRef name_no_template_params
= name_ref
.slice(0, it
);
2589 Module::LookupInfo
no_tp_lookup_info(lookup_info
);
2590 no_tp_lookup_info
.SetLookupName(ConstString(name_no_template_params
));
2591 m_index
->GetFunctions(no_tp_lookup_info
, *this, parent_decl_ctx
,
2593 if (resolved_dies
.insert(die
.GetDIE()).second
)
2594 ResolveFunction(die
, include_inlines
, sc_list
);
2600 // Return the number of variable that were appended to the list
2601 const uint32_t num_matches
= sc_list
.GetSize() - original_size
;
2603 if (log
&& num_matches
> 0) {
2604 GetObjectFile()->GetModule()->LogMessage(
2606 "SymbolFileDWARF::FindFunctions (name=\"{0}\", "
2607 "name_type_mask={1:x}, include_inlines={2:d}, sc_list) => {3}",
2608 name
.GetCString(), name_type_mask
, include_inlines
, num_matches
);
2612 void SymbolFileDWARF::FindFunctions(const RegularExpression
®ex
,
2613 bool include_inlines
,
2614 SymbolContextList
&sc_list
) {
2615 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
2616 LLDB_SCOPED_TIMERF("SymbolFileDWARF::FindFunctions (regex = '%s')",
2617 regex
.GetText().str().c_str());
2619 Log
*log
= GetLog(DWARFLog::Lookups
);
2622 GetObjectFile()->GetModule()->LogMessage(
2623 log
, "SymbolFileDWARF::FindFunctions (regex=\"{0}\", sc_list)",
2624 regex
.GetText().str().c_str());
2627 llvm::DenseSet
<const DWARFDebugInfoEntry
*> resolved_dies
;
2628 m_index
->GetFunctions(regex
, [&](DWARFDIE die
) {
2629 if (resolved_dies
.insert(die
.GetDIE()).second
)
2630 ResolveFunction(die
, include_inlines
, sc_list
);
2635 void SymbolFileDWARF::GetMangledNamesForFunction(
2636 const std::string
&scope_qualified_name
,
2637 std::vector
<ConstString
> &mangled_names
) {
2638 DWARFDebugInfo
&info
= DebugInfo();
2639 uint32_t num_comp_units
= info
.GetNumUnits();
2640 for (uint32_t i
= 0; i
< num_comp_units
; i
++) {
2641 DWARFUnit
*cu
= info
.GetUnitAtIndex(i
);
2645 SymbolFileDWARFDwo
*dwo
= cu
->GetDwoSymbolFile();
2647 dwo
->GetMangledNamesForFunction(scope_qualified_name
, mangled_names
);
2650 for (DIERef die_ref
:
2651 m_function_scope_qualified_name_map
.lookup(scope_qualified_name
)) {
2652 DWARFDIE die
= GetDIE(die_ref
);
2653 mangled_names
.push_back(ConstString(die
.GetMangledName()));
2657 /// Split a name up into a basename and template parameters.
2658 static bool SplitTemplateParams(llvm::StringRef fullname
,
2659 llvm::StringRef
&basename
,
2660 llvm::StringRef
&template_params
) {
2661 auto it
= fullname
.find('<');
2662 if (it
== llvm::StringRef::npos
) {
2663 basename
= fullname
;
2664 template_params
= llvm::StringRef();
2667 basename
= fullname
.slice(0, it
);
2668 template_params
= fullname
.slice(it
, fullname
.size());
2672 static bool UpdateCompilerContextForSimpleTemplateNames(TypeQuery
&match
) {
2673 // We need to find any names in the context that have template parameters
2674 // and strip them so the context can be matched when -gsimple-template-names
2675 // is being used. Returns true if any of the context items were updated.
2676 bool any_context_updated
= false;
2677 for (auto &context
: match
.GetContextRef()) {
2678 llvm::StringRef basename
, params
;
2679 if (SplitTemplateParams(context
.name
.GetStringRef(), basename
, params
)) {
2680 context
.name
= ConstString(basename
);
2681 any_context_updated
= true;
2684 return any_context_updated
;
2687 uint64_t SymbolFileDWARF::GetDebugInfoSize(bool load_all_debug_info
) {
2688 DWARFDebugInfo
&info
= DebugInfo();
2689 uint32_t num_comp_units
= info
.GetNumUnits();
2691 uint64_t debug_info_size
= SymbolFileCommon::GetDebugInfoSize();
2692 // In dwp scenario, debug info == skeleton debug info + dwp debug info.
2693 if (std::shared_ptr
<SymbolFileDWARFDwo
> dwp_sp
= GetDwpSymbolFile())
2694 return debug_info_size
+ dwp_sp
->GetDebugInfoSize();
2696 // In dwo scenario, debug info == skeleton debug info + all dwo debug info.
2697 for (uint32_t i
= 0; i
< num_comp_units
; i
++) {
2698 DWARFUnit
*cu
= info
.GetUnitAtIndex(i
);
2702 SymbolFileDWARFDwo
*dwo
= cu
->GetDwoSymbolFile(load_all_debug_info
);
2704 debug_info_size
+= dwo
->GetDebugInfoSize();
2706 return debug_info_size
;
2709 void SymbolFileDWARF::FindTypes(const TypeQuery
&query
, TypeResults
&results
) {
2711 // Make sure we haven't already searched this SymbolFile before.
2712 if (results
.AlreadySearched(this))
2715 auto type_basename
= query
.GetTypeBasename();
2717 Log
*log
= GetLog(DWARFLog::Lookups
);
2719 GetObjectFile()->GetModule()->LogMessage(
2720 log
, "SymbolFileDWARF::FindTypes(type_basename=\"{0}\")",
2724 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
2726 TypeQuery
query_full(query
);
2727 bool have_index_match
= false;
2728 m_index
->GetTypesWithQuery(query_full
, [&](DWARFDIE die
) {
2729 // Check the language, but only if we have a language filter.
2730 if (query
.HasLanguage()) {
2731 if (!query
.LanguageMatches(GetLanguageFamily(*die
.GetCU())))
2732 return true; // Keep iterating over index types, language mismatch.
2735 // Since mangled names are unique, we only need to check if the names are
2737 if (query
.GetSearchByMangledName()) {
2738 if (die
.GetMangledName(/*substitute_name_allowed=*/false) !=
2739 query
.GetTypeBasename().GetStringRef())
2740 return true; // Keep iterating over index types, mangled name mismatch.
2741 if (Type
*matching_type
= ResolveType(die
, true, true)) {
2742 results
.InsertUnique(matching_type
->shared_from_this());
2743 return !results
.Done(query
); // Keep iterating if we aren't done.
2745 return true; // Keep iterating over index types, weren't able to resolve
2749 // Check the context matches
2750 std::vector
<lldb_private::CompilerContext
> die_context
;
2751 if (query
.GetModuleSearch())
2752 die_context
= die
.GetDeclContext();
2754 die_context
= die
.GetTypeLookupContext();
2755 assert(!die_context
.empty());
2756 if (!query
.ContextMatches(die_context
))
2757 return true; // Keep iterating over index types, context mismatch.
2759 // Try to resolve the type.
2760 if (Type
*matching_type
= ResolveType(die
, true, true)) {
2761 if (matching_type
->IsTemplateType()) {
2762 // We have to watch out for case where we lookup a type by basename and
2763 // it matches a template with simple template names. Like looking up
2764 // "Foo" and if we have simple template names then we will match
2765 // "Foo<int>" and "Foo<double>" because all the DWARF has is "Foo" in
2766 // the accelerator tables. The main case we see this in is when the
2767 // expression parser is trying to parse "Foo<int>" and it will first do
2768 // a lookup on just "Foo". We verify the type basename matches before
2769 // inserting the type in the results.
2770 auto CompilerTypeBasename
=
2771 matching_type
->GetForwardCompilerType().GetTypeName(true);
2772 if (CompilerTypeBasename
!= query
.GetTypeBasename())
2773 return true; // Keep iterating over index types, basename mismatch.
2775 have_index_match
= true;
2776 results
.InsertUnique(matching_type
->shared_from_this());
2778 return !results
.Done(query
); // Keep iterating if we aren't done.
2781 if (results
.Done(query
)) {
2783 GetObjectFile()->GetModule()->LogMessage(
2784 log
, "SymbolFileDWARF::FindTypes(type_basename=\"{0}\") => {1}",
2785 type_basename
, results
.GetTypeMap().GetSize());
2790 // With -gsimple-template-names, a templated type's DW_AT_name will not
2791 // contain the template parameters. Try again stripping '<' and anything
2792 // after, filtering out entries with template parameters that don't match.
2793 if (!have_index_match
) {
2794 // Create a type matcher with a compiler context that is tuned for
2795 // -gsimple-template-names. We will use this for the index lookup and the
2796 // context matching, but will use the original "match" to insert matches
2797 // into if things match. The "match_simple" has a compiler context with
2798 // all template parameters removed to allow the names and context to match.
2799 // The UpdateCompilerContextForSimpleTemplateNames(...) will return true if
2800 // it trims any context items down by removing template parameter names.
2801 TypeQuery
query_simple(query
);
2802 if (UpdateCompilerContextForSimpleTemplateNames(query_simple
)) {
2803 auto type_basename_simple
= query_simple
.GetTypeBasename();
2804 // Copy our match's context and update the basename we are looking for
2805 // so we can use this only to compare the context correctly.
2806 m_index
->GetTypesWithQuery(query_simple
, [&](DWARFDIE die
) {
2807 // Check the language, but only if we have a language filter.
2808 if (query
.HasLanguage()) {
2809 if (!query
.LanguageMatches(GetLanguageFamily(*die
.GetCU())))
2810 return true; // Keep iterating over index types, language mismatch.
2813 // Check the context matches
2814 std::vector
<lldb_private::CompilerContext
> die_context
;
2815 if (query
.GetModuleSearch())
2816 die_context
= die
.GetDeclContext();
2818 die_context
= die
.GetTypeLookupContext();
2819 assert(!die_context
.empty());
2820 if (!query_simple
.ContextMatches(die_context
))
2821 return true; // Keep iterating over index types, context mismatch.
2823 // Try to resolve the type.
2824 if (Type
*matching_type
= ResolveType(die
, true, true)) {
2825 ConstString name
= matching_type
->GetQualifiedName();
2826 // We have found a type that still might not match due to template
2827 // parameters. If we create a new TypeQuery that uses the new type's
2828 // fully qualified name, we can find out if this type matches at all
2829 // context levels. We can't use just the "match_simple" context
2830 // because all template parameters were stripped off. The fully
2831 // qualified name of the type will have the template parameters and
2832 // will allow us to make sure it matches correctly.
2833 TypeQuery
die_query(name
.GetStringRef(),
2834 TypeQueryOptions::e_exact_match
);
2835 if (!query
.ContextMatches(die_query
.GetContextRef()))
2836 return true; // Keep iterating over index types, context mismatch.
2838 results
.InsertUnique(matching_type
->shared_from_this());
2840 return !results
.Done(query
); // Keep iterating if we aren't done.
2842 if (results
.Done(query
)) {
2844 GetObjectFile()->GetModule()->LogMessage(
2846 "SymbolFileDWARF::FindTypes(type_basename=\"{0}\") => {1} "
2847 "(simplified as \"{2}\")",
2848 type_basename
, results
.GetTypeMap().GetSize(),
2849 type_basename_simple
);
2856 // Next search through the reachable Clang modules. This only applies for
2857 // DWARF objects compiled with -gmodules that haven't been processed by
2859 UpdateExternalModuleListIfNeeded();
2861 for (const auto &pair
: m_external_type_modules
) {
2862 if (ModuleSP external_module_sp
= pair
.second
) {
2863 external_module_sp
->FindTypes(query
, results
);
2864 if (results
.Done(query
)) {
2865 // We don't log the results here as they are already logged in the
2866 // nested FindTypes call
2874 SymbolFileDWARF::FindNamespace(ConstString name
,
2875 const CompilerDeclContext
&parent_decl_ctx
,
2876 bool only_root_namespaces
) {
2877 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
2878 Log
*log
= GetLog(DWARFLog::Lookups
);
2881 GetObjectFile()->GetModule()->LogMessage(
2882 log
, "SymbolFileDWARF::FindNamespace (sc, name=\"{0}\")",
2886 CompilerDeclContext namespace_decl_ctx
;
2888 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx
))
2889 return namespace_decl_ctx
;
2891 m_index
->GetNamespacesWithParents(name
, parent_decl_ctx
, [&](DWARFDIE die
) {
2892 if (!DIEInDeclContext(parent_decl_ctx
, die
, only_root_namespaces
))
2893 return true; // The containing decl contexts don't match
2895 DWARFASTParser
*dwarf_ast
= GetDWARFParser(*die
.GetCU());
2899 namespace_decl_ctx
= dwarf_ast
->GetDeclContextForUIDFromDWARF(die
);
2900 return !namespace_decl_ctx
.IsValid();
2903 if (log
&& namespace_decl_ctx
) {
2904 GetObjectFile()->GetModule()->LogMessage(
2906 "SymbolFileDWARF::FindNamespace (sc, name=\"{0}\") => "
2907 "CompilerDeclContext({1:p}/{2:p}) \"{3}\"",
2909 static_cast<const void *>(namespace_decl_ctx
.GetTypeSystem()),
2910 static_cast<const void *>(namespace_decl_ctx
.GetOpaqueDeclContext()),
2911 namespace_decl_ctx
.GetName().AsCString("<NULL>"));
2914 return namespace_decl_ctx
;
2917 TypeSP
SymbolFileDWARF::GetTypeForDIE(const DWARFDIE
&die
,
2918 bool resolve_function_context
) {
2921 Type
*type_ptr
= GetDIEToType().lookup(die
.GetDIE());
2922 if (type_ptr
== nullptr) {
2923 SymbolContextScope
*scope
;
2924 if (auto *dwarf_cu
= llvm::dyn_cast
<DWARFCompileUnit
>(die
.GetCU()))
2925 scope
= GetCompUnitForDWARFCompUnit(*dwarf_cu
);
2927 scope
= GetObjectFile()->GetModule().get();
2929 SymbolContext
sc(scope
);
2930 const DWARFDebugInfoEntry
*parent_die
= die
.GetParent().GetDIE();
2931 while (parent_die
!= nullptr) {
2932 if (parent_die
->Tag() == DW_TAG_subprogram
)
2934 parent_die
= parent_die
->GetParent();
2936 SymbolContext sc_backup
= sc
;
2937 if (resolve_function_context
&& parent_die
!= nullptr &&
2938 !GetFunction(DWARFDIE(die
.GetCU(), parent_die
), sc
))
2941 type_sp
= ParseType(sc
, die
, nullptr);
2942 } else if (type_ptr
!= DIE_IS_BEING_PARSED
) {
2943 // Get the original shared pointer for this type
2944 type_sp
= type_ptr
->shared_from_this();
2951 SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE
&orig_die
) {
2953 DWARFDIE die
= orig_die
;
2956 // If this is the original DIE that we are searching for a declaration
2957 // for, then don't look in the cache as we don't want our own decl
2958 // context to be our decl context...
2959 if (orig_die
!= die
) {
2960 switch (die
.Tag()) {
2961 case DW_TAG_compile_unit
:
2962 case DW_TAG_partial_unit
:
2963 case DW_TAG_namespace
:
2964 case DW_TAG_structure_type
:
2965 case DW_TAG_union_type
:
2966 case DW_TAG_class_type
:
2967 case DW_TAG_lexical_block
:
2968 case DW_TAG_subprogram
:
2970 case DW_TAG_inlined_subroutine
: {
2971 DWARFDIE abs_die
= die
.GetReferencedDIE(DW_AT_abstract_origin
);
2982 DWARFDIE spec_die
= die
.GetReferencedDIE(DW_AT_specification
);
2984 DWARFDIE decl_ctx_die
= GetDeclContextDIEContainingDIE(spec_die
);
2986 return decl_ctx_die
;
2989 DWARFDIE abs_die
= die
.GetReferencedDIE(DW_AT_abstract_origin
);
2991 DWARFDIE decl_ctx_die
= GetDeclContextDIEContainingDIE(abs_die
);
2993 return decl_ctx_die
;
2996 die
= die
.GetParent();
3002 Symbol
*SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name
) {
3003 Symbol
*objc_class_symbol
= nullptr;
3005 Symtab
*symtab
= m_objfile_sp
->GetSymtab();
3007 objc_class_symbol
= symtab
->FindFirstSymbolWithNameAndType(
3008 objc_class_name
, eSymbolTypeObjCClass
, Symtab::eDebugNo
,
3009 Symtab::eVisibilityAny
);
3012 return objc_class_symbol
;
3015 // Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If
3016 // they don't then we can end up looking through all class types for a complete
3017 // type and never find the full definition. We need to know if this attribute
3018 // is supported, so we determine this here and cache th result. We also need to
3019 // worry about the debug map
3021 // if we are doing darwin DWARF in .o file debugging.
3022 bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit
*cu
) {
3023 if (m_supports_DW_AT_APPLE_objc_complete_type
== eLazyBoolCalculate
) {
3024 m_supports_DW_AT_APPLE_objc_complete_type
= eLazyBoolNo
;
3025 if (cu
&& cu
->Supports_DW_AT_APPLE_objc_complete_type())
3026 m_supports_DW_AT_APPLE_objc_complete_type
= eLazyBoolYes
;
3028 DWARFDebugInfo
&debug_info
= DebugInfo();
3029 const uint32_t num_compile_units
= GetNumCompileUnits();
3030 for (uint32_t cu_idx
= 0; cu_idx
< num_compile_units
; ++cu_idx
) {
3031 DWARFUnit
*dwarf_cu
= debug_info
.GetUnitAtIndex(cu_idx
);
3032 if (dwarf_cu
!= cu
&&
3033 dwarf_cu
->Supports_DW_AT_APPLE_objc_complete_type()) {
3034 m_supports_DW_AT_APPLE_objc_complete_type
= eLazyBoolYes
;
3039 if (m_supports_DW_AT_APPLE_objc_complete_type
== eLazyBoolNo
&&
3040 GetDebugMapSymfile())
3041 return m_debug_map_symfile
->Supports_DW_AT_APPLE_objc_complete_type(this);
3043 return m_supports_DW_AT_APPLE_objc_complete_type
== eLazyBoolYes
;
3046 // This function can be used when a DIE is found that is a forward declaration
3047 // DIE and we want to try and find a type that has the complete definition.
3048 TypeSP
SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
3049 const DWARFDIE
&die
, ConstString type_name
, bool must_be_implementation
) {
3053 if (!type_name
|| (must_be_implementation
&& !GetObjCClassSymbol(type_name
)))
3056 m_index
->GetCompleteObjCClass(
3057 type_name
, must_be_implementation
, [&](DWARFDIE type_die
) {
3058 // Don't try and resolve the DIE we are looking for with the DIE
3060 if (type_die
== die
|| !IsStructOrClassTag(type_die
.Tag()))
3063 if (must_be_implementation
&&
3064 type_die
.Supports_DW_AT_APPLE_objc_complete_type()) {
3065 const bool try_resolving_type
= type_die
.GetAttributeValueAsUnsigned(
3066 DW_AT_APPLE_objc_complete_type
, 0);
3067 if (!try_resolving_type
)
3071 Type
*resolved_type
= ResolveType(type_die
, false, true);
3072 if (!resolved_type
|| resolved_type
== DIE_IS_BEING_PARSED
)
3076 "resolved 0x%8.8" PRIx64
" from %s to 0x%8.8" PRIx64
3077 " (cu 0x%8.8" PRIx64
")\n",
3079 m_objfile_sp
->GetFileSpec().GetFilename().AsCString("<Unknown>"),
3080 type_die
.GetID(), type_cu
->GetID());
3083 GetDIEToType()[die
.GetDIE()] = resolved_type
;
3084 type_sp
= resolved_type
->shared_from_this();
3091 SymbolFileDWARF::FindDefinitionDIE(const DWARFDIE
&die
) {
3092 const char *name
= die
.GetName();
3095 if (!die
.GetAttributeValueAsUnsigned(DW_AT_declaration
, 0))
3098 Progress
progress(llvm::formatv(
3099 "Searching definition DIE in {0}: '{1}'",
3100 GetObjectFile()->GetFileSpec().GetFilename().GetString(), name
));
3102 const dw_tag_t tag
= die
.Tag();
3104 Log
*log
= GetLog(DWARFLog::TypeCompletion
| DWARFLog::Lookups
);
3106 GetObjectFile()->GetModule()->LogMessage(
3108 "SymbolFileDWARF::FindDefinitionDIE(tag={0} "
3109 "({1}), name='{2}')",
3110 DW_TAG_value_to_name(tag
), tag
, name
);
3113 // Get the type system that we are looking to find a type for. We will
3114 // use this to ensure any matches we find are in a language that this
3115 // type system supports
3116 const LanguageType language
= GetLanguage(*die
.GetCU());
3117 TypeSystemSP type_system
= nullptr;
3118 if (language
!= eLanguageTypeUnknown
) {
3119 auto type_system_or_err
= GetTypeSystemForLanguage(language
);
3120 if (auto err
= type_system_or_err
.takeError()) {
3121 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols
), std::move(err
),
3122 "Cannot get TypeSystem for language {1}: {0}",
3123 Language::GetNameForLanguageType(language
));
3125 type_system
= *type_system_or_err
;
3129 // See comments below about -gsimple-template-names for why we attempt to
3130 // compute missing template parameter names.
3131 std::vector
<std::string
> template_params
;
3132 DWARFDeclContext die_dwarf_decl_ctx
;
3133 DWARFASTParser
*dwarf_ast
=
3134 type_system
? type_system
->GetDWARFParser() : nullptr;
3135 for (DWARFDIE ctx_die
= die
; ctx_die
&& !isUnitType(ctx_die
.Tag());
3136 ctx_die
= ctx_die
.GetParentDeclContextDIE()) {
3137 die_dwarf_decl_ctx
.AppendDeclContext(ctx_die
.Tag(), ctx_die
.GetName());
3138 template_params
.push_back(
3139 (ctx_die
.IsStructUnionOrClass() && dwarf_ast
)
3140 ? dwarf_ast
->GetDIEClassTemplateParams(ctx_die
)
3143 const bool any_template_params
= llvm::any_of(
3144 template_params
, [](llvm::StringRef p
) { return !p
.empty(); });
3146 auto die_matches
= [&](DWARFDIE type_die
) {
3147 // Resolve the type if both have the same tag or {class, struct} tags.
3148 const bool tag_matches
=
3149 type_die
.Tag() == tag
||
3150 (IsStructOrClassTag(type_die
.Tag()) && IsStructOrClassTag(tag
));
3153 if (any_template_params
) {
3155 for (DWARFDIE ctx_die
= type_die
; ctx_die
&& !isUnitType(ctx_die
.Tag()) &&
3156 pos
< template_params
.size();
3157 ctx_die
= ctx_die
.GetParentDeclContextDIE(), ++pos
) {
3158 if (template_params
[pos
].empty())
3160 if (template_params
[pos
] !=
3161 dwarf_ast
->GetDIEClassTemplateParams(ctx_die
))
3164 if (pos
!= template_params
.size())
3170 m_index
->GetFullyQualifiedType(die_dwarf_decl_ctx
, [&](DWARFDIE type_die
) {
3171 // Make sure type_die's language matches the type system we are
3172 // looking for. We don't want to find a "Foo" type from Java if we
3173 // are looking for a "Foo" type for C, C++, ObjC, or ObjC++.
3175 !type_system
->SupportsLanguage(GetLanguage(*type_die
.GetCU())))
3178 if (!die_matches(type_die
)) {
3180 GetObjectFile()->GetModule()->LogMessage(
3182 "SymbolFileDWARF::FindDefinitionDIE(tag={0} ({1}), "
3183 "name='{2}') ignoring die={3:x16} ({4})",
3184 DW_TAG_value_to_name(tag
), tag
, name
, type_die
.GetOffset(),
3185 type_die
.GetName());
3191 DWARFDeclContext type_dwarf_decl_ctx
= type_die
.GetDWARFDeclContext();
3192 GetObjectFile()->GetModule()->LogMessage(
3194 "SymbolFileDWARF::FindDefinitionTypeDIE(tag={0} ({1}), name='{2}') "
3195 "trying die={3:x16} ({4})",
3196 DW_TAG_value_to_name(tag
), tag
, name
, type_die
.GetOffset(),
3197 type_dwarf_decl_ctx
.GetQualifiedName());
3206 TypeSP
SymbolFileDWARF::ParseType(const SymbolContext
&sc
, const DWARFDIE
&die
,
3207 bool *type_is_new_ptr
) {
3211 auto type_system_or_err
= GetTypeSystemForLanguage(GetLanguage(*die
.GetCU()));
3212 if (auto err
= type_system_or_err
.takeError()) {
3213 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols
), std::move(err
),
3214 "Unable to parse type: {0}");
3217 auto ts
= *type_system_or_err
;
3221 DWARFASTParser
*dwarf_ast
= ts
->GetDWARFParser();
3225 TypeSP type_sp
= dwarf_ast
->ParseTypeFromDWARF(sc
, die
, type_is_new_ptr
);
3227 if (die
.Tag() == DW_TAG_subprogram
) {
3228 std::string
scope_qualified_name(GetDeclContextForUID(die
.GetID())
3229 .GetScopeQualifiedName()
3231 if (scope_qualified_name
.size()) {
3232 m_function_scope_qualified_name_map
[scope_qualified_name
].insert(
3241 size_t SymbolFileDWARF::ParseTypes(const SymbolContext
&sc
,
3242 const DWARFDIE
&orig_die
,
3243 bool parse_siblings
, bool parse_children
) {
3244 size_t types_added
= 0;
3245 DWARFDIE die
= orig_die
;
3248 const dw_tag_t tag
= die
.Tag();
3249 bool type_is_new
= false;
3251 Tag dwarf_tag
= static_cast<Tag
>(tag
);
3253 // TODO: Currently ParseTypeFromDWARF(...) which is called by ParseType(...)
3254 // does not handle DW_TAG_subrange_type. It is not clear if this is a bug or
3256 if (isType(dwarf_tag
) && tag
!= DW_TAG_subrange_type
)
3257 ParseType(sc
, die
, &type_is_new
);
3262 if (parse_children
&& die
.HasChildren()) {
3263 if (die
.Tag() == DW_TAG_subprogram
) {
3264 SymbolContext
child_sc(sc
);
3265 child_sc
.function
= sc
.comp_unit
->FindFunctionByUID(die
.GetID()).get();
3266 types_added
+= ParseTypes(child_sc
, die
.GetFirstChild(), true, true);
3268 types_added
+= ParseTypes(sc
, die
.GetFirstChild(), true, true);
3272 die
= die
.GetSibling();
3279 size_t SymbolFileDWARF::ParseBlocksRecursive(Function
&func
) {
3280 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
3281 CompileUnit
*comp_unit
= func
.GetCompileUnit();
3282 lldbassert(comp_unit
);
3284 DWARFUnit
*dwarf_cu
= GetDWARFCompileUnit(comp_unit
);
3288 size_t functions_added
= 0;
3289 const dw_offset_t function_die_offset
= DIERef(func
.GetID()).die_offset();
3290 DWARFDIE function_die
=
3291 dwarf_cu
->GetNonSkeletonUnit().GetDIE(function_die_offset
);
3293 ParseBlocksRecursive(*comp_unit
, &func
.GetBlock(false), function_die
,
3294 LLDB_INVALID_ADDRESS
, 0);
3297 return functions_added
;
3300 size_t SymbolFileDWARF::ParseTypes(CompileUnit
&comp_unit
) {
3301 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
3302 size_t types_added
= 0;
3303 DWARFUnit
*dwarf_cu
= GetDWARFCompileUnit(&comp_unit
);
3305 DWARFDIE dwarf_cu_die
= dwarf_cu
->DIE();
3306 if (dwarf_cu_die
&& dwarf_cu_die
.HasChildren()) {
3308 sc
.comp_unit
= &comp_unit
;
3309 types_added
= ParseTypes(sc
, dwarf_cu_die
.GetFirstChild(), true, true);
3316 size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext
&sc
) {
3317 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
3318 if (sc
.comp_unit
!= nullptr) {
3320 DWARFDIE function_die
= GetDIE(sc
.function
->GetID());
3322 dw_addr_t func_lo_pc
= LLDB_INVALID_ADDRESS
;
3323 DWARFRangeList ranges
= function_die
.GetDIE()->GetAttributeAddressRanges(
3324 function_die
.GetCU(), /*check_hi_lo_pc=*/true);
3325 if (!ranges
.IsEmpty())
3326 func_lo_pc
= ranges
.GetMinRangeBase(0);
3327 if (func_lo_pc
!= LLDB_INVALID_ADDRESS
) {
3328 const size_t num_variables
=
3329 ParseVariablesInFunctionContext(sc
, function_die
, func_lo_pc
);
3331 // Let all blocks know they have parse all their variables
3332 sc
.function
->GetBlock(false).SetDidParseVariables(true, true);
3333 return num_variables
;
3335 } else if (sc
.comp_unit
) {
3336 DWARFUnit
*dwarf_cu
= DebugInfo().GetUnitAtIndex(sc
.comp_unit
->GetID());
3338 if (dwarf_cu
== nullptr)
3341 uint32_t vars_added
= 0;
3342 VariableListSP
variables(sc
.comp_unit
->GetVariableList(false));
3344 if (variables
.get() == nullptr) {
3345 variables
= std::make_shared
<VariableList
>();
3346 sc
.comp_unit
->SetVariableList(variables
);
3348 m_index
->GetGlobalVariables(*dwarf_cu
, [&](DWARFDIE die
) {
3349 VariableSP
var_sp(ParseVariableDIECached(sc
, die
));
3351 variables
->AddVariableIfUnique(var_sp
);
3363 VariableSP
SymbolFileDWARF::ParseVariableDIECached(const SymbolContext
&sc
,
3364 const DWARFDIE
&die
) {
3368 DIEToVariableSP
&die_to_variable
= die
.GetDWARF()->GetDIEToVariable();
3370 VariableSP var_sp
= die_to_variable
[die
.GetDIE()];
3374 var_sp
= ParseVariableDIE(sc
, die
, LLDB_INVALID_ADDRESS
);
3376 die_to_variable
[die
.GetDIE()] = var_sp
;
3377 if (DWARFDIE spec_die
= die
.GetReferencedDIE(DW_AT_specification
))
3378 die_to_variable
[spec_die
.GetDIE()] = var_sp
;
3383 /// Creates a DWARFExpressionList from an DW_AT_location form_value.
3384 static DWARFExpressionList
GetExprListFromAtLocation(DWARFFormValue form_value
,
3386 const DWARFDIE
&die
,
3387 const addr_t func_low_pc
) {
3388 if (DWARFFormValue::IsBlockForm(form_value
.Form())) {
3389 const DWARFDataExtractor
&data
= die
.GetData();
3391 uint64_t block_offset
= form_value
.BlockData() - data
.GetDataStart();
3392 uint64_t block_length
= form_value
.Unsigned();
3393 return DWARFExpressionList(
3394 module
, DataExtractor(data
, block_offset
, block_length
), die
.GetCU());
3397 DWARFExpressionList
location_list(module
, DWARFExpression(), die
.GetCU());
3398 DataExtractor data
= die
.GetCU()->GetLocationData();
3399 dw_offset_t offset
= form_value
.Unsigned();
3400 if (form_value
.Form() == DW_FORM_loclistx
)
3401 offset
= die
.GetCU()->GetLoclistOffset(offset
).value_or(-1);
3402 if (data
.ValidOffset(offset
)) {
3403 data
= DataExtractor(data
, offset
, data
.GetByteSize() - offset
);
3404 const DWARFUnit
*dwarf_cu
= form_value
.GetUnit();
3405 if (DWARFExpression::ParseDWARFLocationList(dwarf_cu
, data
, &location_list
))
3406 location_list
.SetFuncFileAddress(func_low_pc
);
3409 return location_list
;
3412 /// Creates a DWARFExpressionList from an DW_AT_const_value. This is either a
3413 /// block form, or a string, or a data form. For data forms, this returns an
3414 /// empty list, as we cannot initialize it properly without a SymbolFileType.
3415 static DWARFExpressionList
3416 GetExprListFromAtConstValue(DWARFFormValue form_value
, ModuleSP module
,
3417 const DWARFDIE
&die
) {
3418 const DWARFDataExtractor
&debug_info_data
= die
.GetData();
3419 if (DWARFFormValue::IsBlockForm(form_value
.Form())) {
3420 // Retrieve the value as a block expression.
3421 uint64_t block_offset
=
3422 form_value
.BlockData() - debug_info_data
.GetDataStart();
3423 uint64_t block_length
= form_value
.Unsigned();
3424 return DWARFExpressionList(
3425 module
, DataExtractor(debug_info_data
, block_offset
, block_length
),
3428 if (const char *str
= form_value
.AsCString())
3429 return DWARFExpressionList(module
,
3430 DataExtractor(str
, strlen(str
) + 1,
3431 die
.GetCU()->GetByteOrder(),
3432 die
.GetCU()->GetAddressByteSize()),
3434 return DWARFExpressionList(module
, DWARFExpression(), die
.GetCU());
3437 /// Global variables that are not initialized may have their address set to
3438 /// zero. Since multiple variables may have this address, we cannot apply the
3439 /// OSO relink address approach we normally use.
3440 /// However, the executable will have a matching symbol with a good address;
3441 /// this function attempts to find the correct address by looking into the
3442 /// executable's symbol table. If it succeeds, the expr_list is updated with
3443 /// the new address and the executable's symbol is returned.
3444 static Symbol
*fixupExternalAddrZeroVariable(
3445 SymbolFileDWARFDebugMap
&debug_map_symfile
, llvm::StringRef name
,
3446 DWARFExpressionList
&expr_list
, const DWARFDIE
&die
) {
3447 ObjectFile
*debug_map_objfile
= debug_map_symfile
.GetObjectFile();
3448 if (!debug_map_objfile
)
3451 Symtab
*debug_map_symtab
= debug_map_objfile
->GetSymtab();
3452 if (!debug_map_symtab
)
3454 Symbol
*exe_symbol
= debug_map_symtab
->FindFirstSymbolWithNameAndType(
3455 ConstString(name
), eSymbolTypeData
, Symtab::eDebugYes
,
3456 Symtab::eVisibilityExtern
);
3457 if (!exe_symbol
|| !exe_symbol
->ValueIsAddress())
3459 const addr_t exe_file_addr
= exe_symbol
->GetAddressRef().GetFileAddress();
3460 if (exe_file_addr
== LLDB_INVALID_ADDRESS
)
3463 DWARFExpression
*location
= expr_list
.GetMutableExpressionAtAddress();
3464 if (location
->Update_DW_OP_addr(die
.GetCU(), exe_file_addr
))
3469 VariableSP
SymbolFileDWARF::ParseVariableDIE(const SymbolContext
&sc
,
3470 const DWARFDIE
&die
,
3471 const lldb::addr_t func_low_pc
) {
3472 if (die
.GetDWARF() != this)
3473 return die
.GetDWARF()->ParseVariableDIE(sc
, die
, func_low_pc
);
3478 const dw_tag_t tag
= die
.Tag();
3479 ModuleSP module
= GetObjectFile()->GetModule();
3481 if (tag
!= DW_TAG_variable
&& tag
!= DW_TAG_constant
&&
3482 tag
!= DW_TAG_member
&& (tag
!= DW_TAG_formal_parameter
|| !sc
.function
))
3485 DWARFAttributes attributes
= die
.GetAttributes();
3486 const char *name
= nullptr;
3487 const char *mangled
= nullptr;
3489 DWARFFormValue type_die_form
;
3490 bool is_external
= false;
3491 bool is_artificial
= false;
3492 DWARFFormValue const_value_form
, location_form
;
3493 Variable::RangeList scope_ranges
;
3495 for (size_t i
= 0; i
< attributes
.Size(); ++i
) {
3496 dw_attr_t attr
= attributes
.AttributeAtIndex(i
);
3497 DWARFFormValue form_value
;
3499 if (!attributes
.ExtractFormValueAtIndex(i
, form_value
))
3502 case DW_AT_decl_file
:
3504 attributes
.CompileUnitAtIndex(i
)->GetFile(form_value
.Unsigned()));
3506 case DW_AT_decl_line
:
3507 decl
.SetLine(form_value
.Unsigned());
3509 case DW_AT_decl_column
:
3510 decl
.SetColumn(form_value
.Unsigned());
3513 name
= form_value
.AsCString();
3515 case DW_AT_linkage_name
:
3516 case DW_AT_MIPS_linkage_name
:
3517 mangled
= form_value
.AsCString();
3520 type_die_form
= form_value
;
3522 case DW_AT_external
:
3523 is_external
= form_value
.Boolean();
3525 case DW_AT_const_value
:
3526 const_value_form
= form_value
;
3528 case DW_AT_location
:
3529 location_form
= form_value
;
3531 case DW_AT_start_scope
:
3532 // TODO: Implement this.
3534 case DW_AT_artificial
:
3535 is_artificial
= form_value
.Boolean();
3537 case DW_AT_declaration
:
3538 case DW_AT_description
:
3539 case DW_AT_endianity
:
3541 case DW_AT_specification
:
3542 case DW_AT_visibility
:
3544 case DW_AT_abstract_origin
:
3550 // Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g.
3551 // for static constexpr member variables -- DW_AT_const_value and
3552 // DW_AT_location will both be present in the DIE defining the member.
3553 bool location_is_const_value_data
=
3554 const_value_form
.IsValid() && !location_form
.IsValid();
3556 DWARFExpressionList location_list
= [&] {
3557 if (location_form
.IsValid())
3558 return GetExprListFromAtLocation(location_form
, module
, die
, func_low_pc
);
3559 if (const_value_form
.IsValid())
3560 return GetExprListFromAtConstValue(const_value_form
, module
, die
);
3561 return DWARFExpressionList(module
, DWARFExpression(), die
.GetCU());
3564 const DWARFDIE parent_context_die
= GetDeclContextDIEContainingDIE(die
);
3565 const DWARFDIE sc_parent_die
= GetParentSymbolContextDIE(die
);
3566 const dw_tag_t parent_tag
= sc_parent_die
.Tag();
3567 bool is_static_member
= (parent_tag
== DW_TAG_compile_unit
||
3568 parent_tag
== DW_TAG_partial_unit
) &&
3569 (parent_context_die
.Tag() == DW_TAG_class_type
||
3570 parent_context_die
.Tag() == DW_TAG_structure_type
);
3572 ValueType scope
= eValueTypeInvalid
;
3573 SymbolContextScope
*symbol_context_scope
= nullptr;
3575 bool has_explicit_mangled
= mangled
!= nullptr;
3577 // LLDB relies on the mangled name (DW_TAG_linkage_name or
3578 // DW_AT_MIPS_linkage_name) to generate fully qualified names
3579 // of global variables with commands like "frame var j". For
3580 // example, if j were an int variable holding a value 4 and
3581 // declared in a namespace B which in turn is contained in a
3582 // namespace A, the command "frame var j" returns
3583 // "(int) A::B::j = 4".
3584 // If the compiler does not emit a linkage name, we should be
3585 // able to generate a fully qualified name from the
3586 // declaration context.
3587 if ((parent_tag
== DW_TAG_compile_unit
||
3588 parent_tag
== DW_TAG_partial_unit
) &&
3589 Language::LanguageIsCPlusPlus(GetLanguage(*die
.GetCU())))
3590 mangled
= die
.GetDWARFDeclContext()
3591 .GetQualifiedNameAsConstString()
3595 if (tag
== DW_TAG_formal_parameter
)
3596 scope
= eValueTypeVariableArgument
;
3598 // DWARF doesn't specify if a DW_TAG_variable is a local, global
3599 // or static variable, so we have to do a little digging:
3600 // 1) DW_AT_linkage_name implies static lifetime (but may be missing)
3601 // 2) An empty DW_AT_location is an (optimized-out) static lifetime var.
3602 // 3) DW_AT_location containing a DW_OP_addr implies static lifetime.
3603 // Clang likes to combine small global variables into the same symbol
3604 // with locations like: DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
3605 // so we need to look through the whole expression.
3606 bool has_explicit_location
= location_form
.IsValid();
3607 bool is_static_lifetime
=
3608 has_explicit_mangled
||
3609 (has_explicit_location
&& !location_list
.IsValid());
3610 // Check if the location has a DW_OP_addr with any address value...
3611 lldb::addr_t location_DW_OP_addr
= LLDB_INVALID_ADDRESS
;
3612 if (!location_is_const_value_data
) {
3613 bool op_error
= false;
3614 const DWARFExpression
* location
= location_list
.GetAlwaysValidExpr();
3616 location_DW_OP_addr
=
3617 location
->GetLocation_DW_OP_addr(location_form
.GetUnit(), op_error
);
3620 location
->DumpLocation(&strm
, eDescriptionLevelFull
, nullptr);
3621 GetObjectFile()->GetModule()->ReportError(
3622 "{0:x16}: {1} ({2}) has an invalid location: {3}", die
.GetOffset(),
3623 DW_TAG_value_to_name(die
.Tag()), die
.Tag(), strm
.GetData());
3625 if (location_DW_OP_addr
!= LLDB_INVALID_ADDRESS
)
3626 is_static_lifetime
= true;
3628 SymbolFileDWARFDebugMap
*debug_map_symfile
= GetDebugMapSymfile();
3629 if (debug_map_symfile
)
3630 // Set the module of the expression to the linked module
3631 // instead of the object file so the relocated address can be
3633 location_list
.SetModule(debug_map_symfile
->GetObjectFile()->GetModule());
3635 if (is_static_lifetime
) {
3637 scope
= eValueTypeVariableGlobal
;
3639 scope
= eValueTypeVariableStatic
;
3641 if (debug_map_symfile
) {
3642 bool linked_oso_file_addr
= false;
3644 if (is_external
&& location_DW_OP_addr
== 0) {
3645 if (Symbol
*exe_symbol
= fixupExternalAddrZeroVariable(
3646 *debug_map_symfile
, mangled
? mangled
: name
, location_list
,
3648 linked_oso_file_addr
= true;
3649 symbol_context_scope
= exe_symbol
;
3653 if (!linked_oso_file_addr
) {
3654 // The DW_OP_addr is not zero, but it contains a .o file address
3655 // which needs to be linked up correctly.
3656 const lldb::addr_t exe_file_addr
=
3657 debug_map_symfile
->LinkOSOFileAddress(this, location_DW_OP_addr
);
3658 if (exe_file_addr
!= LLDB_INVALID_ADDRESS
) {
3659 // Update the file address for this variable
3660 DWARFExpression
*location
=
3661 location_list
.GetMutableExpressionAtAddress();
3662 location
->Update_DW_OP_addr(die
.GetCU(), exe_file_addr
);
3664 // Variable didn't make it into the final executable
3670 if (location_is_const_value_data
&&
3671 die
.GetDIE()->IsGlobalOrStaticScopeVariable())
3672 scope
= eValueTypeVariableStatic
;
3674 scope
= eValueTypeVariableLocal
;
3675 if (debug_map_symfile
) {
3676 // We need to check for TLS addresses that we need to fixup
3677 if (location_list
.ContainsThreadLocalStorage()) {
3678 location_list
.LinkThreadLocalStorage(
3679 debug_map_symfile
->GetObjectFile()->GetModule(),
3680 [this, debug_map_symfile
](
3681 lldb::addr_t unlinked_file_addr
) -> lldb::addr_t
{
3682 return debug_map_symfile
->LinkOSOFileAddress(
3683 this, unlinked_file_addr
);
3685 scope
= eValueTypeVariableThreadLocal
;
3692 if (symbol_context_scope
== nullptr) {
3693 switch (parent_tag
) {
3694 case DW_TAG_subprogram
:
3695 case DW_TAG_inlined_subroutine
:
3696 case DW_TAG_lexical_block
:
3698 symbol_context_scope
=
3699 sc
.function
->GetBlock(true).FindBlockByID(sc_parent_die
.GetID());
3700 if (symbol_context_scope
== nullptr)
3701 symbol_context_scope
= sc
.function
;
3706 symbol_context_scope
= sc
.comp_unit
;
3711 if (!symbol_context_scope
) {
3712 // Not ready to parse this variable yet. It might be a global or static
3713 // variable that is in a function scope and the function in the symbol
3714 // context wasn't filled in yet
3718 auto type_sp
= std::make_shared
<SymbolFileType
>(
3719 *this, type_die_form
.Reference().GetID());
3721 bool use_type_size_for_value
=
3722 location_is_const_value_data
&&
3723 DWARFFormValue::IsDataForm(const_value_form
.Form());
3724 if (use_type_size_for_value
&& type_sp
->GetType()) {
3725 DWARFExpression
*location
= location_list
.GetMutableExpressionAtAddress();
3726 location
->UpdateValue(const_value_form
.Unsigned(),
3727 type_sp
->GetType()->GetByteSize(nullptr).value_or(0),
3728 die
.GetCU()->GetAddressByteSize());
3731 return std::make_shared
<Variable
>(
3732 die
.GetID(), name
, mangled
, type_sp
, scope
, symbol_context_scope
,
3733 scope_ranges
, &decl
, location_list
, is_external
, is_artificial
,
3734 location_is_const_value_data
, is_static_member
);
3738 SymbolFileDWARF::FindBlockContainingSpecification(
3739 const DIERef
&func_die_ref
, dw_offset_t spec_block_die_offset
) {
3740 // Give the concrete function die specified by "func_die_offset", find the
3741 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
3742 // to "spec_block_die_offset"
3743 return FindBlockContainingSpecification(GetDIE(func_die_ref
),
3744 spec_block_die_offset
);
3748 SymbolFileDWARF::FindBlockContainingSpecification(
3749 const DWARFDIE
&die
, dw_offset_t spec_block_die_offset
) {
3751 switch (die
.Tag()) {
3752 case DW_TAG_subprogram
:
3753 case DW_TAG_inlined_subroutine
:
3754 case DW_TAG_lexical_block
: {
3755 if (die
.GetReferencedDIE(DW_AT_specification
).GetOffset() ==
3756 spec_block_die_offset
)
3759 if (die
.GetReferencedDIE(DW_AT_abstract_origin
).GetOffset() ==
3760 spec_block_die_offset
)
3767 // Give the concrete function die specified by "func_die_offset", find the
3768 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
3769 // to "spec_block_die_offset"
3770 for (DWARFDIE child_die
: die
.children()) {
3771 DWARFDIE result_die
=
3772 FindBlockContainingSpecification(child_die
, spec_block_die_offset
);
3781 void SymbolFileDWARF::ParseAndAppendGlobalVariable(
3782 const SymbolContext
&sc
, const DWARFDIE
&die
,
3783 VariableList
&cc_variable_list
) {
3787 dw_tag_t tag
= die
.Tag();
3788 if (tag
!= DW_TAG_variable
&& tag
!= DW_TAG_constant
&& tag
!= DW_TAG_member
)
3791 // Check to see if we have already parsed this variable or constant?
3792 VariableSP var_sp
= GetDIEToVariable()[die
.GetDIE()];
3794 cc_variable_list
.AddVariableIfUnique(var_sp
);
3798 // We haven't parsed the variable yet, lets do that now. Also, let us include
3799 // the variable in the relevant compilation unit's variable list, if it
3801 VariableListSP variable_list_sp
;
3802 DWARFDIE sc_parent_die
= GetParentSymbolContextDIE(die
);
3803 dw_tag_t parent_tag
= sc_parent_die
.Tag();
3804 switch (parent_tag
) {
3805 case DW_TAG_compile_unit
:
3806 case DW_TAG_partial_unit
:
3807 if (sc
.comp_unit
!= nullptr) {
3808 variable_list_sp
= sc
.comp_unit
->GetVariableList(false);
3810 GetObjectFile()->GetModule()->ReportError(
3811 "parent {0:x8} {1} ({2}) with no valid compile unit in "
3812 "symbol context for {3:x8} {4} ({5}).\n",
3813 sc_parent_die
.GetID(), DW_TAG_value_to_name(sc_parent_die
.Tag()),
3814 sc_parent_die
.Tag(), die
.GetID(), DW_TAG_value_to_name(die
.Tag()),
3821 LLDB_LOG(GetLog(DWARFLog::Lookups
),
3822 "{0} '{1}' ({2:x8}) is not a global variable - ignoring", tag
,
3823 die
.GetName(), die
.GetID());
3827 var_sp
= ParseVariableDIECached(sc
, die
);
3831 cc_variable_list
.AddVariableIfUnique(var_sp
);
3832 if (variable_list_sp
)
3833 variable_list_sp
->AddVariableIfUnique(var_sp
);
3837 SymbolFileDWARF::MergeBlockAbstractParameters(const DWARFDIE
&block_die
,
3838 DIEArray
&&variable_dies
) {
3839 // DW_TAG_inline_subroutine objects may omit DW_TAG_formal_parameter in
3840 // instances of the function when they are unused (i.e., the parameter's
3841 // location list would be empty). The current DW_TAG_inline_subroutine may
3842 // refer to another DW_TAG_subprogram that might actually have the definitions
3843 // of the parameters and we need to include these so they show up in the
3844 // variables for this function (for example, in a stack trace). Let us try to
3845 // find the abstract subprogram that might contain the parameter definitions
3846 // and merge with the concrete parameters.
3848 // Nothing to merge if the block is not an inlined function.
3849 if (block_die
.Tag() != DW_TAG_inlined_subroutine
) {
3850 return std::move(variable_dies
);
3853 // Nothing to merge if the block does not have abstract parameters.
3854 DWARFDIE abs_die
= block_die
.GetReferencedDIE(DW_AT_abstract_origin
);
3855 if (!abs_die
|| abs_die
.Tag() != DW_TAG_subprogram
||
3856 !abs_die
.HasChildren()) {
3857 return std::move(variable_dies
);
3860 // For each abstract parameter, if we have its concrete counterpart, insert
3861 // it. Otherwise, insert the abstract parameter.
3862 DIEArray::iterator concrete_it
= variable_dies
.begin();
3863 DWARFDIE abstract_child
= abs_die
.GetFirstChild();
3865 bool did_merge_abstract
= false;
3866 for (; abstract_child
; abstract_child
= abstract_child
.GetSibling()) {
3867 if (abstract_child
.Tag() == DW_TAG_formal_parameter
) {
3868 if (concrete_it
== variable_dies
.end() ||
3869 GetDIE(*concrete_it
).Tag() != DW_TAG_formal_parameter
) {
3870 // We arrived at the end of the concrete parameter list, so all
3871 // the remaining abstract parameters must have been omitted.
3872 // Let us insert them to the merged list here.
3873 merged
.push_back(*abstract_child
.GetDIERef());
3874 did_merge_abstract
= true;
3878 DWARFDIE origin_of_concrete
=
3879 GetDIE(*concrete_it
).GetReferencedDIE(DW_AT_abstract_origin
);
3880 if (origin_of_concrete
== abstract_child
) {
3881 // The current abstract parameter is the origin of the current
3882 // concrete parameter, just push the concrete parameter.
3883 merged
.push_back(*concrete_it
);
3886 // Otherwise, the parameter must have been omitted from the concrete
3887 // function, so insert the abstract one.
3888 merged
.push_back(*abstract_child
.GetDIERef());
3889 did_merge_abstract
= true;
3894 // Shortcut if no merging happened.
3895 if (!did_merge_abstract
)
3896 return std::move(variable_dies
);
3898 // We inserted all the abstract parameters (or their concrete counterparts).
3899 // Let us insert all the remaining concrete variables to the merged list.
3900 // During the insertion, let us check there are no remaining concrete
3901 // formal parameters. If that's the case, then just bailout from the merge -
3902 // the variable list is malformed.
3903 for (; concrete_it
!= variable_dies
.end(); ++concrete_it
) {
3904 if (GetDIE(*concrete_it
).Tag() == DW_TAG_formal_parameter
) {
3905 return std::move(variable_dies
);
3907 merged
.push_back(*concrete_it
);
3912 size_t SymbolFileDWARF::ParseVariablesInFunctionContext(
3913 const SymbolContext
&sc
, const DWARFDIE
&die
,
3914 const lldb::addr_t func_low_pc
) {
3915 if (!die
|| !sc
.function
)
3918 DIEArray dummy_block_variables
; // The recursive call should not add anything
3919 // to this vector because |die| should be a
3920 // subprogram, so all variables will be added
3921 // to the subprogram's list.
3922 return ParseVariablesInFunctionContextRecursive(sc
, die
, func_low_pc
,
3923 dummy_block_variables
);
3926 // This method parses all the variables in the blocks in the subtree of |die|,
3927 // and inserts them to the variable list for all the nested blocks.
3928 // The uninserted variables for the current block are accumulated in
3930 size_t SymbolFileDWARF::ParseVariablesInFunctionContextRecursive(
3931 const lldb_private::SymbolContext
&sc
, const DWARFDIE
&die
,
3932 lldb::addr_t func_low_pc
, DIEArray
&accumulator
) {
3933 size_t vars_added
= 0;
3934 dw_tag_t tag
= die
.Tag();
3936 if ((tag
== DW_TAG_variable
) || (tag
== DW_TAG_constant
) ||
3937 (tag
== DW_TAG_formal_parameter
)) {
3938 accumulator
.push_back(*die
.GetDIERef());
3942 case DW_TAG_subprogram
:
3943 case DW_TAG_inlined_subroutine
:
3944 case DW_TAG_lexical_block
: {
3945 // If we start a new block, compute a new block variable list and recurse.
3947 sc
.function
->GetBlock(/*can_create=*/true).FindBlockByID(die
.GetID());
3948 if (block
== nullptr) {
3949 // This must be a specification or abstract origin with a
3950 // concrete block counterpart in the current function. We need
3951 // to find the concrete block so we can correctly add the
3953 const DWARFDIE concrete_block_die
= FindBlockContainingSpecification(
3954 GetDIE(sc
.function
->GetID()), die
.GetOffset());
3955 if (concrete_block_die
)
3956 block
= sc
.function
->GetBlock(/*can_create=*/true)
3957 .FindBlockByID(concrete_block_die
.GetID());
3960 if (block
== nullptr)
3963 const bool can_create
= false;
3964 VariableListSP block_variable_list_sp
=
3965 block
->GetBlockVariableList(can_create
);
3966 if (block_variable_list_sp
.get() == nullptr) {
3967 block_variable_list_sp
= std::make_shared
<VariableList
>();
3968 block
->SetVariableList(block_variable_list_sp
);
3971 DIEArray block_variables
;
3972 for (DWARFDIE child
= die
.GetFirstChild(); child
;
3973 child
= child
.GetSibling()) {
3974 vars_added
+= ParseVariablesInFunctionContextRecursive(
3975 sc
, child
, func_low_pc
, block_variables
);
3978 MergeBlockAbstractParameters(die
, std::move(block_variables
));
3979 vars_added
+= PopulateBlockVariableList(*block_variable_list_sp
, sc
,
3980 block_variables
, func_low_pc
);
3985 // Recurse to children with the same variable accumulator.
3986 for (DWARFDIE child
= die
.GetFirstChild(); child
;
3987 child
= child
.GetSibling()) {
3988 vars_added
+= ParseVariablesInFunctionContextRecursive(
3989 sc
, child
, func_low_pc
, accumulator
);
3997 size_t SymbolFileDWARF::PopulateBlockVariableList(
3998 VariableList
&variable_list
, const lldb_private::SymbolContext
&sc
,
3999 llvm::ArrayRef
<DIERef
> variable_dies
, lldb::addr_t func_low_pc
) {
4000 // Parse the variable DIEs and insert them to the list.
4001 for (auto &die
: variable_dies
) {
4002 if (VariableSP var_sp
= ParseVariableDIE(sc
, GetDIE(die
), func_low_pc
)) {
4003 variable_list
.AddVariableIfUnique(var_sp
);
4006 return variable_dies
.size();
4009 /// Collect call site parameters in a DW_TAG_call_site DIE.
4010 static CallSiteParameterArray
4011 CollectCallSiteParameters(ModuleSP module
, DWARFDIE call_site_die
) {
4012 CallSiteParameterArray parameters
;
4013 for (DWARFDIE child
: call_site_die
.children()) {
4014 if (child
.Tag() != DW_TAG_call_site_parameter
&&
4015 child
.Tag() != DW_TAG_GNU_call_site_parameter
)
4018 std::optional
<DWARFExpressionList
> LocationInCallee
;
4019 std::optional
<DWARFExpressionList
> LocationInCaller
;
4021 DWARFAttributes attributes
= child
.GetAttributes();
4023 // Parse the location at index \p attr_index within this call site parameter
4024 // DIE, or return std::nullopt on failure.
4025 auto parse_simple_location
=
4026 [&](int attr_index
) -> std::optional
<DWARFExpressionList
> {
4027 DWARFFormValue form_value
;
4028 if (!attributes
.ExtractFormValueAtIndex(attr_index
, form_value
))
4030 if (!DWARFFormValue::IsBlockForm(form_value
.Form()))
4032 auto data
= child
.GetData();
4033 uint64_t block_offset
= form_value
.BlockData() - data
.GetDataStart();
4034 uint64_t block_length
= form_value
.Unsigned();
4035 return DWARFExpressionList(
4036 module
, DataExtractor(data
, block_offset
, block_length
),
4040 for (size_t i
= 0; i
< attributes
.Size(); ++i
) {
4041 dw_attr_t attr
= attributes
.AttributeAtIndex(i
);
4042 if (attr
== DW_AT_location
)
4043 LocationInCallee
= parse_simple_location(i
);
4044 if (attr
== DW_AT_call_value
|| attr
== DW_AT_GNU_call_site_value
)
4045 LocationInCaller
= parse_simple_location(i
);
4048 if (LocationInCallee
&& LocationInCaller
) {
4049 CallSiteParameter param
= {*LocationInCallee
, *LocationInCaller
};
4050 parameters
.push_back(param
);
4056 /// Collect call graph edges present in a function DIE.
4057 std::vector
<std::unique_ptr
<lldb_private::CallEdge
>>
4058 SymbolFileDWARF::CollectCallEdges(ModuleSP module
, DWARFDIE function_die
) {
4059 // Check if the function has a supported call site-related attribute.
4060 // TODO: In the future it may be worthwhile to support call_all_source_calls.
4061 bool has_call_edges
=
4062 function_die
.GetAttributeValueAsUnsigned(DW_AT_call_all_calls
, 0) ||
4063 function_die
.GetAttributeValueAsUnsigned(DW_AT_GNU_all_call_sites
, 0);
4064 if (!has_call_edges
)
4067 Log
*log
= GetLog(LLDBLog::Step
);
4068 LLDB_LOG(log
, "CollectCallEdges: Found call site info in {0}",
4069 function_die
.GetPubname());
4071 // Scan the DIE for TAG_call_site entries.
4072 // TODO: A recursive scan of all blocks in the subprogram is needed in order
4073 // to be DWARF5-compliant. This may need to be done lazily to be performant.
4074 // For now, assume that all entries are nested directly under the subprogram
4075 // (this is the kind of DWARF LLVM produces) and parse them eagerly.
4076 std::vector
<std::unique_ptr
<CallEdge
>> call_edges
;
4077 for (DWARFDIE child
: function_die
.children()) {
4078 if (child
.Tag() != DW_TAG_call_site
&& child
.Tag() != DW_TAG_GNU_call_site
)
4081 std::optional
<DWARFDIE
> call_origin
;
4082 std::optional
<DWARFExpressionList
> call_target
;
4083 addr_t return_pc
= LLDB_INVALID_ADDRESS
;
4084 addr_t call_inst_pc
= LLDB_INVALID_ADDRESS
;
4085 addr_t low_pc
= LLDB_INVALID_ADDRESS
;
4086 bool tail_call
= false;
4088 // Second DW_AT_low_pc may come from DW_TAG_subprogram referenced by
4089 // DW_TAG_GNU_call_site's DW_AT_abstract_origin overwriting our 'low_pc'.
4090 // So do not inherit attributes from DW_AT_abstract_origin.
4091 DWARFAttributes attributes
= child
.GetAttributes(DWARFDIE::Recurse::no
);
4092 for (size_t i
= 0; i
< attributes
.Size(); ++i
) {
4093 DWARFFormValue form_value
;
4094 if (!attributes
.ExtractFormValueAtIndex(i
, form_value
)) {
4095 LLDB_LOG(log
, "CollectCallEdges: Could not extract TAG_call_site form");
4099 dw_attr_t attr
= attributes
.AttributeAtIndex(i
);
4101 if (attr
== DW_AT_call_tail_call
|| attr
== DW_AT_GNU_tail_call
)
4102 tail_call
= form_value
.Boolean();
4104 // Extract DW_AT_call_origin (the call target's DIE).
4105 if (attr
== DW_AT_call_origin
|| attr
== DW_AT_abstract_origin
) {
4106 call_origin
= form_value
.Reference();
4107 if (!call_origin
->IsValid()) {
4108 LLDB_LOG(log
, "CollectCallEdges: Invalid call origin in {0}",
4109 function_die
.GetPubname());
4114 if (attr
== DW_AT_low_pc
)
4115 low_pc
= form_value
.Address();
4117 // Extract DW_AT_call_return_pc (the PC the call returns to) if it's
4118 // available. It should only ever be unavailable for tail call edges, in
4119 // which case use LLDB_INVALID_ADDRESS.
4120 if (attr
== DW_AT_call_return_pc
)
4121 return_pc
= form_value
.Address();
4123 // Extract DW_AT_call_pc (the PC at the call/branch instruction). It
4124 // should only ever be unavailable for non-tail calls, in which case use
4125 // LLDB_INVALID_ADDRESS.
4126 if (attr
== DW_AT_call_pc
)
4127 call_inst_pc
= form_value
.Address();
4129 // Extract DW_AT_call_target (the location of the address of the indirect
4131 if (attr
== DW_AT_call_target
|| attr
== DW_AT_GNU_call_site_target
) {
4132 if (!DWARFFormValue::IsBlockForm(form_value
.Form())) {
4134 "CollectCallEdges: AT_call_target does not have block form");
4138 auto data
= child
.GetData();
4139 uint64_t block_offset
= form_value
.BlockData() - data
.GetDataStart();
4140 uint64_t block_length
= form_value
.Unsigned();
4141 call_target
= DWARFExpressionList(
4142 module
, DataExtractor(data
, block_offset
, block_length
),
4146 if (!call_origin
&& !call_target
) {
4147 LLDB_LOG(log
, "CollectCallEdges: call site without any call target");
4151 addr_t caller_address
;
4152 CallEdge::AddrType caller_address_type
;
4153 if (return_pc
!= LLDB_INVALID_ADDRESS
) {
4154 caller_address
= return_pc
;
4155 caller_address_type
= CallEdge::AddrType::AfterCall
;
4156 } else if (low_pc
!= LLDB_INVALID_ADDRESS
) {
4157 caller_address
= low_pc
;
4158 caller_address_type
= CallEdge::AddrType::AfterCall
;
4159 } else if (call_inst_pc
!= LLDB_INVALID_ADDRESS
) {
4160 caller_address
= call_inst_pc
;
4161 caller_address_type
= CallEdge::AddrType::Call
;
4163 LLDB_LOG(log
, "CollectCallEdges: No caller address");
4166 // Adjust any PC forms. It needs to be fixed up if the main executable
4167 // contains a debug map (i.e. pointers to object files), because we need a
4168 // file address relative to the executable's text section.
4169 caller_address
= FixupAddress(caller_address
);
4171 // Extract call site parameters.
4172 CallSiteParameterArray parameters
=
4173 CollectCallSiteParameters(module
, child
);
4175 std::unique_ptr
<CallEdge
> edge
;
4178 "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x}) "
4180 call_origin
->GetPubname(), return_pc
, call_inst_pc
);
4181 edge
= std::make_unique
<DirectCallEdge
>(
4182 call_origin
->GetMangledName(), caller_address_type
, caller_address
,
4183 tail_call
, std::move(parameters
));
4186 StreamString call_target_desc
;
4187 call_target
->GetDescription(&call_target_desc
, eDescriptionLevelBrief
,
4189 LLDB_LOG(log
, "CollectCallEdges: Found indirect call target: {0}",
4190 call_target_desc
.GetString());
4192 edge
= std::make_unique
<IndirectCallEdge
>(
4193 *call_target
, caller_address_type
, caller_address
, tail_call
,
4194 std::move(parameters
));
4197 if (log
&& parameters
.size()) {
4198 for (const CallSiteParameter
¶m
: parameters
) {
4199 StreamString callee_loc_desc
, caller_loc_desc
;
4200 param
.LocationInCallee
.GetDescription(&callee_loc_desc
,
4201 eDescriptionLevelBrief
, nullptr);
4202 param
.LocationInCaller
.GetDescription(&caller_loc_desc
,
4203 eDescriptionLevelBrief
, nullptr);
4204 LLDB_LOG(log
, "CollectCallEdges: \tparam: {0} => {1}",
4205 callee_loc_desc
.GetString(), caller_loc_desc
.GetString());
4209 call_edges
.push_back(std::move(edge
));
4214 std::vector
<std::unique_ptr
<lldb_private::CallEdge
>>
4215 SymbolFileDWARF::ParseCallEdgesInFunction(lldb_private::UserID func_id
) {
4216 // ParseCallEdgesInFunction must be called at the behest of an exclusively
4217 // locked lldb::Function instance. Storage for parsed call edges is owned by
4218 // the lldb::Function instance: locking at the SymbolFile level would be too
4219 // late, because the act of storing results from ParseCallEdgesInFunction
4221 DWARFDIE func_die
= GetDIE(func_id
.GetID());
4222 if (func_die
.IsValid())
4223 return CollectCallEdges(GetObjectFile()->GetModule(), func_die
);
4227 void SymbolFileDWARF::Dump(lldb_private::Stream
&s
) {
4228 SymbolFileCommon::Dump(s
);
4232 void SymbolFileDWARF::DumpClangAST(Stream
&s
) {
4233 auto ts_or_err
= GetTypeSystemForLanguage(eLanguageTypeC_plus_plus
);
4236 auto ts
= *ts_or_err
;
4237 TypeSystemClang
*clang
= llvm::dyn_cast_or_null
<TypeSystemClang
>(ts
.get());
4240 clang
->Dump(s
.AsRawOstream());
4243 bool SymbolFileDWARF::GetSeparateDebugInfo(StructuredData::Dictionary
&d
,
4245 StructuredData::Array separate_debug_info_files
;
4246 DWARFDebugInfo
&info
= DebugInfo();
4247 const size_t num_cus
= info
.GetNumUnits();
4248 for (size_t cu_idx
= 0; cu_idx
< num_cus
; cu_idx
++) {
4249 DWARFUnit
*unit
= info
.GetUnitAtIndex(cu_idx
);
4250 DWARFCompileUnit
*dwarf_cu
= llvm::dyn_cast
<DWARFCompileUnit
>(unit
);
4251 if (dwarf_cu
== nullptr)
4254 // Check if this is a DWO unit by checking if it has a DWO ID.
4255 // NOTE: it seems that `DWARFUnit::IsDWOUnit` is always false?
4256 if (!dwarf_cu
->GetDWOId().has_value())
4259 StructuredData::DictionarySP dwo_data
=
4260 std::make_shared
<StructuredData::Dictionary
>();
4261 const uint64_t dwo_id
= dwarf_cu
->GetDWOId().value();
4262 dwo_data
->AddIntegerItem("dwo_id", dwo_id
);
4264 if (const DWARFBaseDIE die
= dwarf_cu
->GetUnitDIEOnly()) {
4265 const char *dwo_name
= GetDWOName(*dwarf_cu
, *die
.GetDIE());
4267 dwo_data
->AddStringItem("dwo_name", dwo_name
);
4269 dwo_data
->AddStringItem("error", "missing dwo name");
4272 const char *comp_dir
= die
.GetDIE()->GetAttributeValueAsString(
4273 dwarf_cu
, DW_AT_comp_dir
, nullptr);
4275 dwo_data
->AddStringItem("comp_dir", comp_dir
);
4278 dwo_data
->AddStringItem(
4280 llvm::formatv("unable to get unit DIE for DWARFUnit at {0:x}",
4281 dwarf_cu
->GetOffset())
4285 // If we have a DWO symbol file, that means we were able to successfully
4287 SymbolFile
*dwo_symfile
= dwarf_cu
->GetDwoSymbolFile();
4289 dwo_data
->AddStringItem(
4290 "resolved_dwo_path",
4291 dwo_symfile
->GetObjectFile()->GetFileSpec().GetPath());
4293 dwo_data
->AddStringItem("error",
4294 dwarf_cu
->GetDwoError().AsCString("unknown"));
4296 dwo_data
->AddBooleanItem("loaded", dwo_symfile
!= nullptr);
4297 if (!errors_only
|| dwo_data
->HasKey("error"))
4298 separate_debug_info_files
.AddItem(dwo_data
);
4301 d
.AddStringItem("type", "dwo");
4302 d
.AddStringItem("symfile", GetMainObjectFile()->GetFileSpec().GetPath());
4303 d
.AddItem("separate-debug-info-files",
4304 std::make_shared
<StructuredData::Array
>(
4305 std::move(separate_debug_info_files
)));
4309 SymbolFileDWARFDebugMap
*SymbolFileDWARF::GetDebugMapSymfile() {
4310 if (m_debug_map_symfile
== nullptr) {
4311 lldb::ModuleSP
module_sp(m_debug_map_module_wp
.lock());
4313 m_debug_map_symfile
= llvm::cast
<SymbolFileDWARFDebugMap
>(
4314 module_sp
->GetSymbolFile()->GetBackingSymbolFile());
4317 return m_debug_map_symfile
;
4320 const std::shared_ptr
<SymbolFileDWARFDwo
> &SymbolFileDWARF::GetDwpSymbolFile() {
4321 llvm::call_once(m_dwp_symfile_once_flag
, [this]() {
4322 // Create a list of files to try and append .dwp to.
4323 FileSpecList symfiles
;
4324 // Append the module's object file path.
4325 const FileSpec module_fspec
= m_objfile_sp
->GetModule()->GetFileSpec();
4326 symfiles
.Append(module_fspec
);
4327 // Append the object file for this SymbolFile only if it is different from
4328 // the module's file path. Our main module could be "a.out", our symbol file
4329 // could be "a.debug" and our ".dwp" file might be "a.debug.dwp" instead of
4331 const FileSpec
symfile_fspec(m_objfile_sp
->GetFileSpec());
4332 if (symfile_fspec
!= module_fspec
) {
4333 symfiles
.Append(symfile_fspec
);
4335 // If we don't have a separate debug info file, then try stripping the
4336 // extension. The main module could be "a.debug" and the .dwp file could
4337 // be "a.dwp" instead of "a.debug.dwp".
4338 ConstString filename_no_ext
=
4339 module_fspec
.GetFileNameStrippingExtension();
4340 if (filename_no_ext
!= module_fspec
.GetFilename()) {
4341 FileSpec
module_spec_no_ext(module_fspec
);
4342 module_spec_no_ext
.SetFilename(filename_no_ext
);
4343 symfiles
.Append(module_spec_no_ext
);
4346 Log
*log
= GetLog(DWARFLog::SplitDwarf
);
4347 FileSpecList search_paths
= Target::GetDefaultDebugFileSearchPaths();
4348 ModuleSpec module_spec
;
4349 module_spec
.GetFileSpec() = m_objfile_sp
->GetFileSpec();
4350 FileSpec dwp_filespec
;
4351 for (const auto &symfile
: symfiles
.files()) {
4352 module_spec
.GetSymbolFileSpec() =
4353 FileSpec(symfile
.GetPath() + ".dwp", symfile
.GetPathStyle());
4354 LLDB_LOG(log
, "Searching for DWP using: \"{0}\"",
4355 module_spec
.GetSymbolFileSpec());
4357 PluginManager::LocateExecutableSymbolFile(module_spec
, search_paths
);
4358 if (FileSystem::Instance().Exists(dwp_filespec
)) {
4362 if (!FileSystem::Instance().Exists(dwp_filespec
)) {
4363 LLDB_LOG(log
, "No DWP file found locally");
4364 // Fill in the UUID for the module we're trying to match for, so we can
4365 // find the correct DWP file, as the Debuginfod plugin uses *only* this
4366 // data to correctly match the DWP file with the binary.
4367 module_spec
.GetUUID() = m_objfile_sp
->GetUUID();
4369 PluginManager::LocateExecutableSymbolFile(module_spec
, search_paths
);
4371 if (FileSystem::Instance().Exists(dwp_filespec
)) {
4372 LLDB_LOG(log
, "Found DWP file: \"{0}\"", dwp_filespec
);
4373 DataBufferSP dwp_file_data_sp
;
4374 lldb::offset_t dwp_file_data_offset
= 0;
4375 ObjectFileSP dwp_obj_file
= ObjectFile::FindPlugin(
4376 GetObjectFile()->GetModule(), &dwp_filespec
, 0,
4377 FileSystem::Instance().GetByteSize(dwp_filespec
), dwp_file_data_sp
,
4378 dwp_file_data_offset
);
4380 m_dwp_symfile
= std::make_shared
<SymbolFileDWARFDwo
>(
4381 *this, dwp_obj_file
, DIERef::k_file_index_mask
);
4384 if (!m_dwp_symfile
) {
4385 LLDB_LOG(log
, "Unable to locate for DWP file for: \"{0}\"",
4386 m_objfile_sp
->GetModule()->GetFileSpec());
4389 return m_dwp_symfile
;
4392 llvm::Expected
<lldb::TypeSystemSP
>
4393 SymbolFileDWARF::GetTypeSystem(DWARFUnit
&unit
) {
4394 return unit
.GetSymbolFileDWARF().GetTypeSystemForLanguage(GetLanguage(unit
));
4397 DWARFASTParser
*SymbolFileDWARF::GetDWARFParser(DWARFUnit
&unit
) {
4398 auto type_system_or_err
= GetTypeSystem(unit
);
4399 if (auto err
= type_system_or_err
.takeError()) {
4400 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols
), std::move(err
),
4401 "Unable to get DWARFASTParser: {0}");
4404 if (auto ts
= *type_system_or_err
)
4405 return ts
->GetDWARFParser();
4409 CompilerDecl
SymbolFileDWARF::GetDecl(const DWARFDIE
&die
) {
4410 if (DWARFASTParser
*dwarf_ast
= GetDWARFParser(*die
.GetCU()))
4411 return dwarf_ast
->GetDeclForUIDFromDWARF(die
);
4412 return CompilerDecl();
4415 CompilerDeclContext
SymbolFileDWARF::GetDeclContext(const DWARFDIE
&die
) {
4416 if (DWARFASTParser
*dwarf_ast
= GetDWARFParser(*die
.GetCU()))
4417 return dwarf_ast
->GetDeclContextForUIDFromDWARF(die
);
4418 return CompilerDeclContext();
4422 SymbolFileDWARF::GetContainingDeclContext(const DWARFDIE
&die
) {
4423 if (DWARFASTParser
*dwarf_ast
= GetDWARFParser(*die
.GetCU()))
4424 return dwarf_ast
->GetDeclContextContainingUIDFromDWARF(die
);
4425 return CompilerDeclContext();
4428 LanguageType
SymbolFileDWARF::LanguageTypeFromDWARF(uint64_t val
) {
4429 // Note: user languages between lo_user and hi_user must be handled
4432 case DW_LANG_Mips_Assembler
:
4433 return eLanguageTypeMipsAssembler
;
4435 return static_cast<LanguageType
>(val
);
4439 LanguageType
SymbolFileDWARF::GetLanguage(DWARFUnit
&unit
) {
4440 return LanguageTypeFromDWARF(unit
.GetDWARFLanguageType());
4443 LanguageType
SymbolFileDWARF::GetLanguageFamily(DWARFUnit
&unit
) {
4444 auto lang
= (llvm::dwarf::SourceLanguage
)unit
.GetDWARFLanguageType();
4445 if (llvm::dwarf::isCPlusPlus(lang
))
4446 lang
= DW_LANG_C_plus_plus
;
4447 return LanguageTypeFromDWARF(lang
);
4450 StatsDuration::Duration
SymbolFileDWARF::GetDebugInfoIndexTime() {
4452 return m_index
->GetIndexTime();
4456 void SymbolFileDWARF::ResetStatistics() {
4457 m_parse_time
.reset();
4459 return m_index
->ResetStatistics();
4462 Status
SymbolFileDWARF::CalculateFrameVariableError(StackFrame
&frame
) {
4463 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
4464 CompileUnit
*cu
= frame
.GetSymbolContext(eSymbolContextCompUnit
).comp_unit
;
4468 DWARFCompileUnit
*dwarf_cu
= GetDWARFCompileUnit(cu
);
4472 // Check if we have a skeleton compile unit that had issues trying to load
4473 // its .dwo/.dwp file. First pares the Unit DIE to make sure we see any .dwo
4475 dwarf_cu
->ExtractUnitDIEIfNeeded();
4476 const Status
&dwo_error
= dwarf_cu
->GetDwoError();
4477 if (dwo_error
.Fail())
4478 return dwo_error
.Clone();
4480 // Don't return an error for assembly files as they typically don't have
4481 // varaible information.
4482 if (dwarf_cu
->GetDWARFLanguageType() == DW_LANG_Mips_Assembler
)
4485 // Check if this compile unit has any variable DIEs. If it doesn't then there
4486 // is not variable information for the entire compile unit.
4487 if (dwarf_cu
->HasAny({DW_TAG_variable
, DW_TAG_formal_parameter
}))
4490 return Status::FromErrorString(
4491 "no variable information is available in debug info for this "
4495 void SymbolFileDWARF::GetCompileOptions(
4496 std::unordered_map
<lldb::CompUnitSP
, lldb_private::Args
> &args
) {
4498 const uint32_t num_compile_units
= GetNumCompileUnits();
4500 for (uint32_t cu_idx
= 0; cu_idx
< num_compile_units
; ++cu_idx
) {
4501 lldb::CompUnitSP comp_unit
= GetCompileUnitAtIndex(cu_idx
);
4505 DWARFUnit
*dwarf_cu
= GetDWARFCompileUnit(comp_unit
.get());
4509 const DWARFBaseDIE die
= dwarf_cu
->GetUnitDIEOnly();
4513 const char *flags
= die
.GetAttributeValueAsString(DW_AT_APPLE_flags
, NULL
);
4517 args
.insert({comp_unit
, Args(flags
)});