Path: blob/main/contrib/llvm-project/lldb/source/Symbol/SymbolFileOnDemand.cpp
39587 views
//===-- SymbolFileOnDemand.cpp ---------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Symbol/SymbolFileOnDemand.h"910#include "lldb/Core/Module.h"11#include "lldb/Symbol/SymbolFile.h"1213#include <memory>14#include <optional>1516using namespace lldb;17using namespace lldb_private;1819char SymbolFileOnDemand::ID;2021SymbolFileOnDemand::SymbolFileOnDemand(22std::unique_ptr<SymbolFile> &&symbol_file)23: m_sym_file_impl(std::move(symbol_file)) {}2425SymbolFileOnDemand::~SymbolFileOnDemand() = default;2627uint32_t SymbolFileOnDemand::CalculateAbilities() {28// Explicitly allow ability checking to pass though.29// This should be a cheap operation.30return m_sym_file_impl->CalculateAbilities();31}3233std::recursive_mutex &SymbolFileOnDemand::GetModuleMutex() const {34return m_sym_file_impl->GetModuleMutex();35}3637void SymbolFileOnDemand::InitializeObject() {38if (!m_debug_info_enabled) {39LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),40__FUNCTION__);41return;42}43return m_sym_file_impl->InitializeObject();44}4546lldb::LanguageType SymbolFileOnDemand::ParseLanguage(CompileUnit &comp_unit) {47if (!m_debug_info_enabled) {48Log *log = GetLog();49LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);50if (log) {51lldb::LanguageType langType = m_sym_file_impl->ParseLanguage(comp_unit);52if (langType != eLanguageTypeUnknown)53LLDB_LOG(log, "Language {0} would return if hydrated.", langType);54}55return eLanguageTypeUnknown;56}57return m_sym_file_impl->ParseLanguage(comp_unit);58}5960XcodeSDK SymbolFileOnDemand::ParseXcodeSDK(CompileUnit &comp_unit) {61if (!m_debug_info_enabled) {62Log *log = GetLog();63LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);64XcodeSDK defaultValue{};65if (log) {66XcodeSDK sdk = m_sym_file_impl->ParseXcodeSDK(comp_unit);67if (!(sdk == defaultValue))68LLDB_LOG(log, "SDK {0} would return if hydrated.", sdk.GetString());69}70return defaultValue;71}72return m_sym_file_impl->ParseXcodeSDK(comp_unit);73}7475size_t SymbolFileOnDemand::ParseFunctions(CompileUnit &comp_unit) {76if (!m_debug_info_enabled) {77LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),78__FUNCTION__);79return 0;80}81return m_sym_file_impl->ParseFunctions(comp_unit);82}8384bool SymbolFileOnDemand::ParseLineTable(CompileUnit &comp_unit) {85if (!m_debug_info_enabled) {86LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),87__FUNCTION__);88return false;89}90return m_sym_file_impl->ParseLineTable(comp_unit);91}9293bool SymbolFileOnDemand::ParseDebugMacros(CompileUnit &comp_unit) {94if (!m_debug_info_enabled) {95LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),96__FUNCTION__);97return false;98}99return m_sym_file_impl->ParseDebugMacros(comp_unit);100}101102bool SymbolFileOnDemand::ForEachExternalModule(103CompileUnit &comp_unit,104llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files,105llvm::function_ref<bool(Module &)> lambda) {106if (!m_debug_info_enabled) {107LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),108__FUNCTION__);109// Return false to not early exit.110return false;111}112return m_sym_file_impl->ForEachExternalModule(comp_unit, visited_symbol_files,113lambda);114}115116bool SymbolFileOnDemand::ParseSupportFiles(CompileUnit &comp_unit,117SupportFileList &support_files) {118LLDB_LOG(GetLog(),119"[{0}] {1} is not skipped: explicitly allowed to support breakpoint",120GetSymbolFileName(), __FUNCTION__);121// Explicitly allow this API through to support source line breakpoint.122return m_sym_file_impl->ParseSupportFiles(comp_unit, support_files);123}124125bool SymbolFileOnDemand::ParseIsOptimized(CompileUnit &comp_unit) {126if (!m_debug_info_enabled) {127Log *log = GetLog();128LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);129if (log) {130bool optimized = m_sym_file_impl->ParseIsOptimized(comp_unit);131if (optimized) {132LLDB_LOG(log, "Would return optimized if hydrated.");133}134}135return false;136}137return m_sym_file_impl->ParseIsOptimized(comp_unit);138}139140size_t SymbolFileOnDemand::ParseTypes(CompileUnit &comp_unit) {141if (!m_debug_info_enabled) {142LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),143__FUNCTION__);144return 0;145}146return m_sym_file_impl->ParseTypes(comp_unit);147}148149bool SymbolFileOnDemand::ParseImportedModules(150const lldb_private::SymbolContext &sc,151std::vector<SourceModule> &imported_modules) {152if (!m_debug_info_enabled) {153Log *log = GetLog();154LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);155if (log) {156std::vector<SourceModule> tmp_imported_modules;157bool succeed =158m_sym_file_impl->ParseImportedModules(sc, tmp_imported_modules);159if (succeed)160LLDB_LOG(log, "{0} imported modules would be parsed if hydrated.",161tmp_imported_modules.size());162}163return false;164}165return m_sym_file_impl->ParseImportedModules(sc, imported_modules);166}167168size_t SymbolFileOnDemand::ParseBlocksRecursive(Function &func) {169if (!m_debug_info_enabled) {170LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),171__FUNCTION__);172return 0;173}174return m_sym_file_impl->ParseBlocksRecursive(func);175}176177size_t SymbolFileOnDemand::ParseVariablesForContext(const SymbolContext &sc) {178if (!m_debug_info_enabled) {179LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),180__FUNCTION__);181return 0;182}183return m_sym_file_impl->ParseVariablesForContext(sc);184}185186Type *SymbolFileOnDemand::ResolveTypeUID(lldb::user_id_t type_uid) {187if (!m_debug_info_enabled) {188Log *log = GetLog();189LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);190if (log) {191Type *resolved_type = m_sym_file_impl->ResolveTypeUID(type_uid);192if (resolved_type)193LLDB_LOG(log, "Type would be parsed for {0} if hydrated.", type_uid);194}195return nullptr;196}197return m_sym_file_impl->ResolveTypeUID(type_uid);198}199200std::optional<SymbolFile::ArrayInfo>201SymbolFileOnDemand::GetDynamicArrayInfoForUID(202lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {203if (!m_debug_info_enabled) {204LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),205__FUNCTION__);206return std::nullopt;207}208return m_sym_file_impl->GetDynamicArrayInfoForUID(type_uid, exe_ctx);209}210211bool SymbolFileOnDemand::CompleteType(CompilerType &compiler_type) {212if (!m_debug_info_enabled) {213LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),214__FUNCTION__);215return false;216}217return m_sym_file_impl->CompleteType(compiler_type);218}219220CompilerDecl SymbolFileOnDemand::GetDeclForUID(lldb::user_id_t type_uid) {221if (!m_debug_info_enabled) {222Log *log = GetLog();223LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);224if (log) {225CompilerDecl parsed_decl = m_sym_file_impl->GetDeclForUID(type_uid);226if (parsed_decl != CompilerDecl()) {227LLDB_LOG(log, "CompilerDecl {0} would be parsed for {1} if hydrated.",228parsed_decl.GetName(), type_uid);229}230}231return CompilerDecl();232}233return m_sym_file_impl->GetDeclForUID(type_uid);234}235236CompilerDeclContext237SymbolFileOnDemand::GetDeclContextForUID(lldb::user_id_t type_uid) {238if (!m_debug_info_enabled) {239LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),240__FUNCTION__);241return CompilerDeclContext();242}243return m_sym_file_impl->GetDeclContextForUID(type_uid);244}245246CompilerDeclContext247SymbolFileOnDemand::GetDeclContextContainingUID(lldb::user_id_t type_uid) {248if (!m_debug_info_enabled) {249LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),250__FUNCTION__);251return CompilerDeclContext();252}253return m_sym_file_impl->GetDeclContextContainingUID(type_uid);254}255256void SymbolFileOnDemand::ParseDeclsForContext(CompilerDeclContext decl_ctx) {257if (!m_debug_info_enabled) {258LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),259__FUNCTION__);260return;261}262return m_sym_file_impl->ParseDeclsForContext(decl_ctx);263}264265uint32_t266SymbolFileOnDemand::ResolveSymbolContext(const Address &so_addr,267SymbolContextItem resolve_scope,268SymbolContext &sc) {269if (!m_debug_info_enabled) {270LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),271__FUNCTION__);272return 0;273}274return m_sym_file_impl->ResolveSymbolContext(so_addr, resolve_scope, sc);275}276277Status SymbolFileOnDemand::CalculateFrameVariableError(StackFrame &frame) {278if (!m_debug_info_enabled) {279LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),280__FUNCTION__);281return Status();282}283return m_sym_file_impl->CalculateFrameVariableError(frame);284}285286uint32_t SymbolFileOnDemand::ResolveSymbolContext(287const SourceLocationSpec &src_location_spec,288SymbolContextItem resolve_scope, SymbolContextList &sc_list) {289if (!m_debug_info_enabled) {290LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),291__FUNCTION__);292return 0;293}294return m_sym_file_impl->ResolveSymbolContext(src_location_spec, resolve_scope,295sc_list);296}297298void SymbolFileOnDemand::Dump(lldb_private::Stream &s) {299if (!m_debug_info_enabled) {300LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),301__FUNCTION__);302return;303}304return m_sym_file_impl->Dump(s);305}306307void SymbolFileOnDemand::DumpClangAST(lldb_private::Stream &s) {308if (!m_debug_info_enabled) {309LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),310__FUNCTION__);311return;312}313return m_sym_file_impl->DumpClangAST(s);314}315316void SymbolFileOnDemand::FindGlobalVariables(const RegularExpression ®ex,317uint32_t max_matches,318VariableList &variables) {319if (!m_debug_info_enabled) {320LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),321__FUNCTION__);322return;323}324return m_sym_file_impl->FindGlobalVariables(regex, max_matches, variables);325}326327void SymbolFileOnDemand::FindGlobalVariables(328ConstString name, const CompilerDeclContext &parent_decl_ctx,329uint32_t max_matches, VariableList &variables) {330if (!m_debug_info_enabled) {331Log *log = GetLog();332Symtab *symtab = GetSymtab();333if (!symtab) {334LLDB_LOG(log, "[{0}] {1} is skipped - fail to get symtab",335GetSymbolFileName(), __FUNCTION__);336return;337}338Symbol *sym = symtab->FindFirstSymbolWithNameAndType(339name, eSymbolTypeData, Symtab::eDebugAny, Symtab::eVisibilityAny);340if (!sym) {341LLDB_LOG(log, "[{0}] {1} is skipped - fail to find match in symtab",342GetSymbolFileName(), __FUNCTION__);343return;344}345LLDB_LOG(log, "[{0}] {1} is NOT skipped - found match in symtab",346GetSymbolFileName(), __FUNCTION__);347348// Found match in symbol table hydrate debug info and349// allow the FindGlobalVariables to go through.350SetLoadDebugInfoEnabled();351}352return m_sym_file_impl->FindGlobalVariables(name, parent_decl_ctx,353max_matches, variables);354}355356void SymbolFileOnDemand::FindFunctions(const RegularExpression ®ex,357bool include_inlines,358SymbolContextList &sc_list) {359if (!m_debug_info_enabled) {360Log *log = GetLog();361Symtab *symtab = GetSymtab();362if (!symtab) {363LLDB_LOG(log, "[{0}] {1} is skipped - fail to get symtab",364GetSymbolFileName(), __FUNCTION__);365return;366}367std::vector<uint32_t> symbol_indexes;368symtab->AppendSymbolIndexesMatchingRegExAndType(369regex, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny,370symbol_indexes);371if (symbol_indexes.empty()) {372LLDB_LOG(log, "[{0}] {1} is skipped - fail to find match in symtab",373GetSymbolFileName(), __FUNCTION__);374return;375}376LLDB_LOG(log, "[{0}] {1} is NOT skipped - found match in symtab",377GetSymbolFileName(), __FUNCTION__);378379// Found match in symbol table hydrate debug info and380// allow the FindFucntions to go through.381SetLoadDebugInfoEnabled();382}383return m_sym_file_impl->FindFunctions(regex, include_inlines, sc_list);384}385386void SymbolFileOnDemand::FindFunctions(387const Module::LookupInfo &lookup_info,388const CompilerDeclContext &parent_decl_ctx, bool include_inlines,389SymbolContextList &sc_list) {390ConstString name = lookup_info.GetLookupName();391FunctionNameType name_type_mask = lookup_info.GetNameTypeMask();392if (!m_debug_info_enabled) {393Log *log = GetLog();394395Symtab *symtab = GetSymtab();396if (!symtab) {397LLDB_LOG(log, "[{0}] {1}({2}) is skipped - fail to get symtab",398GetSymbolFileName(), __FUNCTION__, name);399return;400}401402SymbolContextList sc_list_helper;403symtab->FindFunctionSymbols(name, name_type_mask, sc_list_helper);404if (sc_list_helper.GetSize() == 0) {405LLDB_LOG(log, "[{0}] {1}({2}) is skipped - fail to find match in symtab",406GetSymbolFileName(), __FUNCTION__, name);407return;408}409LLDB_LOG(log, "[{0}] {1}({2}) is NOT skipped - found match in symtab",410GetSymbolFileName(), __FUNCTION__, name);411412// Found match in symbol table hydrate debug info and413// allow the FindFucntions to go through.414SetLoadDebugInfoEnabled();415}416return m_sym_file_impl->FindFunctions(lookup_info, parent_decl_ctx,417include_inlines, sc_list);418}419420void SymbolFileOnDemand::GetMangledNamesForFunction(421const std::string &scope_qualified_name,422std::vector<ConstString> &mangled_names) {423if (!m_debug_info_enabled) {424Log *log = GetLog();425LLDB_LOG(log, "[{0}] {1}({2}) is skipped", GetSymbolFileName(),426__FUNCTION__, scope_qualified_name);427return;428}429return m_sym_file_impl->GetMangledNamesForFunction(scope_qualified_name,430mangled_names);431}432433void SymbolFileOnDemand::FindTypes(const TypeQuery &match,434TypeResults &results) {435if (!m_debug_info_enabled) {436LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),437__FUNCTION__);438return;439}440return m_sym_file_impl->FindTypes(match, results);441}442443void SymbolFileOnDemand::GetTypes(SymbolContextScope *sc_scope,444TypeClass type_mask, TypeList &type_list) {445if (!m_debug_info_enabled) {446LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),447__FUNCTION__);448return;449}450return m_sym_file_impl->GetTypes(sc_scope, type_mask, type_list);451}452453llvm::Expected<lldb::TypeSystemSP>454SymbolFileOnDemand::GetTypeSystemForLanguage(LanguageType language) {455if (!m_debug_info_enabled) {456Log *log = GetLog();457LLDB_LOG(log, "[{0}] {1} is skipped for language type {2}",458GetSymbolFileName(), __FUNCTION__, language);459return llvm::createStringError(460"GetTypeSystemForLanguage is skipped by SymbolFileOnDemand");461}462return m_sym_file_impl->GetTypeSystemForLanguage(language);463}464465CompilerDeclContext466SymbolFileOnDemand::FindNamespace(ConstString name,467const CompilerDeclContext &parent_decl_ctx,468bool only_root_namespaces) {469if (!m_debug_info_enabled) {470LLDB_LOG(GetLog(), "[{0}] {1}({2}) is skipped", GetSymbolFileName(),471__FUNCTION__, name);472return SymbolFile::FindNamespace(name, parent_decl_ctx,473only_root_namespaces);474}475return m_sym_file_impl->FindNamespace(name, parent_decl_ctx,476only_root_namespaces);477}478479std::vector<std::unique_ptr<lldb_private::CallEdge>>480SymbolFileOnDemand::ParseCallEdgesInFunction(UserID func_id) {481if (!m_debug_info_enabled) {482Log *log = GetLog();483LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);484if (log) {485std::vector<std::unique_ptr<lldb_private::CallEdge>> call_edges =486m_sym_file_impl->ParseCallEdgesInFunction(func_id);487if (call_edges.size() > 0) {488LLDB_LOG(log, "{0} call edges would be parsed for {1} if hydrated.",489call_edges.size(), func_id.GetID());490}491}492return {};493}494return m_sym_file_impl->ParseCallEdgesInFunction(func_id);495}496497lldb::UnwindPlanSP498SymbolFileOnDemand::GetUnwindPlan(const Address &address,499const RegisterInfoResolver &resolver) {500if (!m_debug_info_enabled) {501LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),502__FUNCTION__);503return nullptr;504}505return m_sym_file_impl->GetUnwindPlan(address, resolver);506}507508llvm::Expected<lldb::addr_t>509SymbolFileOnDemand::GetParameterStackSize(Symbol &symbol) {510if (!m_debug_info_enabled) {511Log *log = GetLog();512LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);513if (log) {514llvm::Expected<lldb::addr_t> stack_size =515m_sym_file_impl->GetParameterStackSize(symbol);516if (stack_size) {517LLDB_LOG(log, "{0} stack size would return for symbol {1} if hydrated.",518*stack_size, symbol.GetName());519}520}521return SymbolFile::GetParameterStackSize(symbol);522}523return m_sym_file_impl->GetParameterStackSize(symbol);524}525526void SymbolFileOnDemand::PreloadSymbols() {527m_preload_symbols = true;528if (!m_debug_info_enabled) {529LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),530__FUNCTION__);531return;532}533return m_sym_file_impl->PreloadSymbols();534}535536uint64_t SymbolFileOnDemand::GetDebugInfoSize(bool load_all_debug_info) {537// Always return the real debug info size.538LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),539__FUNCTION__);540return m_sym_file_impl->GetDebugInfoSize(load_all_debug_info);541}542543StatsDuration::Duration SymbolFileOnDemand::GetDebugInfoParseTime() {544// Always return the real parse time.545LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),546__FUNCTION__);547return m_sym_file_impl->GetDebugInfoParseTime();548}549550StatsDuration::Duration SymbolFileOnDemand::GetDebugInfoIndexTime() {551// Always return the real index time.552LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),553__FUNCTION__);554return m_sym_file_impl->GetDebugInfoIndexTime();555}556557void SymbolFileOnDemand::SetLoadDebugInfoEnabled() {558if (m_debug_info_enabled)559return;560LLDB_LOG(GetLog(), "[{0}] Hydrate debug info", GetSymbolFileName());561m_debug_info_enabled = true;562InitializeObject();563if (m_preload_symbols)564PreloadSymbols();565}566567uint32_t SymbolFileOnDemand::GetNumCompileUnits() {568LLDB_LOG(GetLog(), "[{0}] {1} is not skipped to support breakpoint hydration",569GetSymbolFileName(), __FUNCTION__);570return m_sym_file_impl->GetNumCompileUnits();571}572573CompUnitSP SymbolFileOnDemand::GetCompileUnitAtIndex(uint32_t idx) {574LLDB_LOG(GetLog(), "[{0}] {1} is not skipped to support breakpoint hydration",575GetSymbolFileName(), __FUNCTION__);576return m_sym_file_impl->GetCompileUnitAtIndex(idx);577}578579uint32_t SymbolFileOnDemand::GetAbilities() {580if (!m_debug_info_enabled) {581LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),582__FUNCTION__);583return 0;584}585return m_sym_file_impl->GetAbilities();586}587588589