1 //===-- SymbolFileDWARF.h --------------------------------------*- C++ -*-===//
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 #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H
10 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H
16 #include <unordered_map>
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/SetVector.h"
21 #include "llvm/Support/Threading.h"
23 #include "lldb/Core/UniqueCStringMap.h"
24 #include "lldb/Core/dwarf.h"
25 #include "lldb/Expression/DWARFExpressionList.h"
26 #include "lldb/Symbol/DebugMacros.h"
27 #include "lldb/Symbol/SymbolContext.h"
28 #include "lldb/Symbol/SymbolFile.h"
29 #include "lldb/Target/Statistics.h"
30 #include "lldb/Utility/ConstString.h"
31 #include "lldb/Utility/Flags.h"
32 #include "lldb/Utility/RangeMap.h"
33 #include "lldb/Utility/StructuredData.h"
34 #include "lldb/lldb-private.h"
36 #include "DWARFContext.h"
37 #include "DWARFDataExtractor.h"
38 #include "DWARFDefines.h"
39 #include "DWARFIndex.h"
40 #include "UniqueDWARFASTType.h"
42 class DWARFASTParserClang
;
45 class DWARFDebugAbbrev
;
48 namespace lldb_private::plugin
{
50 // Forward Declarations for this DWARF plugin
52 class DWARFCompileUnit
;
53 class DWARFDebugAranges
;
55 class DWARFDebugInfoEntry
;
57 class DWARFDeclContext
;
60 class SymbolFileDWARFDebugMap
;
61 class SymbolFileDWARFDwo
;
62 class SymbolFileDWARFDwp
;
64 #define DIE_IS_BEING_PARSED ((lldb_private::Type *)1)
66 class SymbolFileDWARF
: public SymbolFileCommon
{
67 /// LLVM RTTI support.
71 /// LLVM RTTI support.
73 bool isA(const void *ClassID
) const override
{
74 return ClassID
== &ID
|| SymbolFileCommon::isA(ClassID
);
76 static bool classof(const SymbolFile
*obj
) { return obj
->isA(&ID
); }
79 friend class SymbolFileDWARFDebugMap
;
80 friend class SymbolFileDWARFDwo
;
81 friend class DebugMapModule
;
82 friend class DWARFCompileUnit
;
83 friend class DWARFDIE
;
84 friend class DWARFASTParser
;
87 static void Initialize();
89 static void Terminate();
91 static void DebuggerInitialize(Debugger
&debugger
);
93 static llvm::StringRef
GetPluginNameStatic() { return "dwarf"; }
95 static llvm::StringRef
GetPluginDescriptionStatic();
97 static SymbolFile
*CreateInstance(lldb::ObjectFileSP objfile_sp
);
99 // Constructors and Destructors
101 SymbolFileDWARF(lldb::ObjectFileSP objfile_sp
, SectionList
*dwo_section_list
);
103 ~SymbolFileDWARF() override
;
105 uint32_t CalculateAbilities() override
;
107 void InitializeObject() override
;
109 // Compile Unit function calls
111 lldb::LanguageType
ParseLanguage(CompileUnit
&comp_unit
) override
;
113 XcodeSDK
ParseXcodeSDK(CompileUnit
&comp_unit
) override
;
115 size_t ParseFunctions(CompileUnit
&comp_unit
) override
;
117 bool ParseLineTable(CompileUnit
&comp_unit
) override
;
119 bool ParseDebugMacros(CompileUnit
&comp_unit
) override
;
121 bool ForEachExternalModule(CompileUnit
&, llvm::DenseSet
<SymbolFile
*> &,
122 llvm::function_ref
<bool(Module
&)>) override
;
124 bool ParseSupportFiles(CompileUnit
&comp_unit
,
125 SupportFileList
&support_files
) override
;
127 bool ParseIsOptimized(CompileUnit
&comp_unit
) override
;
129 size_t ParseTypes(CompileUnit
&comp_unit
) override
;
132 ParseImportedModules(const SymbolContext
&sc
,
133 std::vector
<SourceModule
> &imported_modules
) override
;
135 size_t ParseBlocksRecursive(Function
&func
) override
;
137 size_t ParseVariablesForContext(const SymbolContext
&sc
) override
;
139 std::optional
<ArrayInfo
>
140 GetDynamicArrayInfoForUID(lldb::user_id_t type_uid
,
141 const ExecutionContext
*exe_ctx
) override
;
143 bool CompleteType(CompilerType
&compiler_type
) override
;
145 Type
*ResolveType(const DWARFDIE
&die
, bool assert_not_being_parsed
= true,
146 bool resolve_function_context
= false);
148 CompilerDecl
GetDeclForUID(lldb::user_id_t uid
) override
;
150 CompilerDeclContext
GetDeclContextForUID(lldb::user_id_t uid
) override
;
152 CompilerDeclContext
GetDeclContextContainingUID(lldb::user_id_t uid
) override
;
154 std::vector
<CompilerContext
>
155 GetCompilerContextForUID(lldb::user_id_t uid
) override
;
157 void ParseDeclsForContext(CompilerDeclContext decl_ctx
) override
;
159 uint32_t ResolveSymbolContext(const Address
&so_addr
,
160 lldb::SymbolContextItem resolve_scope
,
161 SymbolContext
&sc
) override
;
163 Status
CalculateFrameVariableError(StackFrame
&frame
) override
;
165 uint32_t ResolveSymbolContext(const SourceLocationSpec
&src_location_spec
,
166 lldb::SymbolContextItem resolve_scope
,
167 SymbolContextList
&sc_list
) override
;
169 void FindGlobalVariables(ConstString name
,
170 const CompilerDeclContext
&parent_decl_ctx
,
171 uint32_t max_matches
,
172 VariableList
&variables
) override
;
174 void FindGlobalVariables(const RegularExpression
®ex
, uint32_t max_matches
,
175 VariableList
&variables
) override
;
177 void FindFunctions(const Module::LookupInfo
&lookup_info
,
178 const CompilerDeclContext
&parent_decl_ctx
,
179 bool include_inlines
, SymbolContextList
&sc_list
) override
;
181 void FindFunctions(const RegularExpression
®ex
, bool include_inlines
,
182 SymbolContextList
&sc_list
) override
;
185 GetMangledNamesForFunction(const std::string
&scope_qualified_name
,
186 std::vector
<ConstString
> &mangled_names
) override
;
188 uint64_t GetDebugInfoSize(bool load_all_debug_info
= false) override
;
190 void FindTypes(const lldb_private::TypeQuery
&match
,
191 lldb_private::TypeResults
&results
) override
;
193 void GetTypes(SymbolContextScope
*sc_scope
, lldb::TypeClass type_mask
,
194 TypeList
&type_list
) override
;
196 llvm::Expected
<lldb::TypeSystemSP
>
197 GetTypeSystemForLanguage(lldb::LanguageType language
) override
;
199 CompilerDeclContext
FindNamespace(ConstString name
,
200 const CompilerDeclContext
&parent_decl_ctx
,
201 bool only_root_namespaces
) override
;
203 void PreloadSymbols() override
;
205 std::recursive_mutex
&GetModuleMutex() const override
;
207 // PluginInterface protocol
208 llvm::StringRef
GetPluginName() override
{ return GetPluginNameStatic(); }
210 llvm::DWARFDebugAbbrev
*DebugAbbrev();
212 DWARFDebugInfo
&DebugInfo();
214 static bool SupportedVersion(uint16_t version
);
217 GetDeclContextDIEContainingDIE(const DWARFDIE
&die
);
219 bool HasForwardDeclForCompilerType(const CompilerType
&compiler_type
);
221 CompileUnit
*GetCompUnitForDWARFCompUnit(DWARFCompileUnit
&dwarf_cu
);
223 virtual void GetObjCMethods(ConstString class_name
,
224 llvm::function_ref
<bool(DWARFDIE die
)> callback
);
226 bool Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit
*cu
);
228 DebugMacrosSP
ParseDebugMacros(lldb::offset_t
*offset
);
230 static DWARFDIE
GetParentSymbolContextDIE(const DWARFDIE
&die
);
232 lldb::ModuleSP
GetExternalModule(ConstString name
);
234 typedef std::map
<ConstString
, lldb::ModuleSP
> ExternalTypeModuleMap
;
236 /// Return the list of Clang modules imported by this SymbolFile.
237 const ExternalTypeModuleMap
&getExternalTypeModules() const {
238 return m_external_type_modules
;
241 /// Given a DIERef, find the correct SymbolFileDWARF.
243 /// A DIERef contains a file index that can uniquely identify a N_OSO file for
244 /// DWARF in .o files on mac, or a .dwo or .dwp file index for split DWARF.
245 /// Calling this function will find the correct symbol file to use so that
246 /// further lookups can be done on the correct symbol file so that the DIE
247 /// offset makes sense in the DIERef.
248 virtual SymbolFileDWARF
*GetDIERefSymbolFile(const DIERef
&die_ref
);
250 virtual DWARFDIE
GetDIE(const DIERef
&die_ref
);
252 DWARFDIE
GetDIE(lldb::user_id_t uid
);
254 std::shared_ptr
<SymbolFileDWARFDwo
>
255 GetDwoSymbolFileForCompileUnit(DWARFUnit
&dwarf_cu
,
256 const DWARFDebugInfoEntry
&cu_die
);
258 /// If this is a DWARF object with a single CU, return its DW_AT_dwo_id.
259 std::optional
<uint64_t> GetDWOId();
261 /// Given a DWO DWARFUnit, find the corresponding skeleton DWARFUnit
262 /// in the main symbol file. DWP files can have their DWARFUnits
263 /// parsed without the skeleton compile units having been parsed, so
264 /// sometimes we need to find the skeleton compile unit for a DWO
265 /// DWARFUnit so we can fill in this link. Currently unless the
266 /// skeleton compile unit has been parsed _and_ the Unit DIE has been
267 /// parsed, the DWO unit will not have a backward link setup correctly
268 /// which was causing crashes due to an assertion that was firing
269 /// in SymbolFileDWARF::GetCompUnitForDWARFCompUnit().
270 DWARFUnit
*GetSkeletonUnit(DWARFUnit
*dwo_unit
);
272 static bool DIEInDeclContext(const CompilerDeclContext
&parent_decl_ctx
,
274 bool only_root_namespaces
= false);
276 std::vector
<std::unique_ptr
<CallEdge
>>
277 ParseCallEdgesInFunction(UserID func_id
) override
;
279 void Dump(Stream
&s
) override
;
281 void DumpClangAST(Stream
&s
) override
;
283 /// List separate dwo files.
284 bool GetSeparateDebugInfo(StructuredData::Dictionary
&d
,
285 bool errors_only
) override
;
287 DWARFContext
&GetDWARFContext() { return m_context
; }
289 const std::shared_ptr
<SymbolFileDWARFDwo
> &GetDwpSymbolFile();
291 FileSpec
GetFile(DWARFUnit
&unit
, size_t file_idx
);
293 static llvm::Expected
<lldb::TypeSystemSP
> GetTypeSystem(DWARFUnit
&unit
);
295 static DWARFASTParser
*GetDWARFParser(DWARFUnit
&unit
);
297 // CompilerDecl related functions
299 static CompilerDecl
GetDecl(const DWARFDIE
&die
);
301 static CompilerDeclContext
GetDeclContext(const DWARFDIE
&die
);
303 static CompilerDeclContext
GetContainingDeclContext(const DWARFDIE
&die
);
305 static lldb::LanguageType
LanguageTypeFromDWARF(uint64_t val
);
307 static lldb::LanguageType
GetLanguage(DWARFUnit
&unit
);
308 /// Same as GetLanguage() but reports all C++ versions as C++ (no version).
309 static lldb::LanguageType
GetLanguageFamily(DWARFUnit
&unit
);
311 StatsDuration::Duration
GetDebugInfoParseTime() override
{
314 StatsDuration::Duration
GetDebugInfoIndexTime() override
;
316 StatsDuration
&GetDebugInfoParseTimeRef() { return m_parse_time
; }
318 void ResetStatistics() override
;
320 virtual lldb::offset_t
321 GetVendorDWARFOpcodeSize(const DataExtractor
&data
,
322 const lldb::offset_t data_offset
,
323 const uint8_t op
) const {
324 return LLDB_INVALID_OFFSET
;
327 virtual bool ParseVendorDWARFOpcode(uint8_t op
, const DataExtractor
&opcodes
,
328 lldb::offset_t
&offset
,
329 std::vector
<Value
> &stack
) const {
333 ConstString
ConstructFunctionDemangledName(const DWARFDIE
&die
);
335 std::optional
<uint64_t> GetFileIndex() const { return m_file_index
; }
336 void SetFileIndex(std::optional
<uint64_t> file_index
) {
337 m_file_index
= file_index
;
340 typedef llvm::DenseMap
<const DWARFDebugInfoEntry
*, Type
*> DIEToTypePtr
;
342 virtual DIEToTypePtr
&GetDIEToType() { return m_die_to_type
; }
344 virtual llvm::DenseMap
<lldb::opaque_compiler_type_t
, DIERef
> &
345 GetForwardDeclCompilerTypeToDIE();
347 typedef llvm::DenseMap
<const DWARFDebugInfoEntry
*, lldb::VariableSP
>
350 virtual DIEToVariableSP
&GetDIEToVariable() { return m_die_to_variable_sp
; }
352 virtual UniqueDWARFASTTypeMap
&GetUniqueDWARFASTTypeMap();
354 bool ClassOrStructIsVirtual(const DWARFDIE
&die
);
356 SymbolFileDWARFDebugMap
*GetDebugMapSymfile();
358 virtual DWARFDIE
FindDefinitionDIE(const DWARFDIE
&die
);
360 virtual lldb::TypeSP
FindCompleteObjCDefinitionTypeForDIE(
361 const DWARFDIE
&die
, ConstString type_name
, bool must_be_implementation
);
363 Type
*ResolveTypeUID(lldb::user_id_t type_uid
) override
;
365 Type
*ResolveTypeUID(const DWARFDIE
&die
, bool assert_not_being_parsed
);
367 Type
*ResolveTypeUID(const DIERef
&die_ref
);
369 /// Returns the DWARFIndex for this symbol, if it exists.
370 DWARFIndex
*getIndex() { return m_index
.get(); }
373 SymbolFileDWARF(const SymbolFileDWARF
&) = delete;
374 const SymbolFileDWARF
&operator=(const SymbolFileDWARF
&) = delete;
376 virtual void LoadSectionData(lldb::SectionType sect_type
,
377 DWARFDataExtractor
&data
);
379 bool DeclContextMatchesThisSymbolFile(const CompilerDeclContext
&decl_ctx
);
381 uint32_t CalculateNumCompileUnits() override
;
383 lldb::CompUnitSP
ParseCompileUnitAtIndex(uint32_t index
) override
;
385 TypeList
&GetTypeList() override
;
387 lldb::CompUnitSP
ParseCompileUnit(DWARFCompileUnit
&dwarf_cu
);
389 virtual DWARFCompileUnit
*GetDWARFCompileUnit(CompileUnit
*comp_unit
);
391 DWARFUnit
*GetNextUnparsedDWARFCompileUnit(DWARFUnit
*prev_cu
);
393 bool GetFunction(const DWARFDIE
&die
, SymbolContext
&sc
);
395 Function
*ParseFunction(CompileUnit
&comp_unit
, const DWARFDIE
&die
);
397 size_t ParseBlocksRecursive(CompileUnit
&comp_unit
, Block
*parent_block
,
399 lldb::addr_t subprogram_low_pc
, uint32_t depth
);
401 size_t ParseTypes(const SymbolContext
&sc
, const DWARFDIE
&die
,
402 bool parse_siblings
, bool parse_children
);
404 lldb::TypeSP
ParseType(const SymbolContext
&sc
, const DWARFDIE
&die
,
407 bool ParseSupportFiles(DWARFUnit
&dwarf_cu
, const lldb::ModuleSP
&module
,
408 SupportFileList
&support_files
);
410 lldb::VariableSP
ParseVariableDIE(const SymbolContext
&sc
,
412 const lldb::addr_t func_low_pc
);
413 lldb::VariableSP
ParseVariableDIECached(const SymbolContext
&sc
,
414 const DWARFDIE
&die
);
416 void ParseAndAppendGlobalVariable(const SymbolContext
&sc
,
418 VariableList
&cc_variable_list
);
420 size_t ParseVariablesInFunctionContext(const SymbolContext
&sc
,
422 const lldb::addr_t func_low_pc
);
424 size_t ParseVariablesInFunctionContextRecursive(const SymbolContext
&sc
,
426 lldb::addr_t func_low_pc
,
427 DIEArray
&accumulator
);
429 size_t PopulateBlockVariableList(VariableList
&variable_list
,
430 const SymbolContext
&sc
,
431 llvm::ArrayRef
<DIERef
> variable_dies
,
432 lldb::addr_t func_low_pc
);
434 DIEArray
MergeBlockAbstractParameters(const DWARFDIE
&block_die
,
435 DIEArray
&&variable_dies
);
437 // Given a die_offset, figure out the symbol context representing that die.
438 bool ResolveFunction(const DWARFDIE
&die
, bool include_inlines
,
439 SymbolContextList
&sc_list
);
441 /// Resolve functions and (possibly) blocks for the given file address and a
442 /// compile unit. The compile unit comes from the sc argument and it must be
443 /// set. The results of the lookup (if any) are written back to the symbol
445 void ResolveFunctionAndBlock(lldb::addr_t file_vm_addr
, bool lookup_block
,
448 Symbol
*GetObjCClassSymbol(ConstString objc_class_name
);
450 lldb::TypeSP
GetTypeForDIE(const DWARFDIE
&die
,
451 bool resolve_function_context
= false);
453 void SetDebugMapModule(const lldb::ModuleSP
&module_sp
) {
454 m_debug_map_module_wp
= module_sp
;
458 FindBlockContainingSpecification(const DIERef
&func_die_ref
,
459 dw_offset_t spec_block_die_offset
);
462 FindBlockContainingSpecification(const DWARFDIE
&die
,
463 dw_offset_t spec_block_die_offset
);
465 bool ClassContainsSelector(const DWARFDIE
&class_die
, ConstString selector
);
467 /// Parse call site entries (DW_TAG_call_site), including any nested call site
468 /// parameters (DW_TAG_call_site_parameter).
469 std::vector
<std::unique_ptr
<CallEdge
>>
470 CollectCallEdges(lldb::ModuleSP module
, DWARFDIE function_die
);
472 /// If this symbol file is linked to by a debug map (see
473 /// SymbolFileDWARFDebugMap), and \p file_addr is a file address relative to
474 /// an object file, adjust \p file_addr so that it is relative to the main
475 /// binary. Returns the adjusted address, or \p file_addr if no adjustment is
476 /// needed, on success and LLDB_INVALID_ADDRESS otherwise.
477 lldb::addr_t
FixupAddress(lldb::addr_t file_addr
);
479 bool FixupAddress(Address
&addr
);
481 typedef llvm::SetVector
<Type
*> TypeSet
;
483 void GetTypes(const DWARFDIE
&die
, dw_offset_t min_die_offset
,
484 dw_offset_t max_die_offset
, uint32_t type_mask
,
487 typedef RangeDataVector
<lldb::addr_t
, lldb::addr_t
, Variable
*>
490 GlobalVariableMap
&GetGlobalAranges();
492 void UpdateExternalModuleListIfNeeded();
494 void BuildCuTranslationTable();
495 std::optional
<uint32_t> GetDWARFUnitIndex(uint32_t cu_idx
);
497 void FindDwpSymbolFile();
499 const SupportFileList
*GetTypeUnitSupportFiles(DWARFTypeUnit
&tu
);
501 void InitializeFirstCodeAddressRecursive(const SectionList
§ion_list
);
503 void InitializeFirstCodeAddress();
506 GetCompileOptions(std::unordered_map
<lldb::CompUnitSP
, Args
> &args
) override
;
508 lldb::ModuleWP m_debug_map_module_wp
;
509 SymbolFileDWARFDebugMap
*m_debug_map_symfile
;
511 llvm::once_flag m_dwp_symfile_once_flag
;
512 std::shared_ptr
<SymbolFileDWARFDwo
> m_dwp_symfile
;
514 DWARFContext m_context
;
516 llvm::once_flag m_info_once_flag
;
517 std::unique_ptr
<DWARFDebugInfo
> m_info
;
519 std::unique_ptr
<llvm::DWARFDebugAbbrev
> m_abbr
;
520 std::unique_ptr
<GlobalVariableMap
> m_global_aranges_up
;
522 typedef std::unordered_map
<lldb::offset_t
, DebugMacrosSP
> DebugMacrosMap
;
523 DebugMacrosMap m_debug_macros_map
;
525 ExternalTypeModuleMap m_external_type_modules
;
526 std::unique_ptr
<DWARFIndex
> m_index
;
527 bool m_fetched_external_modules
: 1;
528 LazyBool m_supports_DW_AT_APPLE_objc_complete_type
;
530 typedef std::set
<DIERef
> DIERefSet
;
531 typedef llvm::StringMap
<DIERefSet
> NameToOffsetMap
;
532 NameToOffsetMap m_function_scope_qualified_name_map
;
533 UniqueDWARFASTTypeMap m_unique_ast_type_map
;
534 // A map from DIE to lldb_private::Type. For record type, the key might be
535 // either declaration DIE or definition DIE.
536 DIEToTypePtr m_die_to_type
;
537 DIEToVariableSP m_die_to_variable_sp
;
538 // A map from CompilerType to the struct/class/union/enum DIE (might be a
539 // declaration or a definition) that is used to construct it.
540 llvm::DenseMap
<lldb::opaque_compiler_type_t
, DIERef
>
541 m_forward_decl_compiler_type_to_die
;
542 llvm::DenseMap
<dw_offset_t
, std::unique_ptr
<SupportFileList
>>
543 m_type_unit_support_files
;
544 std::vector
<uint32_t> m_lldb_cu_to_dwarf_unit
;
545 /// DWARF does not provide a good way for traditional (concatenating) linkers
546 /// to invalidate debug info describing dead-stripped code. These linkers will
547 /// keep the debug info but resolve any addresses referring to such code as
548 /// zero (BFD) or a small positive integer (zero + relocation addend -- GOLD).
549 /// Try to filter out this debug info by comparing it to the lowest code
550 /// address in the module.
551 lldb::addr_t m_first_code_address
= LLDB_INVALID_ADDRESS
;
552 StatsDuration m_parse_time
;
553 std::atomic_flag m_dwo_warning_issued
= ATOMIC_FLAG_INIT
;
554 /// If this DWARF file a .DWO file or a DWARF .o file on mac when
555 /// no dSYM file is being used, this file index will be set to a
556 /// valid value that can be used in DIERef objects which will contain
557 /// an index that identifies the .DWO or .o file.
558 std::optional
<uint64_t> m_file_index
;
561 } // namespace lldb_private::plugin
563 #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H