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