130fdc8d8SChris Lattner //===-- SymbolFile.cpp ------------------------------------------*- C++ -*-===//
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"
154069730cSRavitheja Addepally #include "lldb/Symbol/TypeMap.h"
1656939cb3SGreg Clayton #include "lldb/Symbol/TypeSystem.h"
1799558cc4SGreg Clayton #include "lldb/Symbol/VariableList.h"
186f9e6901SZachary Turner #include "lldb/Utility/Log.h"
19bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
20b9c1b51eSKate Stone #include "lldb/lldb-private.h"
2130fdc8d8SChris Lattner 
224f78c4f6SJonas Devlieghere #include <future>
234f78c4f6SJonas Devlieghere 
2430fdc8d8SChris Lattner using namespace lldb_private;
25e0119909SPavel Labath using namespace lldb;
2630fdc8d8SChris Lattner 
277fca8c07SJim Ingham void SymbolFile::PreloadSymbols() {
287fca8c07SJim Ingham   // No-op for most implementations.
297fca8c07SJim Ingham }
307fca8c07SJim Ingham 
314f78c4f6SJonas Devlieghere std::recursive_mutex &SymbolFile::GetModuleMutex() const {
324f78c4f6SJonas Devlieghere   return GetObjectFile()->GetModule()->GetMutex();
334f78c4f6SJonas Devlieghere }
34c2409baaSPavel Labath ObjectFile *SymbolFile::GetMainObjectFile() {
35c2409baaSPavel Labath   return m_obj_file->GetModule()->GetObjectFile();
36c2409baaSPavel Labath }
374f78c4f6SJonas Devlieghere 
38b9c1b51eSKate Stone SymbolFile *SymbolFile::FindPlugin(ObjectFile *obj_file) {
39d5b44036SJonas Devlieghere   std::unique_ptr<SymbolFile> best_symfile_up;
40b9c1b51eSKate Stone   if (obj_file != nullptr) {
413046e668SGreg Clayton 
42b9c1b51eSKate Stone     // We need to test the abilities of this section list. So create what it
4305097246SAdrian Prantl     // would be with this new obj_file.
443046e668SGreg Clayton     lldb::ModuleSP module_sp(obj_file->GetModule());
45b9c1b51eSKate Stone     if (module_sp) {
463046e668SGreg Clayton       // Default to the main module section list.
473046e668SGreg Clayton       ObjectFile *module_obj_file = module_sp->GetObjectFile();
48b9c1b51eSKate Stone       if (module_obj_file != obj_file) {
493046e668SGreg Clayton         // Make sure the main object file's sections are created
503046e668SGreg Clayton         module_obj_file->GetSectionList();
513046e668SGreg Clayton         obj_file->CreateSections(*module_sp->GetUnifiedSectionList());
523046e668SGreg Clayton       }
533046e668SGreg Clayton     }
543046e668SGreg Clayton 
5530fdc8d8SChris Lattner     // TODO: Load any plug-ins in the appropriate plug-in search paths and
5630fdc8d8SChris Lattner     // iterate over all of them to find the best one for the job.
5730fdc8d8SChris Lattner 
5830fdc8d8SChris Lattner     uint32_t best_symfile_abilities = 0;
5930fdc8d8SChris Lattner 
6030fdc8d8SChris Lattner     SymbolFileCreateInstance create_callback;
61b9c1b51eSKate Stone     for (uint32_t idx = 0;
62b9c1b51eSKate Stone          (create_callback = PluginManager::GetSymbolFileCreateCallbackAtIndex(
63b9c1b51eSKate Stone               idx)) != nullptr;
64b9c1b51eSKate Stone          ++idx) {
65d5b44036SJonas Devlieghere       std::unique_ptr<SymbolFile> curr_symfile_up(create_callback(obj_file));
6630fdc8d8SChris Lattner 
67d5b44036SJonas Devlieghere       if (curr_symfile_up) {
68d5b44036SJonas Devlieghere         const uint32_t sym_file_abilities = curr_symfile_up->GetAbilities();
69b9c1b51eSKate Stone         if (sym_file_abilities > best_symfile_abilities) {
7030fdc8d8SChris Lattner           best_symfile_abilities = sym_file_abilities;
71d5b44036SJonas Devlieghere           best_symfile_up.reset(curr_symfile_up.release());
7205097246SAdrian Prantl           // If any symbol file parser has all of the abilities, then we should
7305097246SAdrian Prantl           // just stop looking.
749efa076aSGreg Clayton           if ((kAllAbilities & sym_file_abilities) == kAllAbilities)
759efa076aSGreg Clayton             break;
7630fdc8d8SChris Lattner         }
7730fdc8d8SChris Lattner       }
7830fdc8d8SChris Lattner     }
79d5b44036SJonas Devlieghere     if (best_symfile_up) {
8005097246SAdrian Prantl       // Let the winning symbol file parser initialize itself more completely
8105097246SAdrian Prantl       // now that it has been chosen
82d5b44036SJonas Devlieghere       best_symfile_up->InitializeObject();
8330fdc8d8SChris Lattner     }
846beaaa68SGreg Clayton   }
85d5b44036SJonas Devlieghere   return best_symfile_up.release();
8630fdc8d8SChris Lattner }
8730fdc8d8SChris Lattner 
88b9c1b51eSKate Stone TypeSystem *SymbolFile::GetTypeSystemForLanguage(lldb::LanguageType language) {
89b9c1b51eSKate Stone   TypeSystem *type_system =
90b9c1b51eSKate Stone       m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
9157bee1edSRyan Brown   if (type_system)
9257bee1edSRyan Brown     type_system->SetSymbolFile(this);
9357bee1edSRyan Brown   return type_system;
948b4edba9SGreg Clayton }
958b4edba9SGreg Clayton 
96b9c1b51eSKate Stone uint32_t SymbolFile::ResolveSymbolContext(const FileSpec &file_spec,
97b9c1b51eSKate Stone                                           uint32_t line, bool check_inlines,
98991e4453SZachary Turner                                           lldb::SymbolContextItem resolve_scope,
99b9c1b51eSKate Stone                                           SymbolContextList &sc_list) {
10099558cc4SGreg Clayton   return 0;
10199558cc4SGreg Clayton }
10299558cc4SGreg Clayton 
10334cda14bSPavel Labath uint32_t
1040e4c4821SAdrian Prantl SymbolFile::FindGlobalVariables(ConstString name,
10534cda14bSPavel Labath                                 const CompilerDeclContext *parent_decl_ctx,
10634cda14bSPavel Labath                                 uint32_t max_matches, VariableList &variables) {
10799558cc4SGreg Clayton   return 0;
10899558cc4SGreg Clayton }
10999558cc4SGreg Clayton 
110b9c1b51eSKate Stone uint32_t SymbolFile::FindGlobalVariables(const RegularExpression &regex,
11134cda14bSPavel Labath                                          uint32_t max_matches,
112b9c1b51eSKate Stone                                          VariableList &variables) {
11399558cc4SGreg Clayton   return 0;
11499558cc4SGreg Clayton }
11599558cc4SGreg Clayton 
1160e4c4821SAdrian Prantl uint32_t SymbolFile::FindFunctions(ConstString name,
117b9c1b51eSKate Stone                                    const CompilerDeclContext *parent_decl_ctx,
118117b1fa1SZachary Turner                                    lldb::FunctionNameType name_type_mask,
119b9c1b51eSKate Stone                                    bool include_inlines, bool append,
120b9c1b51eSKate Stone                                    SymbolContextList &sc_list) {
12199558cc4SGreg Clayton   if (!append)
12299558cc4SGreg Clayton     sc_list.Clear();
12399558cc4SGreg Clayton   return 0;
12499558cc4SGreg Clayton }
12599558cc4SGreg Clayton 
126b9c1b51eSKate Stone uint32_t SymbolFile::FindFunctions(const RegularExpression &regex,
127b9c1b51eSKate Stone                                    bool include_inlines, bool append,
128b9c1b51eSKate Stone                                    SymbolContextList &sc_list) {
12999558cc4SGreg Clayton   if (!append)
13099558cc4SGreg Clayton     sc_list.Clear();
13199558cc4SGreg Clayton   return 0;
13299558cc4SGreg Clayton }
13399558cc4SGreg Clayton 
134b9c1b51eSKate Stone void SymbolFile::GetMangledNamesForFunction(
135b9c1b51eSKate Stone     const std::string &scope_qualified_name,
136b9c1b51eSKate Stone     std::vector<ConstString> &mangled_names) {
1379293fc41SSiva Chandra   return;
1389293fc41SSiva Chandra }
1399293fc41SSiva Chandra 
140b9c1b51eSKate Stone uint32_t SymbolFile::FindTypes(
1410e4c4821SAdrian Prantl     ConstString name, const CompilerDeclContext *parent_decl_ctx,
142576495e6SZachary Turner     bool append, uint32_t max_matches,
143b9c1b51eSKate Stone     llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
144b9c1b51eSKate Stone     TypeMap &types) {
14599558cc4SGreg Clayton   if (!append)
14699558cc4SGreg Clayton     types.Clear();
14799558cc4SGreg Clayton   return 0;
14899558cc4SGreg Clayton }
14999558cc4SGreg Clayton 
150b9c1b51eSKate Stone size_t SymbolFile::FindTypes(const std::vector<CompilerContext> &context,
151b9c1b51eSKate Stone                              bool append, TypeMap &types) {
152e6b36cddSGreg Clayton   if (!append)
153e6b36cddSGreg Clayton     types.Clear();
154e6b36cddSGreg Clayton   return 0;
155e6b36cddSGreg Clayton }
1564f78c4f6SJonas Devlieghere 
1574f78c4f6SJonas Devlieghere void SymbolFile::AssertModuleLock() {
1584f78c4f6SJonas Devlieghere   // The code below is too expensive to leave enabled in release builds. It's
1594f78c4f6SJonas Devlieghere   // enabled in debug builds or when the correct macro is set.
1604f78c4f6SJonas Devlieghere #if defined(LLDB_CONFIGURATION_DEBUG)
1614f78c4f6SJonas Devlieghere   // We assert that we have to module lock by trying to acquire the lock from a
1624f78c4f6SJonas Devlieghere   // different thread. Note that we must abort if the result is true to
1634f78c4f6SJonas Devlieghere   // guarantee correctness.
1644f78c4f6SJonas Devlieghere   assert(std::async(std::launch::async,
1654f78c4f6SJonas Devlieghere                     [this] { return this->GetModuleMutex().try_lock(); })
1664f78c4f6SJonas Devlieghere                  .get() == false &&
1674f78c4f6SJonas Devlieghere          "Module is not locked");
1684f78c4f6SJonas Devlieghere #endif
1694f78c4f6SJonas Devlieghere }
17022bbd7d6SPavel Labath 
171e0119909SPavel Labath uint32_t SymbolFile::GetNumCompileUnits() {
172e0119909SPavel Labath   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
173e0119909SPavel Labath   if (!m_compile_units) {
174e0119909SPavel Labath     // Create an array of compile unit shared pointers -- which will each
175e0119909SPavel Labath     // remain NULL until someone asks for the actual compile unit information.
176e0119909SPavel Labath     m_compile_units.emplace(CalculateNumCompileUnits());
177e0119909SPavel Labath   }
178e0119909SPavel Labath   return m_compile_units->size();
179e0119909SPavel Labath }
180e0119909SPavel Labath 
181e0119909SPavel Labath CompUnitSP SymbolFile::GetCompileUnitAtIndex(uint32_t idx) {
182*656ddeb2SPavel Labath   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
183e0119909SPavel Labath   uint32_t num = GetNumCompileUnits();
184e0119909SPavel Labath   if (idx >= num)
185e0119909SPavel Labath     return nullptr;
186e0119909SPavel Labath   lldb::CompUnitSP &cu_sp = (*m_compile_units)[idx];
187e0119909SPavel Labath   if (!cu_sp)
188e0119909SPavel Labath     cu_sp = ParseCompileUnitAtIndex(idx);
189e0119909SPavel Labath   return cu_sp;
190e0119909SPavel Labath }
191e0119909SPavel Labath 
192e0119909SPavel Labath void SymbolFile::SetCompileUnitAtIndex(uint32_t idx, const CompUnitSP &cu_sp) {
193e0119909SPavel Labath   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
194e0119909SPavel Labath   const size_t num_compile_units = GetNumCompileUnits();
195e0119909SPavel Labath   assert(idx < num_compile_units);
1962e959415SFangrui Song   (void)num_compile_units;
197e0119909SPavel Labath 
198e0119909SPavel Labath   // Fire off an assertion if this compile unit already exists for now. The
199e0119909SPavel Labath   // partial parsing should take care of only setting the compile unit
200e0119909SPavel Labath   // once, so if this assertion fails, we need to make sure that we don't
201e0119909SPavel Labath   // have a race condition, or have a second parse of the same compile
202e0119909SPavel Labath   // unit.
203e0119909SPavel Labath   assert((*m_compile_units)[idx] == nullptr);
204e0119909SPavel Labath   (*m_compile_units)[idx] = cu_sp;
205e0119909SPavel Labath }
206e0119909SPavel Labath 
20784a68569SPavel Labath Symtab *SymbolFile::GetSymtab() {
20884a68569SPavel Labath   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
20984a68569SPavel Labath   if (m_symtab)
21084a68569SPavel Labath     return m_symtab;
21184a68569SPavel Labath 
21284a68569SPavel Labath   // Fetch the symtab from the main object file.
213c2409baaSPavel Labath   m_symtab = GetMainObjectFile()->GetSymtab();
21484a68569SPavel Labath 
21584a68569SPavel Labath   // Then add our symbols to it.
21684a68569SPavel Labath   if (m_symtab)
21784a68569SPavel Labath     AddSymbols(*m_symtab);
21884a68569SPavel Labath 
21984a68569SPavel Labath   return m_symtab;
22084a68569SPavel Labath }
22184a68569SPavel Labath 
222c2409baaSPavel Labath void SymbolFile::SectionFileAddressesChanged() {
223c2409baaSPavel Labath   ObjectFile *module_objfile = GetMainObjectFile();
224c2409baaSPavel Labath   ObjectFile *symfile_objfile = GetObjectFile();
225c2409baaSPavel Labath   if (symfile_objfile != module_objfile)
226c2409baaSPavel Labath     symfile_objfile->SectionFileAddressesChanged();
227c2409baaSPavel Labath   if (m_symtab)
228c2409baaSPavel Labath     m_symtab->SectionFileAddressesChanged();
229c2409baaSPavel Labath }
230c2409baaSPavel Labath 
231e0119909SPavel Labath void SymbolFile::Dump(Stream &s) {
232f46e8974SPavel Labath   s.PutCString("Types:\n");
233f46e8974SPavel Labath   m_type_list.Dump(&s, /*show_context*/ false);
234f46e8974SPavel Labath   s.PutChar('\n');
235f46e8974SPavel Labath 
236e0119909SPavel Labath   s.PutCString("Compile units:\n");
237e0119909SPavel Labath   if (m_compile_units) {
238e0119909SPavel Labath     for (const CompUnitSP &cu_sp : *m_compile_units) {
239e0119909SPavel Labath       // We currently only dump the compile units that have been parsed
240e0119909SPavel Labath       if (cu_sp)
241e0119909SPavel Labath         cu_sp->Dump(&s, /*show_context*/ false);
242e0119909SPavel Labath     }
243e0119909SPavel Labath   }
244e0119909SPavel Labath   s.PutChar('\n');
245e0119909SPavel Labath }
246e0119909SPavel Labath 
24722bbd7d6SPavel Labath SymbolFile::RegisterInfoResolver::~RegisterInfoResolver() = default;
248