1 //===-- SymbolFileOnDemand.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 "lldb/Symbol/SymbolFileOnDemand.h"
11 #include "lldb/Core/Module.h"
12 #include "lldb/Symbol/SymbolFile.h"
18 using namespace lldb_private
;
20 char SymbolFileOnDemand::ID
;
22 SymbolFileOnDemand::SymbolFileOnDemand(
23 std::unique_ptr
<SymbolFile
> &&symbol_file
)
24 : m_sym_file_impl(std::move(symbol_file
)) {}
26 SymbolFileOnDemand::~SymbolFileOnDemand() = default;
28 uint32_t SymbolFileOnDemand::CalculateAbilities() {
29 // Explicitly allow ability checking to pass though.
30 // This should be a cheap operation.
31 return m_sym_file_impl
->CalculateAbilities();
34 std::recursive_mutex
&SymbolFileOnDemand::GetModuleMutex() const {
35 return m_sym_file_impl
->GetModuleMutex();
38 void SymbolFileOnDemand::InitializeObject() {
39 if (!m_debug_info_enabled
) {
40 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
44 return m_sym_file_impl
->InitializeObject();
47 lldb::LanguageType
SymbolFileOnDemand::ParseLanguage(CompileUnit
&comp_unit
) {
48 if (!m_debug_info_enabled
) {
50 LLDB_LOG(log
, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__
);
52 lldb::LanguageType langType
= m_sym_file_impl
->ParseLanguage(comp_unit
);
53 if (langType
!= eLanguageTypeUnknown
)
54 LLDB_LOG(log
, "Language {0} would return if hydrated.", langType
);
56 return eLanguageTypeUnknown
;
58 return m_sym_file_impl
->ParseLanguage(comp_unit
);
61 XcodeSDK
SymbolFileOnDemand::ParseXcodeSDK(CompileUnit
&comp_unit
) {
62 if (!m_debug_info_enabled
) {
64 LLDB_LOG(log
, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__
);
65 XcodeSDK defaultValue
{};
67 XcodeSDK sdk
= m_sym_file_impl
->ParseXcodeSDK(comp_unit
);
68 if (!(sdk
== defaultValue
))
69 LLDB_LOG(log
, "SDK {0} would return if hydrated.", sdk
.GetString());
73 return m_sym_file_impl
->ParseXcodeSDK(comp_unit
);
76 size_t SymbolFileOnDemand::ParseFunctions(CompileUnit
&comp_unit
) {
77 if (!m_debug_info_enabled
) {
78 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
82 return m_sym_file_impl
->ParseFunctions(comp_unit
);
85 bool SymbolFileOnDemand::ParseLineTable(CompileUnit
&comp_unit
) {
86 if (!m_debug_info_enabled
) {
87 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
91 return m_sym_file_impl
->ParseLineTable(comp_unit
);
94 bool SymbolFileOnDemand::ParseDebugMacros(CompileUnit
&comp_unit
) {
95 if (!m_debug_info_enabled
) {
96 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
100 return m_sym_file_impl
->ParseDebugMacros(comp_unit
);
103 bool SymbolFileOnDemand::ForEachExternalModule(
104 CompileUnit
&comp_unit
,
105 llvm::DenseSet
<lldb_private::SymbolFile
*> &visited_symbol_files
,
106 llvm::function_ref
<bool(Module
&)> lambda
) {
107 if (!m_debug_info_enabled
) {
108 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
110 // Return false to not early exit.
113 return m_sym_file_impl
->ForEachExternalModule(comp_unit
, visited_symbol_files
,
117 bool SymbolFileOnDemand::ParseSupportFiles(CompileUnit
&comp_unit
,
118 FileSpecList
&support_files
) {
120 "[{0}] {1} is not skipped: explicitly allowed to support breakpoint",
121 GetSymbolFileName(), __FUNCTION__
);
122 // Explicitly allow this API through to support source line breakpoint.
123 return m_sym_file_impl
->ParseSupportFiles(comp_unit
, support_files
);
126 bool SymbolFileOnDemand::ParseIsOptimized(CompileUnit
&comp_unit
) {
127 if (!m_debug_info_enabled
) {
129 LLDB_LOG(log
, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__
);
131 bool optimized
= m_sym_file_impl
->ParseIsOptimized(comp_unit
);
133 LLDB_LOG(log
, "Would return optimized if hydrated.");
138 return m_sym_file_impl
->ParseIsOptimized(comp_unit
);
141 size_t SymbolFileOnDemand::ParseTypes(CompileUnit
&comp_unit
) {
142 if (!m_debug_info_enabled
) {
143 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
147 return m_sym_file_impl
->ParseTypes(comp_unit
);
150 bool SymbolFileOnDemand::ParseImportedModules(
151 const lldb_private::SymbolContext
&sc
,
152 std::vector
<SourceModule
> &imported_modules
) {
153 if (!m_debug_info_enabled
) {
155 LLDB_LOG(log
, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__
);
157 std::vector
<SourceModule
> tmp_imported_modules
;
159 m_sym_file_impl
->ParseImportedModules(sc
, tmp_imported_modules
);
161 LLDB_LOG(log
, "{0} imported modules would be parsed if hydrated.",
162 tmp_imported_modules
.size());
166 return m_sym_file_impl
->ParseImportedModules(sc
, imported_modules
);
169 size_t SymbolFileOnDemand::ParseBlocksRecursive(Function
&func
) {
170 if (!m_debug_info_enabled
) {
171 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
175 return m_sym_file_impl
->ParseBlocksRecursive(func
);
178 size_t SymbolFileOnDemand::ParseVariablesForContext(const SymbolContext
&sc
) {
179 if (!m_debug_info_enabled
) {
180 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
184 return m_sym_file_impl
->ParseVariablesForContext(sc
);
187 Type
*SymbolFileOnDemand::ResolveTypeUID(lldb::user_id_t type_uid
) {
188 if (!m_debug_info_enabled
) {
190 LLDB_LOG(log
, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__
);
192 Type
*resolved_type
= m_sym_file_impl
->ResolveTypeUID(type_uid
);
194 LLDB_LOG(log
, "Type would be parsed for {0} if hydrated.", type_uid
);
198 return m_sym_file_impl
->ResolveTypeUID(type_uid
);
201 std::optional
<SymbolFile::ArrayInfo
>
202 SymbolFileOnDemand::GetDynamicArrayInfoForUID(
203 lldb::user_id_t type_uid
, const lldb_private::ExecutionContext
*exe_ctx
) {
204 if (!m_debug_info_enabled
) {
205 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
209 return m_sym_file_impl
->GetDynamicArrayInfoForUID(type_uid
, exe_ctx
);
212 bool SymbolFileOnDemand::CompleteType(CompilerType
&compiler_type
) {
213 if (!m_debug_info_enabled
) {
214 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
218 return m_sym_file_impl
->CompleteType(compiler_type
);
221 CompilerDecl
SymbolFileOnDemand::GetDeclForUID(lldb::user_id_t type_uid
) {
222 if (!m_debug_info_enabled
) {
224 LLDB_LOG(log
, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__
);
226 CompilerDecl parsed_decl
= m_sym_file_impl
->GetDeclForUID(type_uid
);
227 if (parsed_decl
!= CompilerDecl()) {
228 LLDB_LOG(log
, "CompilerDecl {0} would be parsed for {1} if hydrated.",
229 parsed_decl
.GetName(), type_uid
);
232 return CompilerDecl();
234 return m_sym_file_impl
->GetDeclForUID(type_uid
);
238 SymbolFileOnDemand::GetDeclContextForUID(lldb::user_id_t type_uid
) {
239 if (!m_debug_info_enabled
) {
240 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
242 return CompilerDeclContext();
244 return m_sym_file_impl
->GetDeclContextForUID(type_uid
);
248 SymbolFileOnDemand::GetDeclContextContainingUID(lldb::user_id_t type_uid
) {
249 if (!m_debug_info_enabled
) {
250 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
252 return CompilerDeclContext();
254 return m_sym_file_impl
->GetDeclContextContainingUID(type_uid
);
257 void SymbolFileOnDemand::ParseDeclsForContext(CompilerDeclContext decl_ctx
) {
258 if (!m_debug_info_enabled
) {
259 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
263 return m_sym_file_impl
->ParseDeclsForContext(decl_ctx
);
267 SymbolFileOnDemand::ResolveSymbolContext(const Address
&so_addr
,
268 SymbolContextItem resolve_scope
,
270 if (!m_debug_info_enabled
) {
271 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
275 return m_sym_file_impl
->ResolveSymbolContext(so_addr
, resolve_scope
, sc
);
278 Status
SymbolFileOnDemand::CalculateFrameVariableError(StackFrame
&frame
) {
279 if (!m_debug_info_enabled
) {
280 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
284 return m_sym_file_impl
->CalculateFrameVariableError(frame
);
287 uint32_t SymbolFileOnDemand::ResolveSymbolContext(
288 const SourceLocationSpec
&src_location_spec
,
289 SymbolContextItem resolve_scope
, SymbolContextList
&sc_list
) {
290 if (!m_debug_info_enabled
) {
291 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
295 return m_sym_file_impl
->ResolveSymbolContext(src_location_spec
, resolve_scope
,
299 void SymbolFileOnDemand::Dump(lldb_private::Stream
&s
) {
300 if (!m_debug_info_enabled
) {
301 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
305 return m_sym_file_impl
->Dump(s
);
308 void SymbolFileOnDemand::DumpClangAST(lldb_private::Stream
&s
) {
309 if (!m_debug_info_enabled
) {
310 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
314 return m_sym_file_impl
->DumpClangAST(s
);
317 void SymbolFileOnDemand::FindGlobalVariables(const RegularExpression
®ex
,
318 uint32_t max_matches
,
319 VariableList
&variables
) {
320 if (!m_debug_info_enabled
) {
321 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
325 return m_sym_file_impl
->FindGlobalVariables(regex
, max_matches
, variables
);
328 void SymbolFileOnDemand::FindGlobalVariables(
329 ConstString name
, const CompilerDeclContext
&parent_decl_ctx
,
330 uint32_t max_matches
, VariableList
&variables
) {
331 if (!m_debug_info_enabled
) {
333 Symtab
*symtab
= GetSymtab();
335 LLDB_LOG(log
, "[{0}] {1} is skipped - fail to get symtab",
336 GetSymbolFileName(), __FUNCTION__
);
339 Symbol
*sym
= symtab
->FindFirstSymbolWithNameAndType(
340 name
, eSymbolTypeData
, Symtab::eDebugAny
, Symtab::eVisibilityAny
);
342 LLDB_LOG(log
, "[{0}] {1} is skipped - fail to find match in symtab",
343 GetSymbolFileName(), __FUNCTION__
);
346 LLDB_LOG(log
, "[{0}] {1} is NOT skipped - found match in symtab",
347 GetSymbolFileName(), __FUNCTION__
);
349 // Found match in symbol table hydrate debug info and
350 // allow the FindGlobalVariables to go through.
351 SetLoadDebugInfoEnabled();
353 return m_sym_file_impl
->FindGlobalVariables(name
, parent_decl_ctx
,
354 max_matches
, variables
);
357 void SymbolFileOnDemand::FindFunctions(const RegularExpression
®ex
,
358 bool include_inlines
,
359 SymbolContextList
&sc_list
) {
360 if (!m_debug_info_enabled
) {
362 Symtab
*symtab
= GetSymtab();
364 LLDB_LOG(log
, "[{0}] {1} is skipped - fail to get symtab",
365 GetSymbolFileName(), __FUNCTION__
);
368 std::vector
<uint32_t> symbol_indexes
;
369 symtab
->AppendSymbolIndexesMatchingRegExAndType(
370 regex
, eSymbolTypeAny
, Symtab::eDebugAny
, Symtab::eVisibilityAny
,
372 if (symbol_indexes
.empty()) {
373 LLDB_LOG(log
, "[{0}] {1} is skipped - fail to find match in symtab",
374 GetSymbolFileName(), __FUNCTION__
);
377 LLDB_LOG(log
, "[{0}] {1} is NOT skipped - found match in symtab",
378 GetSymbolFileName(), __FUNCTION__
);
380 // Found match in symbol table hydrate debug info and
381 // allow the FindFucntions to go through.
382 SetLoadDebugInfoEnabled();
384 return m_sym_file_impl
->FindFunctions(regex
, include_inlines
, sc_list
);
387 void SymbolFileOnDemand::FindFunctions(
388 const Module::LookupInfo
&lookup_info
,
389 const CompilerDeclContext
&parent_decl_ctx
, bool include_inlines
,
390 SymbolContextList
&sc_list
) {
391 ConstString name
= lookup_info
.GetLookupName();
392 FunctionNameType name_type_mask
= lookup_info
.GetNameTypeMask();
393 if (!m_debug_info_enabled
) {
396 Symtab
*symtab
= GetSymtab();
398 LLDB_LOG(log
, "[{0}] {1}({2}) is skipped - fail to get symtab",
399 GetSymbolFileName(), __FUNCTION__
, name
);
403 SymbolContextList sc_list_helper
;
404 symtab
->FindFunctionSymbols(name
, name_type_mask
, sc_list_helper
);
405 if (sc_list_helper
.GetSize() == 0) {
406 LLDB_LOG(log
, "[{0}] {1}({2}) is skipped - fail to find match in symtab",
407 GetSymbolFileName(), __FUNCTION__
, name
);
410 LLDB_LOG(log
, "[{0}] {1}({2}) is NOT skipped - found match in symtab",
411 GetSymbolFileName(), __FUNCTION__
, name
);
413 // Found match in symbol table hydrate debug info and
414 // allow the FindFucntions to go through.
415 SetLoadDebugInfoEnabled();
417 return m_sym_file_impl
->FindFunctions(lookup_info
, parent_decl_ctx
,
418 include_inlines
, sc_list
);
421 void SymbolFileOnDemand::GetMangledNamesForFunction(
422 const std::string
&scope_qualified_name
,
423 std::vector
<ConstString
> &mangled_names
) {
424 if (!m_debug_info_enabled
) {
426 LLDB_LOG(log
, "[{0}] {1}({2}) is skipped", GetSymbolFileName(),
427 __FUNCTION__
, scope_qualified_name
);
430 return m_sym_file_impl
->GetMangledNamesForFunction(scope_qualified_name
,
434 void SymbolFileOnDemand::FindTypes(
435 ConstString name
, const CompilerDeclContext
&parent_decl_ctx
,
436 uint32_t max_matches
,
437 llvm::DenseSet
<lldb_private::SymbolFile
*> &searched_symbol_files
,
439 if (!m_debug_info_enabled
) {
441 LLDB_LOG(log
, "[{0}] {1}({2}) is skipped", GetSymbolFileName(),
445 return m_sym_file_impl
->FindTypes(name
, parent_decl_ctx
, max_matches
,
446 searched_symbol_files
, types
);
449 void SymbolFileOnDemand::FindTypes(
450 llvm::ArrayRef
<CompilerContext
> pattern
, LanguageSet languages
,
451 llvm::DenseSet
<SymbolFile
*> &searched_symbol_files
, TypeMap
&types
) {
452 if (!m_debug_info_enabled
) {
453 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
457 return m_sym_file_impl
->FindTypes(pattern
, languages
, searched_symbol_files
,
461 void SymbolFileOnDemand::GetTypes(SymbolContextScope
*sc_scope
,
462 TypeClass type_mask
, TypeList
&type_list
) {
463 if (!m_debug_info_enabled
) {
464 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
468 return m_sym_file_impl
->GetTypes(sc_scope
, type_mask
, type_list
);
471 llvm::Expected
<lldb::TypeSystemSP
>
472 SymbolFileOnDemand::GetTypeSystemForLanguage(LanguageType language
) {
473 if (!m_debug_info_enabled
) {
475 LLDB_LOG(log
, "[{0}] {1} is skipped for language type {2}",
476 GetSymbolFileName(), __FUNCTION__
, language
);
477 return llvm::make_error
<llvm::StringError
>(
478 "GetTypeSystemForLanguage is skipped by SymbolFileOnDemand",
479 llvm::inconvertibleErrorCode());
481 return m_sym_file_impl
->GetTypeSystemForLanguage(language
);
485 SymbolFileOnDemand::FindNamespace(ConstString name
,
486 const CompilerDeclContext
&parent_decl_ctx
,
487 bool only_root_namespaces
) {
488 if (!m_debug_info_enabled
) {
489 LLDB_LOG(GetLog(), "[{0}] {1}({2}) is skipped", GetSymbolFileName(),
491 return SymbolFile::FindNamespace(name
, parent_decl_ctx
,
492 only_root_namespaces
);
494 return m_sym_file_impl
->FindNamespace(name
, parent_decl_ctx
,
495 only_root_namespaces
);
498 std::vector
<std::unique_ptr
<lldb_private::CallEdge
>>
499 SymbolFileOnDemand::ParseCallEdgesInFunction(UserID func_id
) {
500 if (!m_debug_info_enabled
) {
502 LLDB_LOG(log
, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__
);
504 std::vector
<std::unique_ptr
<lldb_private::CallEdge
>> call_edges
=
505 m_sym_file_impl
->ParseCallEdgesInFunction(func_id
);
506 if (call_edges
.size() > 0) {
507 LLDB_LOG(log
, "{0} call edges would be parsed for {1} if hydrated.",
508 call_edges
.size(), func_id
.GetID());
513 return m_sym_file_impl
->ParseCallEdgesInFunction(func_id
);
517 SymbolFileOnDemand::GetUnwindPlan(const Address
&address
,
518 const RegisterInfoResolver
&resolver
) {
519 if (!m_debug_info_enabled
) {
520 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
524 return m_sym_file_impl
->GetUnwindPlan(address
, resolver
);
527 llvm::Expected
<lldb::addr_t
>
528 SymbolFileOnDemand::GetParameterStackSize(Symbol
&symbol
) {
529 if (!m_debug_info_enabled
) {
531 LLDB_LOG(log
, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__
);
533 llvm::Expected
<lldb::addr_t
> stack_size
=
534 m_sym_file_impl
->GetParameterStackSize(symbol
);
536 LLDB_LOG(log
, "{0} stack size would return for symbol {1} if hydrated.",
537 *stack_size
, symbol
.GetName());
540 return SymbolFile::GetParameterStackSize(symbol
);
542 return m_sym_file_impl
->GetParameterStackSize(symbol
);
545 void SymbolFileOnDemand::PreloadSymbols() {
546 m_preload_symbols
= true;
547 if (!m_debug_info_enabled
) {
548 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
552 return m_sym_file_impl
->PreloadSymbols();
555 uint64_t SymbolFileOnDemand::GetDebugInfoSize() {
556 // Always return the real debug info size.
557 LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
559 return m_sym_file_impl
->GetDebugInfoSize();
562 StatsDuration::Duration
SymbolFileOnDemand::GetDebugInfoParseTime() {
563 // Always return the real parse time.
564 LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
566 return m_sym_file_impl
->GetDebugInfoParseTime();
569 StatsDuration::Duration
SymbolFileOnDemand::GetDebugInfoIndexTime() {
570 // Always return the real index time.
571 LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
573 return m_sym_file_impl
->GetDebugInfoIndexTime();
576 void SymbolFileOnDemand::SetLoadDebugInfoEnabled() {
577 if (m_debug_info_enabled
)
579 LLDB_LOG(GetLog(), "[{0}] Hydrate debug info", GetSymbolFileName());
580 m_debug_info_enabled
= true;
582 if (m_preload_symbols
)
586 uint32_t SymbolFileOnDemand::GetNumCompileUnits() {
587 LLDB_LOG(GetLog(), "[{0}] {1} is not skipped to support breakpoint hydration",
588 GetSymbolFileName(), __FUNCTION__
);
589 return m_sym_file_impl
->GetNumCompileUnits();
592 CompUnitSP
SymbolFileOnDemand::GetCompileUnitAtIndex(uint32_t idx
) {
593 LLDB_LOG(GetLog(), "[{0}] {1} is not skipped to support breakpoint hydration",
594 GetSymbolFileName(), __FUNCTION__
);
595 return m_sym_file_impl
->GetCompileUnitAtIndex(idx
);
598 uint32_t SymbolFileOnDemand::GetAbilities() {
599 if (!m_debug_info_enabled
) {
600 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
604 return m_sym_file_impl
->GetAbilities();