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 ®ex, 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 ®ex, 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