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 SupportFileList
&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(const TypeQuery
&match
,
435 TypeResults
&results
) {
436 if (!m_debug_info_enabled
) {
437 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
441 return m_sym_file_impl
->FindTypes(match
, results
);
444 void SymbolFileOnDemand::GetTypes(SymbolContextScope
*sc_scope
,
445 TypeClass type_mask
, TypeList
&type_list
) {
446 if (!m_debug_info_enabled
) {
447 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
451 return m_sym_file_impl
->GetTypes(sc_scope
, type_mask
, type_list
);
454 llvm::Expected
<lldb::TypeSystemSP
>
455 SymbolFileOnDemand::GetTypeSystemForLanguage(LanguageType language
) {
456 if (!m_debug_info_enabled
) {
458 LLDB_LOG(log
, "[{0}] {1} is skipped for language type {2}",
459 GetSymbolFileName(), __FUNCTION__
, language
);
460 return llvm::createStringError(
461 "GetTypeSystemForLanguage is skipped by SymbolFileOnDemand");
463 return m_sym_file_impl
->GetTypeSystemForLanguage(language
);
467 SymbolFileOnDemand::FindNamespace(ConstString name
,
468 const CompilerDeclContext
&parent_decl_ctx
,
469 bool only_root_namespaces
) {
470 if (!m_debug_info_enabled
) {
471 LLDB_LOG(GetLog(), "[{0}] {1}({2}) is skipped", GetSymbolFileName(),
473 return SymbolFile::FindNamespace(name
, parent_decl_ctx
,
474 only_root_namespaces
);
476 return m_sym_file_impl
->FindNamespace(name
, parent_decl_ctx
,
477 only_root_namespaces
);
480 std::vector
<std::unique_ptr
<lldb_private::CallEdge
>>
481 SymbolFileOnDemand::ParseCallEdgesInFunction(UserID func_id
) {
482 if (!m_debug_info_enabled
) {
484 LLDB_LOG(log
, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__
);
486 std::vector
<std::unique_ptr
<lldb_private::CallEdge
>> call_edges
=
487 m_sym_file_impl
->ParseCallEdgesInFunction(func_id
);
488 if (call_edges
.size() > 0) {
489 LLDB_LOG(log
, "{0} call edges would be parsed for {1} if hydrated.",
490 call_edges
.size(), func_id
.GetID());
495 return m_sym_file_impl
->ParseCallEdgesInFunction(func_id
);
499 SymbolFileOnDemand::GetUnwindPlan(const Address
&address
,
500 const RegisterInfoResolver
&resolver
) {
501 if (!m_debug_info_enabled
) {
502 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
506 return m_sym_file_impl
->GetUnwindPlan(address
, resolver
);
509 llvm::Expected
<lldb::addr_t
>
510 SymbolFileOnDemand::GetParameterStackSize(Symbol
&symbol
) {
511 if (!m_debug_info_enabled
) {
513 LLDB_LOG(log
, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__
);
515 llvm::Expected
<lldb::addr_t
> stack_size
=
516 m_sym_file_impl
->GetParameterStackSize(symbol
);
518 LLDB_LOG(log
, "{0} stack size would return for symbol {1} if hydrated.",
519 *stack_size
, symbol
.GetName());
522 return SymbolFile::GetParameterStackSize(symbol
);
524 return m_sym_file_impl
->GetParameterStackSize(symbol
);
527 void SymbolFileOnDemand::PreloadSymbols() {
528 m_preload_symbols
= true;
529 if (!m_debug_info_enabled
) {
530 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
534 return m_sym_file_impl
->PreloadSymbols();
537 uint64_t SymbolFileOnDemand::GetDebugInfoSize(bool load_all_debug_info
) {
538 // Always return the real debug info size.
539 LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
541 return m_sym_file_impl
->GetDebugInfoSize(load_all_debug_info
);
544 StatsDuration::Duration
SymbolFileOnDemand::GetDebugInfoParseTime() {
545 // Always return the real parse time.
546 LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
548 return m_sym_file_impl
->GetDebugInfoParseTime();
551 StatsDuration::Duration
SymbolFileOnDemand::GetDebugInfoIndexTime() {
552 // Always return the real index time.
553 LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
555 return m_sym_file_impl
->GetDebugInfoIndexTime();
558 void SymbolFileOnDemand::ResetStatistics() {
559 LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
561 return m_sym_file_impl
->ResetStatistics();
564 void SymbolFileOnDemand::SetLoadDebugInfoEnabled() {
565 if (m_debug_info_enabled
)
567 LLDB_LOG(GetLog(), "[{0}] Hydrate debug info", GetSymbolFileName());
568 m_debug_info_enabled
= true;
570 if (m_preload_symbols
)
574 uint32_t SymbolFileOnDemand::GetNumCompileUnits() {
575 LLDB_LOG(GetLog(), "[{0}] {1} is not skipped to support breakpoint hydration",
576 GetSymbolFileName(), __FUNCTION__
);
577 return m_sym_file_impl
->GetNumCompileUnits();
580 CompUnitSP
SymbolFileOnDemand::GetCompileUnitAtIndex(uint32_t idx
) {
581 LLDB_LOG(GetLog(), "[{0}] {1} is not skipped to support breakpoint hydration",
582 GetSymbolFileName(), __FUNCTION__
);
583 return m_sym_file_impl
->GetCompileUnitAtIndex(idx
);
586 uint32_t SymbolFileOnDemand::GetAbilities() {
587 if (!m_debug_info_enabled
) {
588 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
592 return m_sym_file_impl
->GetAbilities();