180814287SRaphael Isemann //===-- SymbolFile.cpp ----------------------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner
930fdc8d8SChris Lattner #include "lldb/Symbol/SymbolFile.h"
10c982b3d6SGreg Clayton
112d95dc9bSGreg Clayton #include "lldb/Core/Module.h"
1230fdc8d8SChris Lattner #include "lldb/Core/PluginManager.h"
13e0119909SPavel Labath #include "lldb/Symbol/CompileUnit.h"
142d95dc9bSGreg Clayton #include "lldb/Symbol/ObjectFile.h"
15*7b81192dSJeffrey Tan #include "lldb/Symbol/SymbolFileOnDemand.h"
164069730cSRavitheja Addepally #include "lldb/Symbol/TypeMap.h"
1756939cb3SGreg Clayton #include "lldb/Symbol/TypeSystem.h"
1899558cc4SGreg Clayton #include "lldb/Symbol/VariableList.h"
196f9e6901SZachary Turner #include "lldb/Utility/Log.h"
20bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
21b9c1b51eSKate Stone #include "lldb/lldb-private.h"
2230fdc8d8SChris Lattner
234f78c4f6SJonas Devlieghere #include <future>
244f78c4f6SJonas Devlieghere
2530fdc8d8SChris Lattner using namespace lldb_private;
26e0119909SPavel Labath using namespace lldb;
2730fdc8d8SChris Lattner
287d71dd92SAdrian Prantl char SymbolFile::ID;
295cbf516cSJeffrey Tan char SymbolFileCommon::ID;
307d71dd92SAdrian Prantl
PreloadSymbols()317fca8c07SJim Ingham void SymbolFile::PreloadSymbols() {
327fca8c07SJim Ingham // No-op for most implementations.
337fca8c07SJim Ingham }
347fca8c07SJim Ingham
GetModuleMutex() const354f78c4f6SJonas Devlieghere std::recursive_mutex &SymbolFile::GetModuleMutex() const {
364f78c4f6SJonas Devlieghere return GetObjectFile()->GetModule()->GetMutex();
374f78c4f6SJonas Devlieghere }
384f78c4f6SJonas Devlieghere
FindPlugin(ObjectFileSP objfile_sp)39d2deeb44SPavel Labath SymbolFile *SymbolFile::FindPlugin(ObjectFileSP objfile_sp) {
40d5b44036SJonas Devlieghere std::unique_ptr<SymbolFile> best_symfile_up;
41d2deeb44SPavel Labath if (objfile_sp != nullptr) {
423046e668SGreg Clayton
43b9c1b51eSKate Stone // We need to test the abilities of this section list. So create what it
44d2deeb44SPavel Labath // would be with this new objfile_sp.
45d2deeb44SPavel Labath lldb::ModuleSP module_sp(objfile_sp->GetModule());
46b9c1b51eSKate Stone if (module_sp) {
473046e668SGreg Clayton // Default to the main module section list.
483046e668SGreg Clayton ObjectFile *module_obj_file = module_sp->GetObjectFile();
49d2deeb44SPavel Labath if (module_obj_file != objfile_sp.get()) {
503046e668SGreg Clayton // Make sure the main object file's sections are created
513046e668SGreg Clayton module_obj_file->GetSectionList();
52d2deeb44SPavel Labath objfile_sp->CreateSections(*module_sp->GetUnifiedSectionList());
533046e668SGreg Clayton }
543046e668SGreg Clayton }
553046e668SGreg Clayton
5630fdc8d8SChris Lattner // TODO: Load any plug-ins in the appropriate plug-in search paths and
5730fdc8d8SChris Lattner // iterate over all of them to find the best one for the job.
5830fdc8d8SChris Lattner
5930fdc8d8SChris Lattner uint32_t best_symfile_abilities = 0;
6030fdc8d8SChris Lattner
6130fdc8d8SChris Lattner SymbolFileCreateInstance create_callback;
62b9c1b51eSKate Stone for (uint32_t idx = 0;
63b9c1b51eSKate Stone (create_callback = PluginManager::GetSymbolFileCreateCallbackAtIndex(
64b9c1b51eSKate Stone idx)) != nullptr;
65b9c1b51eSKate Stone ++idx) {
66d2deeb44SPavel Labath std::unique_ptr<SymbolFile> curr_symfile_up(create_callback(objfile_sp));
6730fdc8d8SChris Lattner
68d5b44036SJonas Devlieghere if (curr_symfile_up) {
69d5b44036SJonas Devlieghere const uint32_t sym_file_abilities = curr_symfile_up->GetAbilities();
70b9c1b51eSKate Stone if (sym_file_abilities > best_symfile_abilities) {
7130fdc8d8SChris Lattner best_symfile_abilities = sym_file_abilities;
72d5b44036SJonas Devlieghere best_symfile_up.reset(curr_symfile_up.release());
7305097246SAdrian Prantl // If any symbol file parser has all of the abilities, then we should
7405097246SAdrian Prantl // just stop looking.
759efa076aSGreg Clayton if ((kAllAbilities & sym_file_abilities) == kAllAbilities)
769efa076aSGreg Clayton break;
7730fdc8d8SChris Lattner }
7830fdc8d8SChris Lattner }
7930fdc8d8SChris Lattner }
80d5b44036SJonas Devlieghere if (best_symfile_up) {
81*7b81192dSJeffrey Tan // If symbol on-demand is enabled the winning symbol file parser is
82*7b81192dSJeffrey Tan // wrapped with SymbolFileOnDemand so that hydration of the debug info
83*7b81192dSJeffrey Tan // can be controlled to improve performance.
84*7b81192dSJeffrey Tan //
85*7b81192dSJeffrey Tan // Currently the supported on-demand symbol files include:
86*7b81192dSJeffrey Tan // executables, shared libraries and debug info files.
87*7b81192dSJeffrey Tan //
88*7b81192dSJeffrey Tan // To reduce unnecessary wrapping files with zero debug abilities are
89*7b81192dSJeffrey Tan // skipped.
90*7b81192dSJeffrey Tan ObjectFile::Type obj_file_type = objfile_sp->CalculateType();
91*7b81192dSJeffrey Tan if (ModuleList::GetGlobalModuleListProperties().GetLoadSymbolOnDemand() &&
92*7b81192dSJeffrey Tan best_symfile_abilities > 0 &&
93*7b81192dSJeffrey Tan (obj_file_type == ObjectFile::eTypeExecutable ||
94*7b81192dSJeffrey Tan obj_file_type == ObjectFile::eTypeSharedLibrary ||
95*7b81192dSJeffrey Tan obj_file_type == ObjectFile::eTypeDebugInfo)) {
96*7b81192dSJeffrey Tan best_symfile_up =
97*7b81192dSJeffrey Tan std::make_unique<SymbolFileOnDemand>(std::move(best_symfile_up));
98*7b81192dSJeffrey Tan }
9905097246SAdrian Prantl // Let the winning symbol file parser initialize itself more completely
10005097246SAdrian Prantl // now that it has been chosen
101d5b44036SJonas Devlieghere best_symfile_up->InitializeObject();
10230fdc8d8SChris Lattner }
1036beaaa68SGreg Clayton }
104d5b44036SJonas Devlieghere return best_symfile_up.release();
10530fdc8d8SChris Lattner }
10630fdc8d8SChris Lattner
1073e2ed744SMed Ismail Bennani uint32_t
ResolveSymbolContext(const SourceLocationSpec & src_location_spec,lldb::SymbolContextItem resolve_scope,SymbolContextList & sc_list)1083e2ed744SMed Ismail Bennani SymbolFile::ResolveSymbolContext(const SourceLocationSpec &src_location_spec,
109991e4453SZachary Turner lldb::SymbolContextItem resolve_scope,
110b9c1b51eSKate Stone SymbolContextList &sc_list) {
11199558cc4SGreg Clayton return 0;
11299558cc4SGreg Clayton }
11399558cc4SGreg Clayton
FindGlobalVariables(ConstString name,const CompilerDeclContext & parent_decl_ctx,uint32_t max_matches,VariableList & variables)1141ad655e2SAdrian Prantl void SymbolFile::FindGlobalVariables(ConstString name,
115f9568a95SRaphael Isemann const CompilerDeclContext &parent_decl_ctx,
11634cda14bSPavel Labath uint32_t max_matches,
1171ad655e2SAdrian Prantl VariableList &variables) {}
11899558cc4SGreg Clayton
FindGlobalVariables(const RegularExpression & regex,uint32_t max_matches,VariableList & variables)1191ad655e2SAdrian Prantl void SymbolFile::FindGlobalVariables(const RegularExpression ®ex,
1201ad655e2SAdrian Prantl uint32_t max_matches,
1211ad655e2SAdrian Prantl VariableList &variables) {}
1221ad655e2SAdrian Prantl
FindFunctions(ConstString name,const CompilerDeclContext & parent_decl_ctx,lldb::FunctionNameType name_type_mask,bool include_inlines,SymbolContextList & sc_list)1231ad655e2SAdrian Prantl void SymbolFile::FindFunctions(ConstString name,
124f9568a95SRaphael Isemann const CompilerDeclContext &parent_decl_ctx,
125117b1fa1SZachary Turner lldb::FunctionNameType name_type_mask,
1261ad655e2SAdrian Prantl bool include_inlines,
1271ad655e2SAdrian Prantl SymbolContextList &sc_list) {}
12899558cc4SGreg Clayton
FindFunctions(const RegularExpression & regex,bool include_inlines,SymbolContextList & sc_list)1291ad655e2SAdrian Prantl void SymbolFile::FindFunctions(const RegularExpression ®ex,
1301ad655e2SAdrian Prantl bool include_inlines,
1311ad655e2SAdrian Prantl SymbolContextList &sc_list) {}
13299558cc4SGreg Clayton
GetMangledNamesForFunction(const std::string & scope_qualified_name,std::vector<ConstString> & mangled_names)133b9c1b51eSKate Stone void SymbolFile::GetMangledNamesForFunction(
134b9c1b51eSKate Stone const std::string &scope_qualified_name,
1352d303e67SKazu Hirata std::vector<ConstString> &mangled_names) {}
1369293fc41SSiva Chandra
FindTypes(ConstString name,const CompilerDeclContext & parent_decl_ctx,uint32_t max_matches,llvm::DenseSet<lldb_private::SymbolFile * > & searched_symbol_files,TypeMap & types)137bf9d84c0SAdrian Prantl void SymbolFile::FindTypes(
138f9568a95SRaphael Isemann ConstString name, const CompilerDeclContext &parent_decl_ctx,
139d4d428efSAdrian Prantl uint32_t max_matches,
140b9c1b51eSKate Stone llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
141bf9d84c0SAdrian Prantl TypeMap &types) {}
14299558cc4SGreg Clayton
FindTypes(llvm::ArrayRef<CompilerContext> pattern,LanguageSet languages,llvm::DenseSet<SymbolFile * > & searched_symbol_files,TypeMap & types)143bf9d84c0SAdrian Prantl void SymbolFile::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
1443b73dcdcSAdrian Prantl LanguageSet languages,
1453b73dcdcSAdrian Prantl llvm::DenseSet<SymbolFile *> &searched_symbol_files,
1463b73dcdcSAdrian Prantl TypeMap &types) {}
1474f78c4f6SJonas Devlieghere
AssertModuleLock()1484f78c4f6SJonas Devlieghere void SymbolFile::AssertModuleLock() {
1494f78c4f6SJonas Devlieghere // The code below is too expensive to leave enabled in release builds. It's
1504f78c4f6SJonas Devlieghere // enabled in debug builds or when the correct macro is set.
1514f78c4f6SJonas Devlieghere #if defined(LLDB_CONFIGURATION_DEBUG)
1524f78c4f6SJonas Devlieghere // We assert that we have to module lock by trying to acquire the lock from a
1534f78c4f6SJonas Devlieghere // different thread. Note that we must abort if the result is true to
1544f78c4f6SJonas Devlieghere // guarantee correctness.
155b2e2eeceSLasse Folger assert(std::async(
156b2e2eeceSLasse Folger std::launch::async,
157b2e2eeceSLasse Folger [this] {
158b2e2eeceSLasse Folger return this->GetModuleMutex().try_lock();
159b2e2eeceSLasse Folger }).get() == false &&
1604f78c4f6SJonas Devlieghere "Module is not locked");
1614f78c4f6SJonas Devlieghere #endif
1624f78c4f6SJonas Devlieghere }
16322bbd7d6SPavel Labath
1645cbf516cSJeffrey Tan SymbolFile::RegisterInfoResolver::~RegisterInfoResolver() = default;
165e0119909SPavel Labath
GetSymtab()1665cbf516cSJeffrey Tan Symtab *SymbolFileCommon::GetSymtab() {
16784a68569SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
16884a68569SPavel Labath if (m_symtab)
16984a68569SPavel Labath return m_symtab;
17084a68569SPavel Labath
17184a68569SPavel Labath // Fetch the symtab from the main object file.
172c2409baaSPavel Labath m_symtab = GetMainObjectFile()->GetSymtab();
17384a68569SPavel Labath
17484a68569SPavel Labath // Then add our symbols to it.
17584a68569SPavel Labath if (m_symtab)
17684a68569SPavel Labath AddSymbols(*m_symtab);
17784a68569SPavel Labath
17884a68569SPavel Labath return m_symtab;
17984a68569SPavel Labath }
18084a68569SPavel Labath
GetMainObjectFile()1815cbf516cSJeffrey Tan ObjectFile *SymbolFileCommon::GetMainObjectFile() {
1825cbf516cSJeffrey Tan return m_objfile_sp->GetModule()->GetObjectFile();
1835cbf516cSJeffrey Tan }
1845cbf516cSJeffrey Tan
SectionFileAddressesChanged()1855cbf516cSJeffrey Tan void SymbolFileCommon::SectionFileAddressesChanged() {
186c2409baaSPavel Labath ObjectFile *module_objfile = GetMainObjectFile();
187c2409baaSPavel Labath ObjectFile *symfile_objfile = GetObjectFile();
188c2409baaSPavel Labath if (symfile_objfile != module_objfile)
189c2409baaSPavel Labath symfile_objfile->SectionFileAddressesChanged();
190c2409baaSPavel Labath if (m_symtab)
191c2409baaSPavel Labath m_symtab->SectionFileAddressesChanged();
192c2409baaSPavel Labath }
193c2409baaSPavel Labath
GetNumCompileUnits()1945cbf516cSJeffrey Tan uint32_t SymbolFileCommon::GetNumCompileUnits() {
1955cbf516cSJeffrey Tan std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1965cbf516cSJeffrey Tan if (!m_compile_units) {
1975cbf516cSJeffrey Tan // Create an array of compile unit shared pointers -- which will each
1985cbf516cSJeffrey Tan // remain NULL until someone asks for the actual compile unit information.
1995cbf516cSJeffrey Tan m_compile_units.emplace(CalculateNumCompileUnits());
2005cbf516cSJeffrey Tan }
2015cbf516cSJeffrey Tan return m_compile_units->size();
2025cbf516cSJeffrey Tan }
2035cbf516cSJeffrey Tan
GetCompileUnitAtIndex(uint32_t idx)2045cbf516cSJeffrey Tan CompUnitSP SymbolFileCommon::GetCompileUnitAtIndex(uint32_t idx) {
2055cbf516cSJeffrey Tan std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2065cbf516cSJeffrey Tan uint32_t num = GetNumCompileUnits();
2075cbf516cSJeffrey Tan if (idx >= num)
2085cbf516cSJeffrey Tan return nullptr;
2095cbf516cSJeffrey Tan lldb::CompUnitSP &cu_sp = (*m_compile_units)[idx];
2105cbf516cSJeffrey Tan if (!cu_sp)
2115cbf516cSJeffrey Tan cu_sp = ParseCompileUnitAtIndex(idx);
2125cbf516cSJeffrey Tan return cu_sp;
2135cbf516cSJeffrey Tan }
2145cbf516cSJeffrey Tan
SetCompileUnitAtIndex(uint32_t idx,const CompUnitSP & cu_sp)2155cbf516cSJeffrey Tan void SymbolFileCommon::SetCompileUnitAtIndex(uint32_t idx,
2165cbf516cSJeffrey Tan const CompUnitSP &cu_sp) {
2175cbf516cSJeffrey Tan std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2185cbf516cSJeffrey Tan const size_t num_compile_units = GetNumCompileUnits();
2195cbf516cSJeffrey Tan assert(idx < num_compile_units);
2205cbf516cSJeffrey Tan (void)num_compile_units;
2215cbf516cSJeffrey Tan
2225cbf516cSJeffrey Tan // Fire off an assertion if this compile unit already exists for now. The
2235cbf516cSJeffrey Tan // partial parsing should take care of only setting the compile unit
2245cbf516cSJeffrey Tan // once, so if this assertion fails, we need to make sure that we don't
2255cbf516cSJeffrey Tan // have a race condition, or have a second parse of the same compile
2265cbf516cSJeffrey Tan // unit.
2275cbf516cSJeffrey Tan assert((*m_compile_units)[idx] == nullptr);
2285cbf516cSJeffrey Tan (*m_compile_units)[idx] = cu_sp;
2295cbf516cSJeffrey Tan }
2305cbf516cSJeffrey Tan
2315cbf516cSJeffrey Tan llvm::Expected<TypeSystem &>
GetTypeSystemForLanguage(lldb::LanguageType language)2325cbf516cSJeffrey Tan SymbolFileCommon::GetTypeSystemForLanguage(lldb::LanguageType language) {
2335cbf516cSJeffrey Tan auto type_system_or_err =
2345cbf516cSJeffrey Tan m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
2355cbf516cSJeffrey Tan if (type_system_or_err) {
2365cbf516cSJeffrey Tan type_system_or_err->SetSymbolFile(this);
2375cbf516cSJeffrey Tan }
2385cbf516cSJeffrey Tan return type_system_or_err;
2395cbf516cSJeffrey Tan }
2405cbf516cSJeffrey Tan
GetDebugInfoSize()2415cbf516cSJeffrey Tan uint64_t SymbolFileCommon::GetDebugInfoSize() {
2425cbf516cSJeffrey Tan if (!m_objfile_sp)
2435cbf516cSJeffrey Tan return 0;
2445cbf516cSJeffrey Tan ModuleSP module_sp(m_objfile_sp->GetModule());
2455cbf516cSJeffrey Tan if (!module_sp)
2465cbf516cSJeffrey Tan return 0;
2475cbf516cSJeffrey Tan const SectionList *section_list = module_sp->GetSectionList();
2485cbf516cSJeffrey Tan if (section_list)
2495cbf516cSJeffrey Tan return section_list->GetDebugInfoSize();
2505cbf516cSJeffrey Tan return 0;
2515cbf516cSJeffrey Tan }
2525cbf516cSJeffrey Tan
Dump(Stream & s)2535cbf516cSJeffrey Tan void SymbolFileCommon::Dump(Stream &s) {
2545a7e1e97SPavel Labath s.Format("SymbolFile {0} ({1})\n", GetPluginName(),
2555a7e1e97SPavel Labath GetMainObjectFile()->GetFileSpec());
256f46e8974SPavel Labath s.PutCString("Types:\n");
257f46e8974SPavel Labath m_type_list.Dump(&s, /*show_context*/ false);
258f46e8974SPavel Labath s.PutChar('\n');
259f46e8974SPavel Labath
260e0119909SPavel Labath s.PutCString("Compile units:\n");
261e0119909SPavel Labath if (m_compile_units) {
262e0119909SPavel Labath for (const CompUnitSP &cu_sp : *m_compile_units) {
263e0119909SPavel Labath // We currently only dump the compile units that have been parsed
264e0119909SPavel Labath if (cu_sp)
265e0119909SPavel Labath cu_sp->Dump(&s, /*show_context*/ false);
266e0119909SPavel Labath }
267e0119909SPavel Labath }
268e0119909SPavel Labath s.PutChar('\n');
269d5d47a35SPavel Labath
270d5d47a35SPavel Labath if (Symtab *symtab = GetSymtab())
271d5d47a35SPavel Labath symtab->Dump(&s, nullptr, eSortOrderNone);
272e0119909SPavel Labath }
273