1254721Semaste//===-- SymbolFile.cpp ------------------------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste#include "lldb/Symbol/SymbolFile.h" 10254721Semaste 11254721Semaste#include "lldb/Core/Module.h" 12254721Semaste#include "lldb/Core/PluginManager.h" 13360784Sdim#include "lldb/Symbol/CompileUnit.h" 14254721Semaste#include "lldb/Symbol/ObjectFile.h" 15296417Sdim#include "lldb/Symbol/TypeMap.h" 16296417Sdim#include "lldb/Symbol/TypeSystem.h" 17296417Sdim#include "lldb/Symbol/VariableList.h" 18321369Sdim#include "lldb/Utility/Log.h" 19321369Sdim#include "lldb/Utility/StreamString.h" 20314564Sdim#include "lldb/lldb-private.h" 21254721Semaste 22344779Sdim#include <future> 23344779Sdim 24254721Semasteusing namespace lldb_private; 25360784Sdimusing namespace lldb; 26254721Semaste 27360784Sdimchar SymbolFile::ID; 28360784Sdim 29321369Sdimvoid SymbolFile::PreloadSymbols() { 30321369Sdim // No-op for most implementations. 31321369Sdim} 32321369Sdim 33344779Sdimstd::recursive_mutex &SymbolFile::GetModuleMutex() const { 34344779Sdim return GetObjectFile()->GetModule()->GetMutex(); 35344779Sdim} 36360784SdimObjectFile *SymbolFile::GetMainObjectFile() { 37360784Sdim return m_objfile_sp->GetModule()->GetObjectFile(); 38360784Sdim} 39344779Sdim 40360784SdimSymbolFile *SymbolFile::FindPlugin(ObjectFileSP objfile_sp) { 41353358Sdim std::unique_ptr<SymbolFile> best_symfile_up; 42360784Sdim if (objfile_sp != nullptr) { 43254721Semaste 44314564Sdim // We need to test the abilities of this section list. So create what it 45360784Sdim // would be with this new objfile_sp. 46360784Sdim lldb::ModuleSP module_sp(objfile_sp->GetModule()); 47314564Sdim if (module_sp) { 48314564Sdim // Default to the main module section list. 49314564Sdim ObjectFile *module_obj_file = module_sp->GetObjectFile(); 50360784Sdim if (module_obj_file != objfile_sp.get()) { 51314564Sdim // Make sure the main object file's sections are created 52314564Sdim module_obj_file->GetSectionList(); 53360784Sdim objfile_sp->CreateSections(*module_sp->GetUnifiedSectionList()); 54314564Sdim } 55314564Sdim } 56254721Semaste 57314564Sdim // TODO: Load any plug-ins in the appropriate plug-in search paths and 58314564Sdim // iterate over all of them to find the best one for the job. 59254721Semaste 60314564Sdim uint32_t best_symfile_abilities = 0; 61254721Semaste 62314564Sdim SymbolFileCreateInstance create_callback; 63314564Sdim for (uint32_t idx = 0; 64314564Sdim (create_callback = PluginManager::GetSymbolFileCreateCallbackAtIndex( 65314564Sdim idx)) != nullptr; 66314564Sdim ++idx) { 67360784Sdim std::unique_ptr<SymbolFile> curr_symfile_up(create_callback(objfile_sp)); 68314564Sdim 69353358Sdim if (curr_symfile_up) { 70353358Sdim const uint32_t sym_file_abilities = curr_symfile_up->GetAbilities(); 71314564Sdim if (sym_file_abilities > best_symfile_abilities) { 72314564Sdim best_symfile_abilities = sym_file_abilities; 73353358Sdim best_symfile_up.reset(curr_symfile_up.release()); 74341825Sdim // If any symbol file parser has all of the abilities, then we should 75341825Sdim // just stop looking. 76314564Sdim if ((kAllAbilities & sym_file_abilities) == kAllAbilities) 77314564Sdim break; 78254721Semaste } 79314564Sdim } 80254721Semaste } 81353358Sdim if (best_symfile_up) { 82341825Sdim // Let the winning symbol file parser initialize itself more completely 83341825Sdim // now that it has been chosen 84353358Sdim best_symfile_up->InitializeObject(); 85314564Sdim } 86314564Sdim } 87353358Sdim return best_symfile_up.release(); 88254721Semaste} 89254721Semaste 90360784Sdimllvm::Expected<TypeSystem &> 91360784SdimSymbolFile::GetTypeSystemForLanguage(lldb::LanguageType language) { 92360784Sdim auto type_system_or_err = 93360784Sdim m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language); 94360784Sdim if (type_system_or_err) { 95360784Sdim type_system_or_err->SetSymbolFile(this); 96360784Sdim } 97360784Sdim return type_system_or_err; 98254721Semaste} 99254721Semaste 100314564Sdimuint32_t SymbolFile::ResolveSymbolContext(const FileSpec &file_spec, 101314564Sdim uint32_t line, bool check_inlines, 102344779Sdim lldb::SymbolContextItem resolve_scope, 103314564Sdim SymbolContextList &sc_list) { 104314564Sdim return 0; 105296417Sdim} 106296417Sdim 107360784Sdimvoid SymbolFile::FindGlobalVariables(ConstString name, 108360784Sdim const CompilerDeclContext *parent_decl_ctx, 109360784Sdim uint32_t max_matches, 110360784Sdim VariableList &variables) {} 111296417Sdim 112360784Sdimvoid SymbolFile::FindGlobalVariables(const RegularExpression ®ex, 113360784Sdim uint32_t max_matches, 114360784Sdim VariableList &variables) {} 115296417Sdim 116360784Sdimvoid SymbolFile::FindFunctions(ConstString name, 117360784Sdim const CompilerDeclContext *parent_decl_ctx, 118360784Sdim lldb::FunctionNameType name_type_mask, 119360784Sdim bool include_inlines, 120360784Sdim SymbolContextList &sc_list) {} 121296417Sdim 122360784Sdimvoid SymbolFile::FindFunctions(const RegularExpression ®ex, 123360784Sdim bool include_inlines, 124360784Sdim SymbolContextList &sc_list) {} 125296417Sdim 126314564Sdimvoid SymbolFile::GetMangledNamesForFunction( 127314564Sdim const std::string &scope_qualified_name, 128314564Sdim std::vector<ConstString> &mangled_names) { 129314564Sdim return; 130296417Sdim} 131296417Sdim 132360784Sdimvoid SymbolFile::FindTypes( 133353358Sdim ConstString name, const CompilerDeclContext *parent_decl_ctx, 134360784Sdim uint32_t max_matches, 135314564Sdim llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 136360784Sdim TypeMap &types) {} 137296417Sdim 138360784Sdimvoid SymbolFile::FindTypes(llvm::ArrayRef<CompilerContext> pattern, 139360784Sdim LanguageSet languages, 140360784Sdim llvm::DenseSet<SymbolFile *> &searched_symbol_files, 141360784Sdim TypeMap &types) {} 142344779Sdim 143344779Sdimvoid SymbolFile::AssertModuleLock() { 144344779Sdim // The code below is too expensive to leave enabled in release builds. It's 145344779Sdim // enabled in debug builds or when the correct macro is set. 146344779Sdim#if defined(LLDB_CONFIGURATION_DEBUG) 147344779Sdim // We assert that we have to module lock by trying to acquire the lock from a 148344779Sdim // different thread. Note that we must abort if the result is true to 149344779Sdim // guarantee correctness. 150344779Sdim assert(std::async(std::launch::async, 151344779Sdim [this] { return this->GetModuleMutex().try_lock(); }) 152344779Sdim .get() == false && 153344779Sdim "Module is not locked"); 154344779Sdim#endif 155344779Sdim} 156353358Sdim 157360784Sdimuint32_t SymbolFile::GetNumCompileUnits() { 158360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 159360784Sdim if (!m_compile_units) { 160360784Sdim // Create an array of compile unit shared pointers -- which will each 161360784Sdim // remain NULL until someone asks for the actual compile unit information. 162360784Sdim m_compile_units.emplace(CalculateNumCompileUnits()); 163360784Sdim } 164360784Sdim return m_compile_units->size(); 165360784Sdim} 166360784Sdim 167360784SdimCompUnitSP SymbolFile::GetCompileUnitAtIndex(uint32_t idx) { 168360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 169360784Sdim uint32_t num = GetNumCompileUnits(); 170360784Sdim if (idx >= num) 171360784Sdim return nullptr; 172360784Sdim lldb::CompUnitSP &cu_sp = (*m_compile_units)[idx]; 173360784Sdim if (!cu_sp) 174360784Sdim cu_sp = ParseCompileUnitAtIndex(idx); 175360784Sdim return cu_sp; 176360784Sdim} 177360784Sdim 178360784Sdimvoid SymbolFile::SetCompileUnitAtIndex(uint32_t idx, const CompUnitSP &cu_sp) { 179360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 180360784Sdim const size_t num_compile_units = GetNumCompileUnits(); 181360784Sdim assert(idx < num_compile_units); 182360784Sdim (void)num_compile_units; 183360784Sdim 184360784Sdim // Fire off an assertion if this compile unit already exists for now. The 185360784Sdim // partial parsing should take care of only setting the compile unit 186360784Sdim // once, so if this assertion fails, we need to make sure that we don't 187360784Sdim // have a race condition, or have a second parse of the same compile 188360784Sdim // unit. 189360784Sdim assert((*m_compile_units)[idx] == nullptr); 190360784Sdim (*m_compile_units)[idx] = cu_sp; 191360784Sdim} 192360784Sdim 193360784SdimSymtab *SymbolFile::GetSymtab() { 194360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 195360784Sdim if (m_symtab) 196360784Sdim return m_symtab; 197360784Sdim 198360784Sdim // Fetch the symtab from the main object file. 199360784Sdim m_symtab = GetMainObjectFile()->GetSymtab(); 200360784Sdim 201360784Sdim // Then add our symbols to it. 202360784Sdim if (m_symtab) 203360784Sdim AddSymbols(*m_symtab); 204360784Sdim 205360784Sdim return m_symtab; 206360784Sdim} 207360784Sdim 208360784Sdimvoid SymbolFile::SectionFileAddressesChanged() { 209360784Sdim ObjectFile *module_objfile = GetMainObjectFile(); 210360784Sdim ObjectFile *symfile_objfile = GetObjectFile(); 211360784Sdim if (symfile_objfile != module_objfile) 212360784Sdim symfile_objfile->SectionFileAddressesChanged(); 213360784Sdim if (m_symtab) 214360784Sdim m_symtab->SectionFileAddressesChanged(); 215360784Sdim} 216360784Sdim 217360784Sdimvoid SymbolFile::Dump(Stream &s) { 218360784Sdim s.Format("SymbolFile {0} ({1})\n", GetPluginName(), 219360784Sdim GetMainObjectFile()->GetFileSpec()); 220360784Sdim s.PutCString("Types:\n"); 221360784Sdim m_type_list.Dump(&s, /*show_context*/ false); 222360784Sdim s.PutChar('\n'); 223360784Sdim 224360784Sdim s.PutCString("Compile units:\n"); 225360784Sdim if (m_compile_units) { 226360784Sdim for (const CompUnitSP &cu_sp : *m_compile_units) { 227360784Sdim // We currently only dump the compile units that have been parsed 228360784Sdim if (cu_sp) 229360784Sdim cu_sp->Dump(&s, /*show_context*/ false); 230360784Sdim } 231360784Sdim } 232360784Sdim s.PutChar('\n'); 233360784Sdim 234360784Sdim if (Symtab *symtab = GetSymtab()) 235360784Sdim symtab->Dump(&s, nullptr, eSortOrderNone); 236360784Sdim} 237360784Sdim 238353358SdimSymbolFile::RegisterInfoResolver::~RegisterInfoResolver() = default; 239