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"
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 
277d71dd92SAdrian Prantl char SymbolFile::ID;
287d71dd92SAdrian Prantl 
297fca8c07SJim Ingham void SymbolFile::PreloadSymbols() {
307fca8c07SJim Ingham   // No-op for most implementations.
317fca8c07SJim Ingham }
327fca8c07SJim Ingham 
334f78c4f6SJonas Devlieghere std::recursive_mutex &SymbolFile::GetModuleMutex() const {
344f78c4f6SJonas Devlieghere   return GetObjectFile()->GetModule()->GetMutex();
354f78c4f6SJonas Devlieghere }
36c2409baaSPavel Labath ObjectFile *SymbolFile::GetMainObjectFile() {
37d2deeb44SPavel Labath   return m_objfile_sp->GetModule()->GetObjectFile();
38c2409baaSPavel Labath }
394f78c4f6SJonas Devlieghere 
40d2deeb44SPavel Labath SymbolFile *SymbolFile::FindPlugin(ObjectFileSP objfile_sp) {
41d5b44036SJonas Devlieghere   std::unique_ptr<SymbolFile> best_symfile_up;
42d2deeb44SPavel Labath   if (objfile_sp != nullptr) {
433046e668SGreg Clayton 
44b9c1b51eSKate Stone     // We need to test the abilities of this section list. So create what it
45d2deeb44SPavel Labath     // would be with this new objfile_sp.
46d2deeb44SPavel Labath     lldb::ModuleSP module_sp(objfile_sp->GetModule());
47b9c1b51eSKate Stone     if (module_sp) {
483046e668SGreg Clayton       // Default to the main module section list.
493046e668SGreg Clayton       ObjectFile *module_obj_file = module_sp->GetObjectFile();
50d2deeb44SPavel Labath       if (module_obj_file != objfile_sp.get()) {
513046e668SGreg Clayton         // Make sure the main object file's sections are created
523046e668SGreg Clayton         module_obj_file->GetSectionList();
53d2deeb44SPavel Labath         objfile_sp->CreateSections(*module_sp->GetUnifiedSectionList());
543046e668SGreg Clayton       }
553046e668SGreg Clayton     }
563046e668SGreg Clayton 
5730fdc8d8SChris Lattner     // TODO: Load any plug-ins in the appropriate plug-in search paths and
5830fdc8d8SChris Lattner     // iterate over all of them to find the best one for the job.
5930fdc8d8SChris Lattner 
6030fdc8d8SChris Lattner     uint32_t best_symfile_abilities = 0;
6130fdc8d8SChris Lattner 
6230fdc8d8SChris Lattner     SymbolFileCreateInstance create_callback;
63b9c1b51eSKate Stone     for (uint32_t idx = 0;
64b9c1b51eSKate Stone          (create_callback = PluginManager::GetSymbolFileCreateCallbackAtIndex(
65b9c1b51eSKate Stone               idx)) != nullptr;
66b9c1b51eSKate Stone          ++idx) {
67d2deeb44SPavel Labath       std::unique_ptr<SymbolFile> curr_symfile_up(create_callback(objfile_sp));
6830fdc8d8SChris Lattner 
69d5b44036SJonas Devlieghere       if (curr_symfile_up) {
70d5b44036SJonas Devlieghere         const uint32_t sym_file_abilities = curr_symfile_up->GetAbilities();
71b9c1b51eSKate Stone         if (sym_file_abilities > best_symfile_abilities) {
7230fdc8d8SChris Lattner           best_symfile_abilities = sym_file_abilities;
73d5b44036SJonas Devlieghere           best_symfile_up.reset(curr_symfile_up.release());
7405097246SAdrian Prantl           // If any symbol file parser has all of the abilities, then we should
7505097246SAdrian Prantl           // just stop looking.
769efa076aSGreg Clayton           if ((kAllAbilities & sym_file_abilities) == kAllAbilities)
779efa076aSGreg Clayton             break;
7830fdc8d8SChris Lattner         }
7930fdc8d8SChris Lattner       }
8030fdc8d8SChris Lattner     }
81d5b44036SJonas Devlieghere     if (best_symfile_up) {
8205097246SAdrian Prantl       // Let the winning symbol file parser initialize itself more completely
8305097246SAdrian Prantl       // now that it has been chosen
84d5b44036SJonas Devlieghere       best_symfile_up->InitializeObject();
8530fdc8d8SChris Lattner     }
866beaaa68SGreg Clayton   }
87d5b44036SJonas Devlieghere   return best_symfile_up.release();
8830fdc8d8SChris Lattner }
8930fdc8d8SChris Lattner 
900e252e38SAlex Langford llvm::Expected<TypeSystem &>
910e252e38SAlex Langford SymbolFile::GetTypeSystemForLanguage(lldb::LanguageType language) {
920e252e38SAlex Langford   auto type_system_or_err =
93d2deeb44SPavel Labath       m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
940e252e38SAlex Langford   if (type_system_or_err) {
950e252e38SAlex Langford     type_system_or_err->SetSymbolFile(this);
960e252e38SAlex Langford   }
970e252e38SAlex Langford   return type_system_or_err;
988b4edba9SGreg Clayton }
998b4edba9SGreg Clayton 
1003e2ed744SMed Ismail Bennani uint32_t
1013e2ed744SMed Ismail Bennani SymbolFile::ResolveSymbolContext(const SourceLocationSpec &src_location_spec,
102991e4453SZachary Turner                                  lldb::SymbolContextItem resolve_scope,
103b9c1b51eSKate Stone                                  SymbolContextList &sc_list) {
10499558cc4SGreg Clayton   return 0;
10599558cc4SGreg Clayton }
10699558cc4SGreg Clayton 
1071ad655e2SAdrian Prantl void SymbolFile::FindGlobalVariables(ConstString name,
108f9568a95SRaphael Isemann                                      const CompilerDeclContext &parent_decl_ctx,
10934cda14bSPavel Labath                                      uint32_t max_matches,
1101ad655e2SAdrian Prantl                                      VariableList &variables) {}
11199558cc4SGreg Clayton 
1121ad655e2SAdrian Prantl void SymbolFile::FindGlobalVariables(const RegularExpression &regex,
1131ad655e2SAdrian Prantl                                      uint32_t max_matches,
1141ad655e2SAdrian Prantl                                      VariableList &variables) {}
1151ad655e2SAdrian Prantl 
1161ad655e2SAdrian Prantl void SymbolFile::FindFunctions(ConstString name,
117f9568a95SRaphael Isemann                                const CompilerDeclContext &parent_decl_ctx,
118117b1fa1SZachary Turner                                lldb::FunctionNameType name_type_mask,
1191ad655e2SAdrian Prantl                                bool include_inlines,
1201ad655e2SAdrian Prantl                                SymbolContextList &sc_list) {}
12199558cc4SGreg Clayton 
1221ad655e2SAdrian Prantl void SymbolFile::FindFunctions(const RegularExpression &regex,
1231ad655e2SAdrian Prantl                                bool include_inlines,
1241ad655e2SAdrian Prantl                                SymbolContextList &sc_list) {}
12599558cc4SGreg Clayton 
126b9c1b51eSKate Stone void SymbolFile::GetMangledNamesForFunction(
127b9c1b51eSKate Stone     const std::string &scope_qualified_name,
128b9c1b51eSKate Stone     std::vector<ConstString> &mangled_names) {
1299293fc41SSiva Chandra   return;
1309293fc41SSiva Chandra }
1319293fc41SSiva Chandra 
132bf9d84c0SAdrian Prantl void SymbolFile::FindTypes(
133f9568a95SRaphael Isemann     ConstString name, const CompilerDeclContext &parent_decl_ctx,
134d4d428efSAdrian Prantl     uint32_t max_matches,
135b9c1b51eSKate Stone     llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
136bf9d84c0SAdrian Prantl     TypeMap &types) {}
13799558cc4SGreg Clayton 
138bf9d84c0SAdrian Prantl void SymbolFile::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
1393b73dcdcSAdrian Prantl                            LanguageSet languages,
1403b73dcdcSAdrian Prantl                            llvm::DenseSet<SymbolFile *> &searched_symbol_files,
1413b73dcdcSAdrian Prantl                            TypeMap &types) {}
1424f78c4f6SJonas Devlieghere 
1434f78c4f6SJonas Devlieghere void SymbolFile::AssertModuleLock() {
1444f78c4f6SJonas Devlieghere   // The code below is too expensive to leave enabled in release builds. It's
1454f78c4f6SJonas Devlieghere   // enabled in debug builds or when the correct macro is set.
1464f78c4f6SJonas Devlieghere #if defined(LLDB_CONFIGURATION_DEBUG)
1474f78c4f6SJonas Devlieghere   // We assert that we have to module lock by trying to acquire the lock from a
1484f78c4f6SJonas Devlieghere   // different thread. Note that we must abort if the result is true to
1494f78c4f6SJonas Devlieghere   // guarantee correctness.
150*b2e2eeceSLasse Folger   assert(std::async(
151*b2e2eeceSLasse Folger              std::launch::async,
152*b2e2eeceSLasse Folger              [this] {
153*b2e2eeceSLasse Folger                return this->GetModuleMutex().try_lock();
154*b2e2eeceSLasse Folger              }).get() == false &&
1554f78c4f6SJonas Devlieghere          "Module is not locked");
1564f78c4f6SJonas Devlieghere #endif
1574f78c4f6SJonas Devlieghere }
15822bbd7d6SPavel Labath 
159e0119909SPavel Labath uint32_t SymbolFile::GetNumCompileUnits() {
160e0119909SPavel Labath   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
161e0119909SPavel Labath   if (!m_compile_units) {
162e0119909SPavel Labath     // Create an array of compile unit shared pointers -- which will each
163e0119909SPavel Labath     // remain NULL until someone asks for the actual compile unit information.
164e0119909SPavel Labath     m_compile_units.emplace(CalculateNumCompileUnits());
165e0119909SPavel Labath   }
166e0119909SPavel Labath   return m_compile_units->size();
167e0119909SPavel Labath }
168e0119909SPavel Labath 
169e0119909SPavel Labath CompUnitSP SymbolFile::GetCompileUnitAtIndex(uint32_t idx) {
170656ddeb2SPavel Labath   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
171e0119909SPavel Labath   uint32_t num = GetNumCompileUnits();
172e0119909SPavel Labath   if (idx >= num)
173e0119909SPavel Labath     return nullptr;
174e0119909SPavel Labath   lldb::CompUnitSP &cu_sp = (*m_compile_units)[idx];
175e0119909SPavel Labath   if (!cu_sp)
176e0119909SPavel Labath     cu_sp = ParseCompileUnitAtIndex(idx);
177e0119909SPavel Labath   return cu_sp;
178e0119909SPavel Labath }
179e0119909SPavel Labath 
180e0119909SPavel Labath void SymbolFile::SetCompileUnitAtIndex(uint32_t idx, const CompUnitSP &cu_sp) {
181e0119909SPavel Labath   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
182e0119909SPavel Labath   const size_t num_compile_units = GetNumCompileUnits();
183e0119909SPavel Labath   assert(idx < num_compile_units);
1842e959415SFangrui Song   (void)num_compile_units;
185e0119909SPavel Labath 
186e0119909SPavel Labath   // Fire off an assertion if this compile unit already exists for now. The
187e0119909SPavel Labath   // partial parsing should take care of only setting the compile unit
188e0119909SPavel Labath   // once, so if this assertion fails, we need to make sure that we don't
189e0119909SPavel Labath   // have a race condition, or have a second parse of the same compile
190e0119909SPavel Labath   // unit.
191e0119909SPavel Labath   assert((*m_compile_units)[idx] == nullptr);
192e0119909SPavel Labath   (*m_compile_units)[idx] = cu_sp;
193e0119909SPavel Labath }
194e0119909SPavel Labath 
19584a68569SPavel Labath Symtab *SymbolFile::GetSymtab() {
19684a68569SPavel Labath   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
19784a68569SPavel Labath   if (m_symtab)
19884a68569SPavel Labath     return m_symtab;
19984a68569SPavel Labath 
20084a68569SPavel Labath   // Fetch the symtab from the main object file.
201c2409baaSPavel Labath   m_symtab = GetMainObjectFile()->GetSymtab();
20284a68569SPavel Labath 
20384a68569SPavel Labath   // Then add our symbols to it.
20484a68569SPavel Labath   if (m_symtab)
20584a68569SPavel Labath     AddSymbols(*m_symtab);
20684a68569SPavel Labath 
20784a68569SPavel Labath   return m_symtab;
20884a68569SPavel Labath }
20984a68569SPavel Labath 
210c2409baaSPavel Labath void SymbolFile::SectionFileAddressesChanged() {
211c2409baaSPavel Labath   ObjectFile *module_objfile = GetMainObjectFile();
212c2409baaSPavel Labath   ObjectFile *symfile_objfile = GetObjectFile();
213c2409baaSPavel Labath   if (symfile_objfile != module_objfile)
214c2409baaSPavel Labath     symfile_objfile->SectionFileAddressesChanged();
215c2409baaSPavel Labath   if (m_symtab)
216c2409baaSPavel Labath     m_symtab->SectionFileAddressesChanged();
217c2409baaSPavel Labath }
218c2409baaSPavel Labath 
219e0119909SPavel Labath void SymbolFile::Dump(Stream &s) {
2205a7e1e97SPavel Labath   s.Format("SymbolFile {0} ({1})\n", GetPluginName(),
2215a7e1e97SPavel Labath            GetMainObjectFile()->GetFileSpec());
222f46e8974SPavel Labath   s.PutCString("Types:\n");
223f46e8974SPavel Labath   m_type_list.Dump(&s, /*show_context*/ false);
224f46e8974SPavel Labath   s.PutChar('\n');
225f46e8974SPavel Labath 
226e0119909SPavel Labath   s.PutCString("Compile units:\n");
227e0119909SPavel Labath   if (m_compile_units) {
228e0119909SPavel Labath     for (const CompUnitSP &cu_sp : *m_compile_units) {
229e0119909SPavel Labath       // We currently only dump the compile units that have been parsed
230e0119909SPavel Labath       if (cu_sp)
231e0119909SPavel Labath         cu_sp->Dump(&s, /*show_context*/ false);
232e0119909SPavel Labath     }
233e0119909SPavel Labath   }
234e0119909SPavel Labath   s.PutChar('\n');
235d5d47a35SPavel Labath 
236d5d47a35SPavel Labath   if (Symtab *symtab = GetSymtab())
237d5d47a35SPavel Labath     symtab->Dump(&s, nullptr, eSortOrderNone);
238e0119909SPavel Labath }
239e0119909SPavel Labath 
24022bbd7d6SPavel Labath SymbolFile::RegisterInfoResolver::~RegisterInfoResolver() = default;
2412887d9fdSGreg Clayton 
2422887d9fdSGreg Clayton uint64_t SymbolFile::GetDebugInfoSize() {
2432887d9fdSGreg Clayton   if (!m_objfile_sp)
2442887d9fdSGreg Clayton     return 0;
2452887d9fdSGreg Clayton   ModuleSP module_sp(m_objfile_sp->GetModule());
2462887d9fdSGreg Clayton   if (!module_sp)
2472887d9fdSGreg Clayton     return 0;
2482887d9fdSGreg Clayton   const SectionList *section_list = module_sp->GetSectionList();
2492887d9fdSGreg Clayton   if (section_list)
2502887d9fdSGreg Clayton     return section_list->GetDebugInfoSize();
2512887d9fdSGreg Clayton   return 0;
2522887d9fdSGreg Clayton }
253