10b57cec5SDimitry Andric //===-- SymbolFile.h --------------------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 95ffd83dbSDimitry Andric #ifndef LLDB_SYMBOL_SYMBOLFILE_H 105ffd83dbSDimitry Andric #define LLDB_SYMBOL_SYMBOLFILE_H 110b57cec5SDimitry Andric 12*bdd1243dSDimitry Andric #include "lldb/Core/Module.h" 1381ad6265SDimitry Andric #include "lldb/Core/ModuleList.h" 140b57cec5SDimitry Andric #include "lldb/Core/PluginInterface.h" 15fe6060f1SDimitry Andric #include "lldb/Core/SourceLocationSpec.h" 160b57cec5SDimitry Andric #include "lldb/Symbol/CompilerDecl.h" 170b57cec5SDimitry Andric #include "lldb/Symbol/CompilerDeclContext.h" 180b57cec5SDimitry Andric #include "lldb/Symbol/CompilerType.h" 190b57cec5SDimitry Andric #include "lldb/Symbol/Function.h" 200b57cec5SDimitry Andric #include "lldb/Symbol/SourceModule.h" 210b57cec5SDimitry Andric #include "lldb/Symbol/Type.h" 229dba64beSDimitry Andric #include "lldb/Symbol/TypeList.h" 239dba64beSDimitry Andric #include "lldb/Symbol/TypeSystem.h" 24349cc55cSDimitry Andric #include "lldb/Target/Statistics.h" 255ffd83dbSDimitry Andric #include "lldb/Utility/XcodeSDK.h" 260b57cec5SDimitry Andric #include "lldb/lldb-private.h" 270b57cec5SDimitry Andric #include "llvm/ADT/DenseSet.h" 289dba64beSDimitry Andric #include "llvm/Support/Errc.h" 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric #include <mutex> 31*bdd1243dSDimitry Andric #include <optional> 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric #if defined(LLDB_CONFIGURATION_DEBUG) 340b57cec5SDimitry Andric #define ASSERT_MODULE_LOCK(expr) (expr->AssertModuleLock()) 350b57cec5SDimitry Andric #else 360b57cec5SDimitry Andric #define ASSERT_MODULE_LOCK(expr) ((void)0) 370b57cec5SDimitry Andric #endif 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric namespace lldb_private { 400b57cec5SDimitry Andric 4181ad6265SDimitry Andric /// Provides public interface for all SymbolFiles. Any protected 4281ad6265SDimitry Andric /// virtual members should go into SymbolFileCommon; most SymbolFile 4381ad6265SDimitry Andric /// implementations should inherit from SymbolFileCommon to override 4481ad6265SDimitry Andric /// the behaviors except SymbolFileOnDemand which inherits 4581ad6265SDimitry Andric /// public interfaces from SymbolFile and forward to underlying concrete 4681ad6265SDimitry Andric /// SymbolFile implementation. 470b57cec5SDimitry Andric class SymbolFile : public PluginInterface { 48480093f4SDimitry Andric /// LLVM RTTI support. 49480093f4SDimitry Andric static char ID; 50480093f4SDimitry Andric 510b57cec5SDimitry Andric public: 52480093f4SDimitry Andric /// LLVM RTTI support. 53480093f4SDimitry Andric /// \{ 54480093f4SDimitry Andric virtual bool isA(const void *ClassID) const { return ClassID == &ID; } 55480093f4SDimitry Andric static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } 56480093f4SDimitry Andric /// \} 57480093f4SDimitry Andric 580b57cec5SDimitry Andric // Symbol file ability bits. 590b57cec5SDimitry Andric // 600b57cec5SDimitry Andric // Each symbol file can claim to support one or more symbol file abilities. 610b57cec5SDimitry Andric // These get returned from SymbolFile::GetAbilities(). These help us to 620b57cec5SDimitry Andric // determine which plug-in will be best to load the debug information found 630b57cec5SDimitry Andric // in files. 640b57cec5SDimitry Andric enum Abilities { 650b57cec5SDimitry Andric CompileUnits = (1u << 0), 660b57cec5SDimitry Andric LineTables = (1u << 1), 670b57cec5SDimitry Andric Functions = (1u << 2), 680b57cec5SDimitry Andric Blocks = (1u << 3), 690b57cec5SDimitry Andric GlobalVariables = (1u << 4), 700b57cec5SDimitry Andric LocalVariables = (1u << 5), 710b57cec5SDimitry Andric VariableTypes = (1u << 6), 720b57cec5SDimitry Andric kAllAbilities = ((1u << 7) - 1u) 730b57cec5SDimitry Andric }; 740b57cec5SDimitry Andric 759dba64beSDimitry Andric static SymbolFile *FindPlugin(lldb::ObjectFileSP objfile_sp); 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric // Constructors and Destructors 7881ad6265SDimitry Andric SymbolFile() = default; 790b57cec5SDimitry Andric 80fe6060f1SDimitry Andric ~SymbolFile() override = default; 810b57cec5SDimitry Andric 8281ad6265SDimitry Andric /// SymbolFileOnDemand class overrides this to return the underlying 8381ad6265SDimitry Andric /// backing SymbolFile implementation that loads on-demand. 8481ad6265SDimitry Andric virtual SymbolFile *GetBackingSymbolFile() { return this; } 8581ad6265SDimitry Andric 860b57cec5SDimitry Andric /// Get a mask of what this symbol file supports for the object file 870b57cec5SDimitry Andric /// that it was constructed with. 880b57cec5SDimitry Andric /// 890b57cec5SDimitry Andric /// Each symbol file gets to respond with a mask of abilities that 900b57cec5SDimitry Andric /// it supports for each object file. This happens when we are 910b57cec5SDimitry Andric /// trying to figure out which symbol file plug-in will get used 920b57cec5SDimitry Andric /// for a given object file. The plug-in that responds with the 930b57cec5SDimitry Andric /// best mix of "SymbolFile::Abilities" bits set, will get chosen to 940b57cec5SDimitry Andric /// be the symbol file parser. This allows each plug-in to check for 950b57cec5SDimitry Andric /// sections that contain data a symbol file plug-in would need. For 960b57cec5SDimitry Andric /// example the DWARF plug-in requires DWARF sections in a file that 970b57cec5SDimitry Andric /// contain debug information. If the DWARF plug-in doesn't find 980b57cec5SDimitry Andric /// these sections, it won't respond with many ability bits set, and 990b57cec5SDimitry Andric /// we will probably fall back to the symbol table SymbolFile plug-in 1000b57cec5SDimitry Andric /// which uses any information in the symbol table. Also, plug-ins 1010b57cec5SDimitry Andric /// might check for some specific symbols in a symbol table in the 1020b57cec5SDimitry Andric /// case where the symbol table contains debug information (STABS 1030b57cec5SDimitry Andric /// and COFF). Not a lot of work should happen in these functions 1040b57cec5SDimitry Andric /// as the plug-in might not get selected due to another plug-in 1050b57cec5SDimitry Andric /// having more abilities. Any initialization work should be saved 1060b57cec5SDimitry Andric /// for "void SymbolFile::InitializeObject()" which will get called 1070b57cec5SDimitry Andric /// on the SymbolFile object with the best set of abilities. 1080b57cec5SDimitry Andric /// 1090b57cec5SDimitry Andric /// \return 1100b57cec5SDimitry Andric /// A uint32_t mask containing bits from the SymbolFile::Abilities 1110b57cec5SDimitry Andric /// enumeration. Any bits that are set represent an ability that 1120b57cec5SDimitry Andric /// this symbol plug-in can parse from the object file. 11381ad6265SDimitry Andric virtual uint32_t GetAbilities() = 0; 1140b57cec5SDimitry Andric virtual uint32_t CalculateAbilities() = 0; 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric /// Symbols file subclasses should override this to return the Module that 1170b57cec5SDimitry Andric /// owns the TypeSystem that this symbol file modifies type information in. 1180b57cec5SDimitry Andric virtual std::recursive_mutex &GetModuleMutex() const; 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric /// Initialize the SymbolFile object. 1210b57cec5SDimitry Andric /// 1220b57cec5SDimitry Andric /// The SymbolFile object with the best set of abilities (detected 1230b57cec5SDimitry Andric /// in "uint32_t SymbolFile::GetAbilities()) will have this function 1240b57cec5SDimitry Andric /// called if it is chosen to parse an object file. More complete 1250b57cec5SDimitry Andric /// initialization can happen in this function which will get called 1260b57cec5SDimitry Andric /// prior to any other functions in the SymbolFile protocol. 1270b57cec5SDimitry Andric virtual void InitializeObject() {} 1280b57cec5SDimitry Andric 12981ad6265SDimitry Andric /// Whether debug info will be loaded or not. 13081ad6265SDimitry Andric /// 13181ad6265SDimitry Andric /// It will be true for most implementations except SymbolFileOnDemand. 13281ad6265SDimitry Andric virtual bool GetLoadDebugInfoEnabled() { return true; } 13381ad6265SDimitry Andric 13481ad6265SDimitry Andric /// Specify debug info should be loaded. 13581ad6265SDimitry Andric /// 13681ad6265SDimitry Andric /// It will be no-op for most implementations except SymbolFileOnDemand. 137fcaf7f86SDimitry Andric virtual void SetLoadDebugInfoEnabled() {} 13881ad6265SDimitry Andric 1390b57cec5SDimitry Andric // Compile Unit function calls 1400b57cec5SDimitry Andric // Approach 1 - iterator 14181ad6265SDimitry Andric virtual uint32_t GetNumCompileUnits() = 0; 14281ad6265SDimitry Andric virtual lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) = 0; 1439dba64beSDimitry Andric 14481ad6265SDimitry Andric virtual Symtab *GetSymtab() = 0; 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) = 0; 1475ffd83dbSDimitry Andric /// Return the Xcode SDK comp_unit was compiled against. 1485ffd83dbSDimitry Andric virtual XcodeSDK ParseXcodeSDK(CompileUnit &comp_unit) { return {}; } 1490b57cec5SDimitry Andric virtual size_t ParseFunctions(CompileUnit &comp_unit) = 0; 1500b57cec5SDimitry Andric virtual bool ParseLineTable(CompileUnit &comp_unit) = 0; 1510b57cec5SDimitry Andric virtual bool ParseDebugMacros(CompileUnit &comp_unit) = 0; 152480093f4SDimitry Andric 153480093f4SDimitry Andric /// Apply a lambda to each external lldb::Module referenced by this 154480093f4SDimitry Andric /// \p comp_unit. Recursively also descends into the referenced external 155480093f4SDimitry Andric /// modules of any encountered compilation unit. 156480093f4SDimitry Andric /// 1575ffd83dbSDimitry Andric /// This function can be used to traverse Clang -gmodules debug 1585ffd83dbSDimitry Andric /// information, which is stored in DWARF files separate from the 1595ffd83dbSDimitry Andric /// object files. 1605ffd83dbSDimitry Andric /// 161480093f4SDimitry Andric /// \param comp_unit 162480093f4SDimitry Andric /// When this SymbolFile consists of multiple auxilliary 163480093f4SDimitry Andric /// SymbolFiles, for example, a Darwin debug map that references 164480093f4SDimitry Andric /// multiple .o files, comp_unit helps choose the auxilliary 165480093f4SDimitry Andric /// file. In most other cases comp_unit's symbol file is 1665ffd83dbSDimitry Andric /// identical with *this. 167480093f4SDimitry Andric /// 168480093f4SDimitry Andric /// \param[in] lambda 169480093f4SDimitry Andric /// The lambda that should be applied to every function. The lambda can 170480093f4SDimitry Andric /// return true if the iteration should be aborted earlier. 171480093f4SDimitry Andric /// 172480093f4SDimitry Andric /// \param visited_symbol_files 173480093f4SDimitry Andric /// A set of SymbolFiles that were already visited to avoid 174480093f4SDimitry Andric /// visiting one file more than once. 175480093f4SDimitry Andric /// 176480093f4SDimitry Andric /// \return 177480093f4SDimitry Andric /// If the lambda early-exited, this function returns true to 178480093f4SDimitry Andric /// propagate the early exit. 179480093f4SDimitry Andric virtual bool ForEachExternalModule( 180480093f4SDimitry Andric lldb_private::CompileUnit &comp_unit, 181480093f4SDimitry Andric llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files, 182480093f4SDimitry Andric llvm::function_ref<bool(Module &)> lambda) { 183480093f4SDimitry Andric return false; 184480093f4SDimitry Andric } 1850b57cec5SDimitry Andric virtual bool ParseSupportFiles(CompileUnit &comp_unit, 1860b57cec5SDimitry Andric FileSpecList &support_files) = 0; 1870b57cec5SDimitry Andric virtual size_t ParseTypes(CompileUnit &comp_unit) = 0; 1880b57cec5SDimitry Andric virtual bool ParseIsOptimized(CompileUnit &comp_unit) { return false; } 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric virtual bool 1910b57cec5SDimitry Andric ParseImportedModules(const SymbolContext &sc, 1920b57cec5SDimitry Andric std::vector<SourceModule> &imported_modules) = 0; 1930b57cec5SDimitry Andric virtual size_t ParseBlocksRecursive(Function &func) = 0; 1940b57cec5SDimitry Andric virtual size_t ParseVariablesForContext(const SymbolContext &sc) = 0; 1950b57cec5SDimitry Andric virtual Type *ResolveTypeUID(lldb::user_id_t type_uid) = 0; 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric /// The characteristics of an array type. 1980b57cec5SDimitry Andric struct ArrayInfo { 1990b57cec5SDimitry Andric int64_t first_index = 0; 2000b57cec5SDimitry Andric llvm::SmallVector<uint64_t, 1> element_orders; 2010b57cec5SDimitry Andric uint32_t byte_stride = 0; 2020b57cec5SDimitry Andric uint32_t bit_stride = 0; 2030b57cec5SDimitry Andric }; 2040b57cec5SDimitry Andric /// If \c type_uid points to an array type, return its characteristics. 2050b57cec5SDimitry Andric /// To support variable-length array types, this function takes an 2065ffd83dbSDimitry Andric /// optional \p ExecutionContext. If \c exe_ctx is non-null, the 2070b57cec5SDimitry Andric /// dynamic characteristics for that context are returned. 208*bdd1243dSDimitry Andric virtual std::optional<ArrayInfo> 2090b57cec5SDimitry Andric GetDynamicArrayInfoForUID(lldb::user_id_t type_uid, 2100b57cec5SDimitry Andric const lldb_private::ExecutionContext *exe_ctx) = 0; 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric virtual bool CompleteType(CompilerType &compiler_type) = 0; 2130b57cec5SDimitry Andric virtual void ParseDeclsForContext(CompilerDeclContext decl_ctx) {} 2140b57cec5SDimitry Andric virtual CompilerDecl GetDeclForUID(lldb::user_id_t uid) { 2150b57cec5SDimitry Andric return CompilerDecl(); 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric virtual CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) { 2180b57cec5SDimitry Andric return CompilerDeclContext(); 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric virtual CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) { 2210b57cec5SDimitry Andric return CompilerDeclContext(); 2220b57cec5SDimitry Andric } 2230b57cec5SDimitry Andric virtual uint32_t ResolveSymbolContext(const Address &so_addr, 2240b57cec5SDimitry Andric lldb::SymbolContextItem resolve_scope, 2250b57cec5SDimitry Andric SymbolContext &sc) = 0; 226*bdd1243dSDimitry Andric 227*bdd1243dSDimitry Andric /// Get an error that describes why variables might be missing for a given 228*bdd1243dSDimitry Andric /// symbol context. 229*bdd1243dSDimitry Andric /// 230*bdd1243dSDimitry Andric /// If there is an error in the debug information that prevents variables from 231*bdd1243dSDimitry Andric /// being fetched, this error will get filled in. If there is no debug 232*bdd1243dSDimitry Andric /// informaiton, no error should be returned. But if there is debug 233*bdd1243dSDimitry Andric /// information and something prevents the variables from being available a 234*bdd1243dSDimitry Andric /// valid error should be returned. Valid cases include: 235*bdd1243dSDimitry Andric /// - compiler option that removes variables (-gline-tables-only) 236*bdd1243dSDimitry Andric /// - missing external files 237*bdd1243dSDimitry Andric /// - .dwo files in fission are not accessible or missing 238*bdd1243dSDimitry Andric /// - .o files on darwin when not using dSYM files that are not accessible 239*bdd1243dSDimitry Andric /// or missing 240*bdd1243dSDimitry Andric /// - mismatched exteral files 241*bdd1243dSDimitry Andric /// - .dwo files in fission where the DWO ID doesn't match 242*bdd1243dSDimitry Andric /// - .o files on darwin when modification timestamp doesn't match 243*bdd1243dSDimitry Andric /// - corrupted debug info 244*bdd1243dSDimitry Andric /// 245*bdd1243dSDimitry Andric /// \param[in] frame 246*bdd1243dSDimitry Andric /// The stack frame to use as a basis for the context to check. The frame 247*bdd1243dSDimitry Andric /// address can be used if there is not debug info due to it not being able 248*bdd1243dSDimitry Andric /// to be loaded, or if there is a debug info context, like a compile unit, 249*bdd1243dSDimitry Andric /// or function, it can be used to track down more information on why 250*bdd1243dSDimitry Andric /// variables are missing. 251*bdd1243dSDimitry Andric /// 252*bdd1243dSDimitry Andric /// \returns 253*bdd1243dSDimitry Andric /// An error specifying why there should have been debug info with variable 254*bdd1243dSDimitry Andric /// information but the variables were not able to be resolved. 255*bdd1243dSDimitry Andric Status GetFrameVariableError(StackFrame &frame) { 256*bdd1243dSDimitry Andric Status err = CalculateFrameVariableError(frame); 257*bdd1243dSDimitry Andric if (err.Fail()) 258*bdd1243dSDimitry Andric SetDebugInfoHadFrameVariableErrors(); 259*bdd1243dSDimitry Andric return err; 260*bdd1243dSDimitry Andric } 261*bdd1243dSDimitry Andric 262*bdd1243dSDimitry Andric /// Subclasses will override this function to for GetFrameVariableError(). 263*bdd1243dSDimitry Andric /// 264*bdd1243dSDimitry Andric /// This allows GetFrameVariableError() to set the member variable 265*bdd1243dSDimitry Andric /// m_debug_info_had_variable_errors correctly without users having to do it 266*bdd1243dSDimitry Andric /// manually which is error prone. 267*bdd1243dSDimitry Andric virtual Status CalculateFrameVariableError(StackFrame &frame) { 268*bdd1243dSDimitry Andric return Status(); 269*bdd1243dSDimitry Andric } 270fe6060f1SDimitry Andric virtual uint32_t 271fe6060f1SDimitry Andric ResolveSymbolContext(const SourceLocationSpec &src_location_spec, 2720b57cec5SDimitry Andric lldb::SymbolContextItem resolve_scope, 2730b57cec5SDimitry Andric SymbolContextList &sc_list); 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric virtual void DumpClangAST(Stream &s) {} 2765ffd83dbSDimitry Andric virtual void FindGlobalVariables(ConstString name, 2775ffd83dbSDimitry Andric const CompilerDeclContext &parent_decl_ctx, 2785ffd83dbSDimitry Andric uint32_t max_matches, 2795ffd83dbSDimitry Andric VariableList &variables); 2809dba64beSDimitry Andric virtual void FindGlobalVariables(const RegularExpression ®ex, 2810b57cec5SDimitry Andric uint32_t max_matches, 2820b57cec5SDimitry Andric VariableList &variables); 283*bdd1243dSDimitry Andric virtual void FindFunctions(const Module::LookupInfo &lookup_info, 2845ffd83dbSDimitry Andric const CompilerDeclContext &parent_decl_ctx, 2859dba64beSDimitry Andric bool include_inlines, SymbolContextList &sc_list); 2869dba64beSDimitry Andric virtual void FindFunctions(const RegularExpression ®ex, 2879dba64beSDimitry Andric bool include_inlines, SymbolContextList &sc_list); 2889dba64beSDimitry Andric virtual void 2895ffd83dbSDimitry Andric FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx, 2909dba64beSDimitry Andric uint32_t max_matches, 2910b57cec5SDimitry Andric llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 2920b57cec5SDimitry Andric TypeMap &types); 2939dba64beSDimitry Andric 2949dba64beSDimitry Andric /// Find types specified by a CompilerContextPattern. 295480093f4SDimitry Andric /// \param languages 296480093f4SDimitry Andric /// Only return results in these languages. 297480093f4SDimitry Andric /// \param searched_symbol_files 298480093f4SDimitry Andric /// Prevents one file from being visited multiple times. 299480093f4SDimitry Andric virtual void 300480093f4SDimitry Andric FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages, 301480093f4SDimitry Andric llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 302480093f4SDimitry Andric TypeMap &types); 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric virtual void 3050b57cec5SDimitry Andric GetMangledNamesForFunction(const std::string &scope_qualified_name, 3060b57cec5SDimitry Andric std::vector<ConstString> &mangled_names); 3079dba64beSDimitry Andric 3089dba64beSDimitry Andric virtual void GetTypes(lldb_private::SymbolContextScope *sc_scope, 3090b57cec5SDimitry Andric lldb::TypeClass type_mask, 3100b57cec5SDimitry Andric lldb_private::TypeList &type_list) = 0; 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric virtual void PreloadSymbols(); 3130b57cec5SDimitry Andric 314*bdd1243dSDimitry Andric virtual llvm::Expected<lldb::TypeSystemSP> 31581ad6265SDimitry Andric GetTypeSystemForLanguage(lldb::LanguageType language) = 0; 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric virtual CompilerDeclContext 3185ffd83dbSDimitry Andric FindNamespace(ConstString name, const CompilerDeclContext &parent_decl_ctx) { 3190b57cec5SDimitry Andric return CompilerDeclContext(); 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric 32281ad6265SDimitry Andric virtual ObjectFile *GetObjectFile() = 0; 32381ad6265SDimitry Andric virtual const ObjectFile *GetObjectFile() const = 0; 32481ad6265SDimitry Andric virtual ObjectFile *GetMainObjectFile() = 0; 3250b57cec5SDimitry Andric 326480093f4SDimitry Andric virtual std::vector<std::unique_ptr<CallEdge>> 327480093f4SDimitry Andric ParseCallEdgesInFunction(UserID func_id) { 3280b57cec5SDimitry Andric return {}; 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric virtual void AddSymbols(Symtab &symtab) {} 3320b57cec5SDimitry Andric 3330b57cec5SDimitry Andric /// Notify the SymbolFile that the file addresses in the Sections 3340b57cec5SDimitry Andric /// for this module have been changed. 33581ad6265SDimitry Andric virtual void SectionFileAddressesChanged() = 0; 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric struct RegisterInfoResolver { 3380b57cec5SDimitry Andric virtual ~RegisterInfoResolver(); // anchor 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric virtual const RegisterInfo *ResolveName(llvm::StringRef name) const = 0; 3410b57cec5SDimitry Andric virtual const RegisterInfo *ResolveNumber(lldb::RegisterKind kind, 3420b57cec5SDimitry Andric uint32_t number) const = 0; 3430b57cec5SDimitry Andric }; 3440b57cec5SDimitry Andric virtual lldb::UnwindPlanSP 3450b57cec5SDimitry Andric GetUnwindPlan(const Address &address, const RegisterInfoResolver &resolver) { 3460b57cec5SDimitry Andric return nullptr; 3470b57cec5SDimitry Andric } 3480b57cec5SDimitry Andric 3499dba64beSDimitry Andric /// Return the number of stack bytes taken up by the parameters to this 3509dba64beSDimitry Andric /// function. 3519dba64beSDimitry Andric virtual llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) { 3529dba64beSDimitry Andric return llvm::createStringError(make_error_code(llvm::errc::not_supported), 3539dba64beSDimitry Andric "Operation not supported."); 3549dba64beSDimitry Andric } 3559dba64beSDimitry Andric 35681ad6265SDimitry Andric virtual void Dump(Stream &s) = 0; 3570b57cec5SDimitry Andric 358349cc55cSDimitry Andric /// Metrics gathering functions 359349cc55cSDimitry Andric 360349cc55cSDimitry Andric /// Return the size in bytes of all debug information in the symbol file. 361349cc55cSDimitry Andric /// 362349cc55cSDimitry Andric /// If the debug information is contained in sections of an ObjectFile, then 363349cc55cSDimitry Andric /// this call should add the size of all sections that contain debug 364349cc55cSDimitry Andric /// information. Symbols the symbol tables are not considered debug 365349cc55cSDimitry Andric /// information for this call to make it easy and quick for this number to be 366349cc55cSDimitry Andric /// calculated. If the symbol file is all debug information, the size of the 367349cc55cSDimitry Andric /// entire file should be returned. The default implementation of this 368349cc55cSDimitry Andric /// function will iterate over all sections in a module and add up their 369349cc55cSDimitry Andric /// debug info only section byte sizes. 37081ad6265SDimitry Andric virtual uint64_t GetDebugInfoSize() = 0; 371349cc55cSDimitry Andric 372349cc55cSDimitry Andric /// Return the time taken to parse the debug information. 373349cc55cSDimitry Andric /// 374349cc55cSDimitry Andric /// \returns 0.0 if no information has been parsed or if there is 375349cc55cSDimitry Andric /// no computational cost to parsing the debug information. 37604eeddc0SDimitry Andric virtual StatsDuration::Duration GetDebugInfoParseTime() { return {}; } 377349cc55cSDimitry Andric 378349cc55cSDimitry Andric /// Return the time it took to index the debug information in the object 379349cc55cSDimitry Andric /// file. 380349cc55cSDimitry Andric /// 381349cc55cSDimitry Andric /// \returns 0.0 if the file doesn't need to be indexed or if it 382349cc55cSDimitry Andric /// hasn't been indexed yet, or a valid duration if it has. 38304eeddc0SDimitry Andric virtual StatsDuration::Duration GetDebugInfoIndexTime() { return {}; } 38404eeddc0SDimitry Andric 38581ad6265SDimitry Andric /// Get the additional modules that this symbol file uses to parse debug info. 38681ad6265SDimitry Andric /// 38781ad6265SDimitry Andric /// Some debug info is stored in stand alone object files that are represented 38881ad6265SDimitry Andric /// by unique modules that will show up in the statistics module list. Return 38981ad6265SDimitry Andric /// a list of modules that are not in the target module list that this symbol 39081ad6265SDimitry Andric /// file is currently using so that they can be tracked and assoicated with 39181ad6265SDimitry Andric /// the module in the statistics. 39281ad6265SDimitry Andric virtual ModuleList GetDebugInfoModules() { return ModuleList(); } 39381ad6265SDimitry Andric 39404eeddc0SDimitry Andric /// Accessors for the bool that indicates if the debug info index was loaded 39504eeddc0SDimitry Andric /// from, or saved to the module index cache. 39604eeddc0SDimitry Andric /// 39704eeddc0SDimitry Andric /// In statistics it is handy to know if a module's debug info was loaded from 39804eeddc0SDimitry Andric /// or saved to the cache. When the debug info index is loaded from the cache 39904eeddc0SDimitry Andric /// startup times can be faster. When the cache is enabled and the debug info 40004eeddc0SDimitry Andric /// index is saved to the cache, debug sessions can be slower. These accessors 40104eeddc0SDimitry Andric /// can be accessed by the statistics and emitted to help track these costs. 40204eeddc0SDimitry Andric /// \{ 40381ad6265SDimitry Andric virtual bool GetDebugInfoIndexWasLoadedFromCache() const = 0; 40481ad6265SDimitry Andric virtual void SetDebugInfoIndexWasLoadedFromCache() = 0; 40581ad6265SDimitry Andric virtual bool GetDebugInfoIndexWasSavedToCache() const = 0; 40681ad6265SDimitry Andric virtual void SetDebugInfoIndexWasSavedToCache() = 0; 40704eeddc0SDimitry Andric /// \} 408349cc55cSDimitry Andric 409*bdd1243dSDimitry Andric /// Accessors for the bool that indicates if there was debug info, but errors 410*bdd1243dSDimitry Andric /// stopped variables from being able to be displayed correctly. See 411*bdd1243dSDimitry Andric /// GetFrameVariableError() for details on what are considered errors. 412*bdd1243dSDimitry Andric virtual bool GetDebugInfoHadFrameVariableErrors() const = 0; 413*bdd1243dSDimitry Andric virtual void SetDebugInfoHadFrameVariableErrors() = 0; 414*bdd1243dSDimitry Andric 415*bdd1243dSDimitry Andric virtual lldb::TypeSP 416*bdd1243dSDimitry Andric MakeType(lldb::user_id_t uid, ConstString name, 417*bdd1243dSDimitry Andric std::optional<uint64_t> byte_size, SymbolContextScope *context, 418*bdd1243dSDimitry Andric lldb::user_id_t encoding_uid, 419*bdd1243dSDimitry Andric Type::EncodingDataType encoding_uid_type, const Declaration &decl, 420*bdd1243dSDimitry Andric const CompilerType &compiler_qual_type, 421*bdd1243dSDimitry Andric Type::ResolveState compiler_type_resolve_state, 422*bdd1243dSDimitry Andric uint32_t opaque_payload = 0) = 0; 423*bdd1243dSDimitry Andric 424*bdd1243dSDimitry Andric virtual lldb::TypeSP CopyType(const lldb::TypeSP &other_type) = 0; 425*bdd1243dSDimitry Andric 4260b57cec5SDimitry Andric protected: 4270b57cec5SDimitry Andric void AssertModuleLock(); 42881ad6265SDimitry Andric 42981ad6265SDimitry Andric private: 43081ad6265SDimitry Andric SymbolFile(const SymbolFile &) = delete; 43181ad6265SDimitry Andric const SymbolFile &operator=(const SymbolFile &) = delete; 43281ad6265SDimitry Andric }; 43381ad6265SDimitry Andric 43481ad6265SDimitry Andric /// Containing protected virtual methods for child classes to override. 43581ad6265SDimitry Andric /// Most actual SymbolFile implementations should inherit from this class. 43681ad6265SDimitry Andric class SymbolFileCommon : public SymbolFile { 43781ad6265SDimitry Andric /// LLVM RTTI support. 43881ad6265SDimitry Andric static char ID; 43981ad6265SDimitry Andric 44081ad6265SDimitry Andric public: 44181ad6265SDimitry Andric /// LLVM RTTI support. 44281ad6265SDimitry Andric /// \{ 44381ad6265SDimitry Andric bool isA(const void *ClassID) const override { 44481ad6265SDimitry Andric return ClassID == &ID || SymbolFile::isA(ClassID); 44581ad6265SDimitry Andric } 44681ad6265SDimitry Andric static bool classof(const SymbolFileCommon *obj) { return obj->isA(&ID); } 44781ad6265SDimitry Andric /// \} 44881ad6265SDimitry Andric 44981ad6265SDimitry Andric // Constructors and Destructors 45081ad6265SDimitry Andric SymbolFileCommon(lldb::ObjectFileSP objfile_sp) 45181ad6265SDimitry Andric : m_objfile_sp(std::move(objfile_sp)) {} 45281ad6265SDimitry Andric 45381ad6265SDimitry Andric ~SymbolFileCommon() override = default; 45481ad6265SDimitry Andric 45581ad6265SDimitry Andric uint32_t GetAbilities() override { 45681ad6265SDimitry Andric if (!m_calculated_abilities) { 45781ad6265SDimitry Andric m_abilities = CalculateAbilities(); 45881ad6265SDimitry Andric m_calculated_abilities = true; 45981ad6265SDimitry Andric } 46081ad6265SDimitry Andric return m_abilities; 46181ad6265SDimitry Andric } 46281ad6265SDimitry Andric 46381ad6265SDimitry Andric Symtab *GetSymtab() override; 46481ad6265SDimitry Andric 46581ad6265SDimitry Andric ObjectFile *GetObjectFile() override { return m_objfile_sp.get(); } 46681ad6265SDimitry Andric const ObjectFile *GetObjectFile() const override { 46781ad6265SDimitry Andric return m_objfile_sp.get(); 46881ad6265SDimitry Andric } 46981ad6265SDimitry Andric ObjectFile *GetMainObjectFile() override; 47081ad6265SDimitry Andric 47181ad6265SDimitry Andric /// Notify the SymbolFile that the file addresses in the Sections 47281ad6265SDimitry Andric /// for this module have been changed. 47381ad6265SDimitry Andric void SectionFileAddressesChanged() override; 47481ad6265SDimitry Andric 47581ad6265SDimitry Andric // Compile Unit function calls 47681ad6265SDimitry Andric // Approach 1 - iterator 47781ad6265SDimitry Andric uint32_t GetNumCompileUnits() override; 47881ad6265SDimitry Andric lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) override; 47981ad6265SDimitry Andric 480*bdd1243dSDimitry Andric llvm::Expected<lldb::TypeSystemSP> 48181ad6265SDimitry Andric GetTypeSystemForLanguage(lldb::LanguageType language) override; 48281ad6265SDimitry Andric 48381ad6265SDimitry Andric void Dump(Stream &s) override; 48481ad6265SDimitry Andric 48581ad6265SDimitry Andric uint64_t GetDebugInfoSize() override; 48681ad6265SDimitry Andric 48781ad6265SDimitry Andric bool GetDebugInfoIndexWasLoadedFromCache() const override { 48881ad6265SDimitry Andric return m_index_was_loaded_from_cache; 48981ad6265SDimitry Andric } 49081ad6265SDimitry Andric void SetDebugInfoIndexWasLoadedFromCache() override { 49181ad6265SDimitry Andric m_index_was_loaded_from_cache = true; 49281ad6265SDimitry Andric } 49381ad6265SDimitry Andric bool GetDebugInfoIndexWasSavedToCache() const override { 49481ad6265SDimitry Andric return m_index_was_saved_to_cache; 49581ad6265SDimitry Andric } 49681ad6265SDimitry Andric void SetDebugInfoIndexWasSavedToCache() override { 49781ad6265SDimitry Andric m_index_was_saved_to_cache = true; 49881ad6265SDimitry Andric } 499*bdd1243dSDimitry Andric bool GetDebugInfoHadFrameVariableErrors() const override { 500*bdd1243dSDimitry Andric return m_debug_info_had_variable_errors; 501*bdd1243dSDimitry Andric } 502*bdd1243dSDimitry Andric void SetDebugInfoHadFrameVariableErrors() override { 503*bdd1243dSDimitry Andric m_debug_info_had_variable_errors = true; 504*bdd1243dSDimitry Andric } 505*bdd1243dSDimitry Andric 506*bdd1243dSDimitry Andric /// This function is used to create types that belong to a SymbolFile. The 507*bdd1243dSDimitry Andric /// symbol file will own a strong reference to the type in an internal type 508*bdd1243dSDimitry Andric /// list. 509*bdd1243dSDimitry Andric lldb::TypeSP MakeType(lldb::user_id_t uid, ConstString name, 510*bdd1243dSDimitry Andric std::optional<uint64_t> byte_size, 511*bdd1243dSDimitry Andric SymbolContextScope *context, 512*bdd1243dSDimitry Andric lldb::user_id_t encoding_uid, 513*bdd1243dSDimitry Andric Type::EncodingDataType encoding_uid_type, 514*bdd1243dSDimitry Andric const Declaration &decl, 515*bdd1243dSDimitry Andric const CompilerType &compiler_qual_type, 516*bdd1243dSDimitry Andric Type::ResolveState compiler_type_resolve_state, 517*bdd1243dSDimitry Andric uint32_t opaque_payload = 0) override { 518*bdd1243dSDimitry Andric lldb::TypeSP type_sp (new Type( 519*bdd1243dSDimitry Andric uid, this, name, byte_size, context, encoding_uid, 520*bdd1243dSDimitry Andric encoding_uid_type, decl, compiler_qual_type, 521*bdd1243dSDimitry Andric compiler_type_resolve_state, opaque_payload)); 522*bdd1243dSDimitry Andric m_type_list.Insert(type_sp); 523*bdd1243dSDimitry Andric return type_sp; 524*bdd1243dSDimitry Andric } 525*bdd1243dSDimitry Andric 526*bdd1243dSDimitry Andric lldb::TypeSP CopyType(const lldb::TypeSP &other_type) override { 527*bdd1243dSDimitry Andric // Make sure the real symbol file matches when copying types. 528*bdd1243dSDimitry Andric if (GetBackingSymbolFile() != other_type->GetSymbolFile()) 529*bdd1243dSDimitry Andric return lldb::TypeSP(); 530*bdd1243dSDimitry Andric lldb::TypeSP type_sp(new Type(*other_type)); 531*bdd1243dSDimitry Andric m_type_list.Insert(type_sp); 532*bdd1243dSDimitry Andric return type_sp; 533*bdd1243dSDimitry Andric } 53481ad6265SDimitry Andric 53581ad6265SDimitry Andric protected: 5369dba64beSDimitry Andric virtual uint32_t CalculateNumCompileUnits() = 0; 5379dba64beSDimitry Andric virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx) = 0; 5389dba64beSDimitry Andric virtual TypeList &GetTypeList() { return m_type_list; } 5399dba64beSDimitry Andric void SetCompileUnitAtIndex(uint32_t idx, const lldb::CompUnitSP &cu_sp); 5409dba64beSDimitry Andric 5419dba64beSDimitry Andric lldb::ObjectFileSP m_objfile_sp; // Keep a reference to the object file in 5429dba64beSDimitry Andric // case it isn't the same as the module 5439dba64beSDimitry Andric // object file (debug symbols in a separate 5449dba64beSDimitry Andric // file) 545*bdd1243dSDimitry Andric std::optional<std::vector<lldb::CompUnitSP>> m_compile_units; 5469dba64beSDimitry Andric TypeList m_type_list; 54704eeddc0SDimitry Andric uint32_t m_abilities = 0; 54804eeddc0SDimitry Andric bool m_calculated_abilities = false; 54904eeddc0SDimitry Andric bool m_index_was_loaded_from_cache = false; 55004eeddc0SDimitry Andric bool m_index_was_saved_to_cache = false; 551*bdd1243dSDimitry Andric /// Set to true if any variable feteching errors have been found when calling 552*bdd1243dSDimitry Andric /// GetFrameVariableError(). This will be emitted in the "statistics dump" 553*bdd1243dSDimitry Andric /// information for a module. 554*bdd1243dSDimitry Andric bool m_debug_info_had_variable_errors = false; 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andric private: 55781ad6265SDimitry Andric SymbolFileCommon(const SymbolFileCommon &) = delete; 55881ad6265SDimitry Andric const SymbolFileCommon &operator=(const SymbolFileCommon &) = delete; 559*bdd1243dSDimitry Andric 560*bdd1243dSDimitry Andric /// Do not use m_symtab directly, as it may be freed. Use GetSymtab() 561*bdd1243dSDimitry Andric /// to access it instead. 562*bdd1243dSDimitry Andric Symtab *m_symtab = nullptr; 5630b57cec5SDimitry Andric }; 5640b57cec5SDimitry Andric 5650b57cec5SDimitry Andric } // namespace lldb_private 5660b57cec5SDimitry Andric 5675ffd83dbSDimitry Andric #endif // LLDB_SYMBOL_SYMBOLFILE_H 568