1 //===-- SymbolVendor.cpp ----------------------------------------*- C++ -*-===// 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/SymbolVendor.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/SymbolFile.h" 16 #include "lldb/Utility/Stream.h" 17 18 using namespace lldb; 19 using namespace lldb_private; 20 21 // FindPlugin 22 // 23 // Platforms can register a callback to use when creating symbol vendors to 24 // allow for complex debug information file setups, and to also allow for 25 // finding separate debug information files. 26 SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp, 27 lldb_private::Stream *feedback_strm) { 28 std::unique_ptr<SymbolVendor> instance_up; 29 SymbolVendorCreateInstance create_callback; 30 31 for (size_t idx = 0; 32 (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex( 33 idx)) != nullptr; 34 ++idx) { 35 instance_up.reset(create_callback(module_sp, feedback_strm)); 36 37 if (instance_up) { 38 return instance_up.release(); 39 } 40 } 41 // The default implementation just tries to create debug information using 42 // the file representation for the module. 43 ObjectFileSP sym_objfile_sp; 44 FileSpec sym_spec = module_sp->GetSymbolFileFileSpec(); 45 if (sym_spec && sym_spec != module_sp->GetObjectFile()->GetFileSpec()) { 46 DataBufferSP data_sp; 47 offset_t data_offset = 0; 48 sym_objfile_sp = ObjectFile::FindPlugin( 49 module_sp, &sym_spec, 0, FileSystem::Instance().GetByteSize(sym_spec), 50 data_sp, data_offset); 51 } 52 if (!sym_objfile_sp) 53 sym_objfile_sp = module_sp->GetObjectFile()->shared_from_this(); 54 instance_up.reset(new SymbolVendor(module_sp)); 55 instance_up->AddSymbolFileRepresentation(sym_objfile_sp); 56 return instance_up.release(); 57 } 58 59 // SymbolVendor constructor 60 SymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp) 61 : ModuleChild(module_sp), m_sym_file_up() {} 62 63 // Destructor 64 SymbolVendor::~SymbolVendor() {} 65 66 // Add a representation given an object file. 67 void SymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp) { 68 ModuleSP module_sp(GetModule()); 69 if (module_sp) { 70 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 71 if (objfile_sp) 72 m_sym_file_up.reset(SymbolFile::FindPlugin(objfile_sp)); 73 } 74 } 75 76 size_t SymbolVendor::GetNumCompileUnits() { 77 if (m_sym_file_up) 78 return m_sym_file_up->GetNumCompileUnits(); 79 return 0; 80 } 81 82 lldb::LanguageType SymbolVendor::ParseLanguage(CompileUnit &comp_unit) { 83 if (m_sym_file_up) 84 return m_sym_file_up->ParseLanguage(comp_unit); 85 return eLanguageTypeUnknown; 86 } 87 88 size_t SymbolVendor::ParseFunctions(CompileUnit &comp_unit) { 89 if (m_sym_file_up) 90 return m_sym_file_up->ParseFunctions(comp_unit); 91 return 0; 92 } 93 94 bool SymbolVendor::ParseLineTable(CompileUnit &comp_unit) { 95 if (m_sym_file_up) 96 return m_sym_file_up->ParseLineTable(comp_unit); 97 return false; 98 } 99 100 bool SymbolVendor::ParseDebugMacros(CompileUnit &comp_unit) { 101 if (m_sym_file_up) 102 return m_sym_file_up->ParseDebugMacros(comp_unit); 103 return false; 104 } 105 bool SymbolVendor::ParseSupportFiles(CompileUnit &comp_unit, 106 FileSpecList &support_files) { 107 if (m_sym_file_up) 108 return m_sym_file_up->ParseSupportFiles(comp_unit, support_files); 109 return false; 110 } 111 112 bool SymbolVendor::ParseIsOptimized(CompileUnit &comp_unit) { 113 if (m_sym_file_up) 114 return m_sym_file_up->ParseIsOptimized(comp_unit); 115 return false; 116 } 117 118 bool SymbolVendor::ParseImportedModules( 119 const SymbolContext &sc, std::vector<SourceModule> &imported_modules) { 120 if (m_sym_file_up) 121 return m_sym_file_up->ParseImportedModules(sc, imported_modules); 122 return false; 123 } 124 125 size_t SymbolVendor::ParseBlocksRecursive(Function &func) { 126 if (m_sym_file_up) 127 return m_sym_file_up->ParseBlocksRecursive(func); 128 return 0; 129 } 130 131 size_t SymbolVendor::ParseTypes(CompileUnit &comp_unit) { 132 if (m_sym_file_up) 133 return m_sym_file_up->ParseTypes(comp_unit); 134 return 0; 135 } 136 137 size_t SymbolVendor::ParseVariablesForContext(const SymbolContext &sc) { 138 if (m_sym_file_up) 139 return m_sym_file_up->ParseVariablesForContext(sc); 140 return 0; 141 } 142 143 Type *SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid) { 144 if (m_sym_file_up) 145 return m_sym_file_up->ResolveTypeUID(type_uid); 146 return nullptr; 147 } 148 149 uint32_t SymbolVendor::ResolveSymbolContext(const Address &so_addr, 150 SymbolContextItem resolve_scope, 151 SymbolContext &sc) { 152 if (m_sym_file_up) 153 return m_sym_file_up->ResolveSymbolContext(so_addr, resolve_scope, sc); 154 return 0; 155 } 156 157 uint32_t SymbolVendor::ResolveSymbolContext(const FileSpec &file_spec, 158 uint32_t line, bool check_inlines, 159 SymbolContextItem resolve_scope, 160 SymbolContextList &sc_list) { 161 if (m_sym_file_up) 162 return m_sym_file_up->ResolveSymbolContext(file_spec, line, check_inlines, 163 resolve_scope, sc_list); 164 return 0; 165 } 166 167 size_t 168 SymbolVendor::FindGlobalVariables(ConstString name, 169 const CompilerDeclContext *parent_decl_ctx, 170 size_t max_matches, VariableList &variables) { 171 if (m_sym_file_up) 172 return m_sym_file_up->FindGlobalVariables(name, parent_decl_ctx, 173 max_matches, variables); 174 return 0; 175 } 176 177 size_t SymbolVendor::FindGlobalVariables(const RegularExpression ®ex, 178 size_t max_matches, 179 VariableList &variables) { 180 if (m_sym_file_up) 181 return m_sym_file_up->FindGlobalVariables(regex, max_matches, variables); 182 return 0; 183 } 184 185 size_t SymbolVendor::FindFunctions(ConstString name, 186 const CompilerDeclContext *parent_decl_ctx, 187 FunctionNameType name_type_mask, 188 bool include_inlines, bool append, 189 SymbolContextList &sc_list) { 190 if (m_sym_file_up) 191 return m_sym_file_up->FindFunctions(name, parent_decl_ctx, name_type_mask, 192 include_inlines, append, sc_list); 193 return 0; 194 } 195 196 size_t SymbolVendor::FindFunctions(const RegularExpression ®ex, 197 bool include_inlines, bool append, 198 SymbolContextList &sc_list) { 199 if (m_sym_file_up) 200 return m_sym_file_up->FindFunctions(regex, include_inlines, append, 201 sc_list); 202 return 0; 203 } 204 205 size_t SymbolVendor::FindTypes( 206 ConstString name, const CompilerDeclContext *parent_decl_ctx, 207 bool append, size_t max_matches, 208 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 209 TypeMap &types) { 210 if (m_sym_file_up) 211 return m_sym_file_up->FindTypes(name, parent_decl_ctx, append, max_matches, 212 searched_symbol_files, types); 213 if (!append) 214 types.Clear(); 215 return 0; 216 } 217 218 size_t SymbolVendor::FindTypes(const std::vector<CompilerContext> &context, 219 bool append, TypeMap &types) { 220 if (m_sym_file_up) 221 return m_sym_file_up->FindTypes(context, append, types); 222 if (!append) 223 types.Clear(); 224 return 0; 225 } 226 227 size_t SymbolVendor::GetTypes(SymbolContextScope *sc_scope, TypeClass type_mask, 228 lldb_private::TypeList &type_list) { 229 if (m_sym_file_up) 230 return m_sym_file_up->GetTypes(sc_scope, type_mask, type_list); 231 return 0; 232 } 233 234 CompilerDeclContext 235 SymbolVendor::FindNamespace(ConstString name, 236 const CompilerDeclContext *parent_decl_ctx) { 237 CompilerDeclContext namespace_decl_ctx; 238 if (m_sym_file_up) 239 namespace_decl_ctx = m_sym_file_up->FindNamespace(name, parent_decl_ctx); 240 return namespace_decl_ctx; 241 } 242 243 void SymbolVendor::Dump(Stream *s) { 244 ModuleSP module_sp(GetModule()); 245 if (module_sp) { 246 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 247 248 s->Printf("%p: ", static_cast<void *>(this)); 249 s->Indent(); 250 s->PutCString("SymbolVendor"); 251 if (m_sym_file_up) { 252 *s << " " << m_sym_file_up->GetPluginName(); 253 ObjectFile *objfile = m_sym_file_up->GetObjectFile(); 254 if (objfile) { 255 const FileSpec &objfile_file_spec = objfile->GetFileSpec(); 256 if (objfile_file_spec) { 257 s->PutCString(" ("); 258 objfile_file_spec.Dump(s); 259 s->PutChar(')'); 260 } 261 } 262 } 263 s->EOL(); 264 if (m_sym_file_up) 265 m_sym_file_up->Dump(*s); 266 s->IndentMore(); 267 268 if (Symtab *symtab = GetSymtab()) 269 symtab->Dump(s, nullptr, eSortOrderNone); 270 271 s->IndentLess(); 272 } 273 } 274 275 CompUnitSP SymbolVendor::GetCompileUnitAtIndex(size_t idx) { 276 if (m_sym_file_up) 277 return m_sym_file_up->GetCompileUnitAtIndex(idx); 278 return nullptr; 279 } 280 281 FileSpec SymbolVendor::GetMainFileSpec() const { 282 if (m_sym_file_up) { 283 const ObjectFile *symfile_objfile = m_sym_file_up->GetObjectFile(); 284 if (symfile_objfile) 285 return symfile_objfile->GetFileSpec(); 286 } 287 288 return FileSpec(); 289 } 290 291 Symtab *SymbolVendor::GetSymtab() { 292 if (m_sym_file_up) 293 return m_sym_file_up->GetSymtab(); 294 return nullptr; 295 } 296 297 void SymbolVendor::SectionFileAddressesChanged() { 298 if (m_sym_file_up) 299 m_sym_file_up->SectionFileAddressesChanged(); 300 } 301 302 // PluginInterface protocol 303 lldb_private::ConstString SymbolVendor::GetPluginName() { 304 static ConstString g_name("vendor-default"); 305 return g_name; 306 } 307 308 uint32_t SymbolVendor::GetPluginVersion() { return 1; } 309