1 //===-- SymbolFile.cpp ----------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/Symbol/SymbolFile.h" 10 11 #include "lldb/Core/Module.h" 12 #include "lldb/Core/PluginManager.h" 13 #include "lldb/Symbol/CompileUnit.h" 14 #include "lldb/Symbol/ObjectFile.h" 15 #include "lldb/Symbol/SymbolFileOnDemand.h" 16 #include "lldb/Symbol/TypeMap.h" 17 #include "lldb/Symbol/TypeSystem.h" 18 #include "lldb/Symbol/VariableList.h" 19 #include "lldb/Utility/Log.h" 20 #include "lldb/Utility/StreamString.h" 21 #include "lldb/lldb-private.h" 22 23 #include <future> 24 25 using namespace lldb_private; 26 using namespace lldb; 27 28 char SymbolFile::ID; 29 char SymbolFileCommon::ID; 30 31 void SymbolFile::PreloadSymbols() { 32 // No-op for most implementations. 33 } 34 35 std::recursive_mutex &SymbolFile::GetModuleMutex() const { 36 return GetObjectFile()->GetModule()->GetMutex(); 37 } 38 39 SymbolFile *SymbolFile::FindPlugin(ObjectFileSP objfile_sp) { 40 std::unique_ptr<SymbolFile> best_symfile_up; 41 if (objfile_sp != nullptr) { 42 43 // We need to test the abilities of this section list. So create what it 44 // would be with this new objfile_sp. 45 lldb::ModuleSP module_sp(objfile_sp->GetModule()); 46 if (module_sp) { 47 // Default to the main module section list. 48 ObjectFile *module_obj_file = module_sp->GetObjectFile(); 49 if (module_obj_file != objfile_sp.get()) { 50 // Make sure the main object file's sections are created 51 module_obj_file->GetSectionList(); 52 objfile_sp->CreateSections(*module_sp->GetUnifiedSectionList()); 53 } 54 } 55 56 // TODO: Load any plug-ins in the appropriate plug-in search paths and 57 // iterate over all of them to find the best one for the job. 58 59 uint32_t best_symfile_abilities = 0; 60 61 SymbolFileCreateInstance create_callback; 62 for (uint32_t idx = 0; 63 (create_callback = PluginManager::GetSymbolFileCreateCallbackAtIndex( 64 idx)) != nullptr; 65 ++idx) { 66 std::unique_ptr<SymbolFile> curr_symfile_up(create_callback(objfile_sp)); 67 68 if (curr_symfile_up) { 69 const uint32_t sym_file_abilities = curr_symfile_up->GetAbilities(); 70 if (sym_file_abilities > best_symfile_abilities) { 71 best_symfile_abilities = sym_file_abilities; 72 best_symfile_up.reset(curr_symfile_up.release()); 73 // If any symbol file parser has all of the abilities, then we should 74 // just stop looking. 75 if ((kAllAbilities & sym_file_abilities) == kAllAbilities) 76 break; 77 } 78 } 79 } 80 if (best_symfile_up) { 81 // If symbol on-demand is enabled the winning symbol file parser is 82 // wrapped with SymbolFileOnDemand so that hydration of the debug info 83 // can be controlled to improve performance. 84 // 85 // Currently the supported on-demand symbol files include: 86 // executables, shared libraries and debug info files. 87 // 88 // To reduce unnecessary wrapping files with zero debug abilities are 89 // skipped. 90 ObjectFile::Type obj_file_type = objfile_sp->CalculateType(); 91 if (ModuleList::GetGlobalModuleListProperties().GetLoadSymbolOnDemand() && 92 best_symfile_abilities > 0 && 93 (obj_file_type == ObjectFile::eTypeExecutable || 94 obj_file_type == ObjectFile::eTypeSharedLibrary || 95 obj_file_type == ObjectFile::eTypeDebugInfo)) { 96 best_symfile_up = 97 std::make_unique<SymbolFileOnDemand>(std::move(best_symfile_up)); 98 } 99 // Let the winning symbol file parser initialize itself more completely 100 // now that it has been chosen 101 best_symfile_up->InitializeObject(); 102 } 103 } 104 return best_symfile_up.release(); 105 } 106 107 uint32_t 108 SymbolFile::ResolveSymbolContext(const SourceLocationSpec &src_location_spec, 109 lldb::SymbolContextItem resolve_scope, 110 SymbolContextList &sc_list) { 111 return 0; 112 } 113 114 void SymbolFile::FindGlobalVariables(ConstString name, 115 const CompilerDeclContext &parent_decl_ctx, 116 uint32_t max_matches, 117 VariableList &variables) {} 118 119 void SymbolFile::FindGlobalVariables(const RegularExpression ®ex, 120 uint32_t max_matches, 121 VariableList &variables) {} 122 123 void SymbolFile::FindFunctions(ConstString name, 124 const CompilerDeclContext &parent_decl_ctx, 125 lldb::FunctionNameType name_type_mask, 126 bool include_inlines, 127 SymbolContextList &sc_list) {} 128 129 void SymbolFile::FindFunctions(const RegularExpression ®ex, 130 bool include_inlines, 131 SymbolContextList &sc_list) {} 132 133 void SymbolFile::GetMangledNamesForFunction( 134 const std::string &scope_qualified_name, 135 std::vector<ConstString> &mangled_names) {} 136 137 void SymbolFile::FindTypes( 138 ConstString name, const CompilerDeclContext &parent_decl_ctx, 139 uint32_t max_matches, 140 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 141 TypeMap &types) {} 142 143 void SymbolFile::FindTypes(llvm::ArrayRef<CompilerContext> pattern, 144 LanguageSet languages, 145 llvm::DenseSet<SymbolFile *> &searched_symbol_files, 146 TypeMap &types) {} 147 148 void SymbolFile::AssertModuleLock() { 149 // The code below is too expensive to leave enabled in release builds. It's 150 // enabled in debug builds or when the correct macro is set. 151 #if defined(LLDB_CONFIGURATION_DEBUG) 152 // We assert that we have to module lock by trying to acquire the lock from a 153 // different thread. Note that we must abort if the result is true to 154 // guarantee correctness. 155 assert(std::async( 156 std::launch::async, 157 [this] { 158 return this->GetModuleMutex().try_lock(); 159 }).get() == false && 160 "Module is not locked"); 161 #endif 162 } 163 164 SymbolFile::RegisterInfoResolver::~RegisterInfoResolver() = default; 165 166 Symtab *SymbolFileCommon::GetSymtab() { 167 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 168 if (m_symtab) 169 return m_symtab; 170 171 // Fetch the symtab from the main object file. 172 m_symtab = GetMainObjectFile()->GetSymtab(); 173 174 // Then add our symbols to it. 175 if (m_symtab) 176 AddSymbols(*m_symtab); 177 178 return m_symtab; 179 } 180 181 ObjectFile *SymbolFileCommon::GetMainObjectFile() { 182 return m_objfile_sp->GetModule()->GetObjectFile(); 183 } 184 185 void SymbolFileCommon::SectionFileAddressesChanged() { 186 ObjectFile *module_objfile = GetMainObjectFile(); 187 ObjectFile *symfile_objfile = GetObjectFile(); 188 if (symfile_objfile != module_objfile) 189 symfile_objfile->SectionFileAddressesChanged(); 190 if (m_symtab) 191 m_symtab->SectionFileAddressesChanged(); 192 } 193 194 uint32_t SymbolFileCommon::GetNumCompileUnits() { 195 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 196 if (!m_compile_units) { 197 // Create an array of compile unit shared pointers -- which will each 198 // remain NULL until someone asks for the actual compile unit information. 199 m_compile_units.emplace(CalculateNumCompileUnits()); 200 } 201 return m_compile_units->size(); 202 } 203 204 CompUnitSP SymbolFileCommon::GetCompileUnitAtIndex(uint32_t idx) { 205 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 206 uint32_t num = GetNumCompileUnits(); 207 if (idx >= num) 208 return nullptr; 209 lldb::CompUnitSP &cu_sp = (*m_compile_units)[idx]; 210 if (!cu_sp) 211 cu_sp = ParseCompileUnitAtIndex(idx); 212 return cu_sp; 213 } 214 215 void SymbolFileCommon::SetCompileUnitAtIndex(uint32_t idx, 216 const CompUnitSP &cu_sp) { 217 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 218 const size_t num_compile_units = GetNumCompileUnits(); 219 assert(idx < num_compile_units); 220 (void)num_compile_units; 221 222 // Fire off an assertion if this compile unit already exists for now. The 223 // partial parsing should take care of only setting the compile unit 224 // once, so if this assertion fails, we need to make sure that we don't 225 // have a race condition, or have a second parse of the same compile 226 // unit. 227 assert((*m_compile_units)[idx] == nullptr); 228 (*m_compile_units)[idx] = cu_sp; 229 } 230 231 llvm::Expected<TypeSystem &> 232 SymbolFileCommon::GetTypeSystemForLanguage(lldb::LanguageType language) { 233 auto type_system_or_err = 234 m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language); 235 if (type_system_or_err) { 236 type_system_or_err->SetSymbolFile(this); 237 } 238 return type_system_or_err; 239 } 240 241 uint64_t SymbolFileCommon::GetDebugInfoSize() { 242 if (!m_objfile_sp) 243 return 0; 244 ModuleSP module_sp(m_objfile_sp->GetModule()); 245 if (!module_sp) 246 return 0; 247 const SectionList *section_list = module_sp->GetSectionList(); 248 if (section_list) 249 return section_list->GetDebugInfoSize(); 250 return 0; 251 } 252 253 void SymbolFileCommon::Dump(Stream &s) { 254 s.Format("SymbolFile {0} ({1})\n", GetPluginName(), 255 GetMainObjectFile()->GetFileSpec()); 256 s.PutCString("Types:\n"); 257 m_type_list.Dump(&s, /*show_context*/ false); 258 s.PutChar('\n'); 259 260 s.PutCString("Compile units:\n"); 261 if (m_compile_units) { 262 for (const CompUnitSP &cu_sp : *m_compile_units) { 263 // We currently only dump the compile units that have been parsed 264 if (cu_sp) 265 cu_sp->Dump(&s, /*show_context*/ false); 266 } 267 } 268 s.PutChar('\n'); 269 270 if (Symtab *symtab = GetSymtab()) 271 symtab->Dump(&s, nullptr, eSortOrderNone); 272 } 273