xref: /freebsd/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFile.h (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
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 
12bdd1243dSDimitry 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"
255f757f3fSDimitry Andric #include "lldb/Utility/StructuredData.h"
265ffd83dbSDimitry Andric #include "lldb/Utility/XcodeSDK.h"
270b57cec5SDimitry Andric #include "lldb/lldb-private.h"
280b57cec5SDimitry Andric #include "llvm/ADT/DenseSet.h"
2906c3fb27SDimitry Andric #include "llvm/ADT/SmallSet.h"
309dba64beSDimitry Andric #include "llvm/Support/Errc.h"
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric #include <mutex>
33bdd1243dSDimitry Andric #include <optional>
3406c3fb27SDimitry Andric #include <unordered_map>
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric #if defined(LLDB_CONFIGURATION_DEBUG)
370b57cec5SDimitry Andric #define ASSERT_MODULE_LOCK(expr) (expr->AssertModuleLock())
380b57cec5SDimitry Andric #else
390b57cec5SDimitry Andric #define ASSERT_MODULE_LOCK(expr) ((void)0)
400b57cec5SDimitry Andric #endif
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric namespace lldb_private {
430b57cec5SDimitry Andric 
4481ad6265SDimitry Andric /// Provides public interface for all SymbolFiles. Any protected
4581ad6265SDimitry Andric /// virtual members should go into SymbolFileCommon; most SymbolFile
4681ad6265SDimitry Andric /// implementations should inherit from SymbolFileCommon to override
4781ad6265SDimitry Andric /// the behaviors except SymbolFileOnDemand which inherits
4881ad6265SDimitry Andric /// public interfaces from SymbolFile and forward to underlying concrete
4981ad6265SDimitry Andric /// SymbolFile implementation.
500b57cec5SDimitry Andric class SymbolFile : public PluginInterface {
51480093f4SDimitry Andric   /// LLVM RTTI support.
52480093f4SDimitry Andric   static char ID;
53480093f4SDimitry Andric 
540b57cec5SDimitry Andric public:
55480093f4SDimitry Andric   /// LLVM RTTI support.
56480093f4SDimitry Andric   /// \{
57480093f4SDimitry Andric   virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
58480093f4SDimitry Andric   static bool classof(const SymbolFile *obj) { return obj->isA(&ID); }
59480093f4SDimitry Andric   /// \}
60480093f4SDimitry Andric 
610b57cec5SDimitry Andric   // Symbol file ability bits.
620b57cec5SDimitry Andric   //
630b57cec5SDimitry Andric   // Each symbol file can claim to support one or more symbol file abilities.
640b57cec5SDimitry Andric   // These get returned from SymbolFile::GetAbilities(). These help us to
650b57cec5SDimitry Andric   // determine which plug-in will be best to load the debug information found
660b57cec5SDimitry Andric   // in files.
670b57cec5SDimitry Andric   enum Abilities {
680b57cec5SDimitry Andric     CompileUnits = (1u << 0),
690b57cec5SDimitry Andric     LineTables = (1u << 1),
700b57cec5SDimitry Andric     Functions = (1u << 2),
710b57cec5SDimitry Andric     Blocks = (1u << 3),
720b57cec5SDimitry Andric     GlobalVariables = (1u << 4),
730b57cec5SDimitry Andric     LocalVariables = (1u << 5),
740b57cec5SDimitry Andric     VariableTypes = (1u << 6),
750b57cec5SDimitry Andric     kAllAbilities = ((1u << 7) - 1u)
760b57cec5SDimitry Andric   };
770b57cec5SDimitry Andric 
789dba64beSDimitry Andric   static SymbolFile *FindPlugin(lldb::ObjectFileSP objfile_sp);
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   // Constructors and Destructors
8181ad6265SDimitry Andric   SymbolFile() = default;
820b57cec5SDimitry Andric 
83fe6060f1SDimitry Andric   ~SymbolFile() override = default;
840b57cec5SDimitry Andric 
8581ad6265SDimitry Andric   /// SymbolFileOnDemand class overrides this to return the underlying
8681ad6265SDimitry Andric   /// backing SymbolFile implementation that loads on-demand.
8781ad6265SDimitry Andric   virtual SymbolFile *GetBackingSymbolFile() { return this; }
8881ad6265SDimitry Andric 
890b57cec5SDimitry Andric   /// Get a mask of what this symbol file supports for the object file
900b57cec5SDimitry Andric   /// that it was constructed with.
910b57cec5SDimitry Andric   ///
920b57cec5SDimitry Andric   /// Each symbol file gets to respond with a mask of abilities that
930b57cec5SDimitry Andric   /// it supports for each object file. This happens when we are
940b57cec5SDimitry Andric   /// trying to figure out which symbol file plug-in will get used
950b57cec5SDimitry Andric   /// for a given object file. The plug-in that responds with the
960b57cec5SDimitry Andric   /// best mix of "SymbolFile::Abilities" bits set, will get chosen to
970b57cec5SDimitry Andric   /// be the symbol file parser. This allows each plug-in to check for
980b57cec5SDimitry Andric   /// sections that contain data a symbol file plug-in would need. For
990b57cec5SDimitry Andric   /// example the DWARF plug-in requires DWARF sections in a file that
1000b57cec5SDimitry Andric   /// contain debug information. If the DWARF plug-in doesn't find
1010b57cec5SDimitry Andric   /// these sections, it won't respond with many ability bits set, and
1020b57cec5SDimitry Andric   /// we will probably fall back to the symbol table SymbolFile plug-in
1030b57cec5SDimitry Andric   /// which uses any information in the symbol table. Also, plug-ins
1040b57cec5SDimitry Andric   /// might check for some specific symbols in a symbol table in the
1050b57cec5SDimitry Andric   /// case where the symbol table contains debug information (STABS
1060b57cec5SDimitry Andric   /// and COFF). Not a lot of work should happen in these functions
1070b57cec5SDimitry Andric   /// as the plug-in might not get selected due to another plug-in
1080b57cec5SDimitry Andric   /// having more abilities. Any initialization work should be saved
1090b57cec5SDimitry Andric   /// for "void SymbolFile::InitializeObject()" which will get called
1100b57cec5SDimitry Andric   /// on the SymbolFile object with the best set of abilities.
1110b57cec5SDimitry Andric   ///
1120b57cec5SDimitry Andric   /// \return
1130b57cec5SDimitry Andric   ///     A uint32_t mask containing bits from the SymbolFile::Abilities
1140b57cec5SDimitry Andric   ///     enumeration. Any bits that are set represent an ability that
1150b57cec5SDimitry Andric   ///     this symbol plug-in can parse from the object file.
11681ad6265SDimitry Andric   virtual uint32_t GetAbilities() = 0;
1170b57cec5SDimitry Andric   virtual uint32_t CalculateAbilities() = 0;
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric   /// Symbols file subclasses should override this to return the Module that
1200b57cec5SDimitry Andric   /// owns the TypeSystem that this symbol file modifies type information in.
1210b57cec5SDimitry Andric   virtual std::recursive_mutex &GetModuleMutex() const;
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric   /// Initialize the SymbolFile object.
1240b57cec5SDimitry Andric   ///
1250b57cec5SDimitry Andric   /// The SymbolFile object with the best set of abilities (detected
1260b57cec5SDimitry Andric   /// in "uint32_t SymbolFile::GetAbilities()) will have this function
1270b57cec5SDimitry Andric   /// called if it is chosen to parse an object file. More complete
1280b57cec5SDimitry Andric   /// initialization can happen in this function which will get called
1290b57cec5SDimitry Andric   /// prior to any other functions in the SymbolFile protocol.
1300b57cec5SDimitry Andric   virtual void InitializeObject() {}
1310b57cec5SDimitry Andric 
13281ad6265SDimitry Andric   /// Whether debug info will be loaded or not.
13381ad6265SDimitry Andric   ///
13481ad6265SDimitry Andric   /// It will be true for most implementations except SymbolFileOnDemand.
13581ad6265SDimitry Andric   virtual bool GetLoadDebugInfoEnabled() { return true; }
13681ad6265SDimitry Andric 
13781ad6265SDimitry Andric   /// Specify debug info should be loaded.
13881ad6265SDimitry Andric   ///
13981ad6265SDimitry Andric   /// It will be no-op for most implementations except SymbolFileOnDemand.
140fcaf7f86SDimitry Andric   virtual void SetLoadDebugInfoEnabled() {}
14181ad6265SDimitry Andric 
1420b57cec5SDimitry Andric   // Compile Unit function calls
1430b57cec5SDimitry Andric   // Approach 1 - iterator
14481ad6265SDimitry Andric   virtual uint32_t GetNumCompileUnits() = 0;
14581ad6265SDimitry Andric   virtual lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) = 0;
1469dba64beSDimitry Andric 
14781ad6265SDimitry Andric   virtual Symtab *GetSymtab() = 0;
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric   virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) = 0;
1505ffd83dbSDimitry Andric   /// Return the Xcode SDK comp_unit was compiled against.
1515ffd83dbSDimitry Andric   virtual XcodeSDK ParseXcodeSDK(CompileUnit &comp_unit) { return {}; }
15206c3fb27SDimitry Andric 
15306c3fb27SDimitry Andric   /// This function exists because SymbolFileDWARFDebugMap may extra compile
15406c3fb27SDimitry Andric   /// units which aren't exposed as "real" compile units. In every other
15506c3fb27SDimitry Andric   /// case this function should behave identically as ParseLanguage.
15606c3fb27SDimitry Andric   virtual llvm::SmallSet<lldb::LanguageType, 4>
15706c3fb27SDimitry Andric   ParseAllLanguages(CompileUnit &comp_unit) {
15806c3fb27SDimitry Andric     llvm::SmallSet<lldb::LanguageType, 4> langs;
15906c3fb27SDimitry Andric     langs.insert(ParseLanguage(comp_unit));
16006c3fb27SDimitry Andric     return langs;
16106c3fb27SDimitry Andric   }
16206c3fb27SDimitry Andric 
1630b57cec5SDimitry Andric   virtual size_t ParseFunctions(CompileUnit &comp_unit) = 0;
1640b57cec5SDimitry Andric   virtual bool ParseLineTable(CompileUnit &comp_unit) = 0;
1650b57cec5SDimitry Andric   virtual bool ParseDebugMacros(CompileUnit &comp_unit) = 0;
166480093f4SDimitry Andric 
167480093f4SDimitry Andric   /// Apply a lambda to each external lldb::Module referenced by this
168480093f4SDimitry Andric   /// \p comp_unit. Recursively also descends into the referenced external
169480093f4SDimitry Andric   /// modules of any encountered compilation unit.
170480093f4SDimitry Andric   ///
1715ffd83dbSDimitry Andric   /// This function can be used to traverse Clang -gmodules debug
1725ffd83dbSDimitry Andric   /// information, which is stored in DWARF files separate from the
1735ffd83dbSDimitry Andric   /// object files.
1745ffd83dbSDimitry Andric   ///
175480093f4SDimitry Andric   /// \param comp_unit
176480093f4SDimitry Andric   ///     When this SymbolFile consists of multiple auxilliary
177480093f4SDimitry Andric   ///     SymbolFiles, for example, a Darwin debug map that references
178480093f4SDimitry Andric   ///     multiple .o files, comp_unit helps choose the auxilliary
179480093f4SDimitry Andric   ///     file. In most other cases comp_unit's symbol file is
1805ffd83dbSDimitry Andric   ///     identical with *this.
181480093f4SDimitry Andric   ///
182480093f4SDimitry Andric   /// \param[in] lambda
183480093f4SDimitry Andric   ///     The lambda that should be applied to every function. The lambda can
184480093f4SDimitry Andric   ///     return true if the iteration should be aborted earlier.
185480093f4SDimitry Andric   ///
186480093f4SDimitry Andric   /// \param visited_symbol_files
187480093f4SDimitry Andric   ///     A set of SymbolFiles that were already visited to avoid
188480093f4SDimitry Andric   ///     visiting one file more than once.
189480093f4SDimitry Andric   ///
190480093f4SDimitry Andric   /// \return
191480093f4SDimitry Andric   ///     If the lambda early-exited, this function returns true to
192480093f4SDimitry Andric   ///     propagate the early exit.
193480093f4SDimitry Andric   virtual bool ForEachExternalModule(
194480093f4SDimitry Andric       lldb_private::CompileUnit &comp_unit,
195480093f4SDimitry Andric       llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files,
196480093f4SDimitry Andric       llvm::function_ref<bool(Module &)> lambda) {
197480093f4SDimitry Andric     return false;
198480093f4SDimitry Andric   }
1990b57cec5SDimitry Andric   virtual bool ParseSupportFiles(CompileUnit &comp_unit,
200*1db9f3b2SDimitry Andric                                  SupportFileList &support_files) = 0;
2010b57cec5SDimitry Andric   virtual size_t ParseTypes(CompileUnit &comp_unit) = 0;
2020b57cec5SDimitry Andric   virtual bool ParseIsOptimized(CompileUnit &comp_unit) { return false; }
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric   virtual bool
2050b57cec5SDimitry Andric   ParseImportedModules(const SymbolContext &sc,
2060b57cec5SDimitry Andric                        std::vector<SourceModule> &imported_modules) = 0;
2070b57cec5SDimitry Andric   virtual size_t ParseBlocksRecursive(Function &func) = 0;
2080b57cec5SDimitry Andric   virtual size_t ParseVariablesForContext(const SymbolContext &sc) = 0;
2090b57cec5SDimitry Andric   virtual Type *ResolveTypeUID(lldb::user_id_t type_uid) = 0;
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   /// The characteristics of an array type.
2120b57cec5SDimitry Andric   struct ArrayInfo {
2130b57cec5SDimitry Andric     int64_t first_index = 0;
2140b57cec5SDimitry Andric     llvm::SmallVector<uint64_t, 1> element_orders;
2150b57cec5SDimitry Andric     uint32_t byte_stride = 0;
2160b57cec5SDimitry Andric     uint32_t bit_stride = 0;
2170b57cec5SDimitry Andric   };
2180b57cec5SDimitry Andric   /// If \c type_uid points to an array type, return its characteristics.
2190b57cec5SDimitry Andric   /// To support variable-length array types, this function takes an
2205ffd83dbSDimitry Andric   /// optional \p ExecutionContext. If \c exe_ctx is non-null, the
2210b57cec5SDimitry Andric   /// dynamic characteristics for that context are returned.
222bdd1243dSDimitry Andric   virtual std::optional<ArrayInfo>
2230b57cec5SDimitry Andric   GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,
2240b57cec5SDimitry Andric                             const lldb_private::ExecutionContext *exe_ctx) = 0;
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric   virtual bool CompleteType(CompilerType &compiler_type) = 0;
2270b57cec5SDimitry Andric   virtual void ParseDeclsForContext(CompilerDeclContext decl_ctx) {}
2285f757f3fSDimitry Andric   virtual CompilerDecl GetDeclForUID(lldb::user_id_t uid) { return {}; }
2290b57cec5SDimitry Andric   virtual CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) {
2305f757f3fSDimitry Andric     return {};
2310b57cec5SDimitry Andric   }
2320b57cec5SDimitry Andric   virtual CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) {
2335f757f3fSDimitry Andric     return {};
2345f757f3fSDimitry Andric   }
2355f757f3fSDimitry Andric   virtual std::vector<CompilerContext>
2365f757f3fSDimitry Andric   GetCompilerContextForUID(lldb::user_id_t uid) {
2375f757f3fSDimitry Andric     return {};
2380b57cec5SDimitry Andric   }
2390b57cec5SDimitry Andric   virtual uint32_t ResolveSymbolContext(const Address &so_addr,
2400b57cec5SDimitry Andric                                         lldb::SymbolContextItem resolve_scope,
2410b57cec5SDimitry Andric                                         SymbolContext &sc) = 0;
242bdd1243dSDimitry Andric 
243bdd1243dSDimitry Andric   /// Get an error that describes why variables might be missing for a given
244bdd1243dSDimitry Andric   /// symbol context.
245bdd1243dSDimitry Andric   ///
246bdd1243dSDimitry Andric   /// If there is an error in the debug information that prevents variables from
247bdd1243dSDimitry Andric   /// being fetched, this error will get filled in. If there is no debug
248bdd1243dSDimitry Andric   /// informaiton, no error should be returned. But if there is debug
249bdd1243dSDimitry Andric   /// information and something prevents the variables from being available a
250bdd1243dSDimitry Andric   /// valid error should be returned. Valid cases include:
251bdd1243dSDimitry Andric   /// - compiler option that removes variables (-gline-tables-only)
252bdd1243dSDimitry Andric   /// - missing external files
253bdd1243dSDimitry Andric   ///   - .dwo files in fission are not accessible or missing
254bdd1243dSDimitry Andric   ///   - .o files on darwin when not using dSYM files that are not accessible
255bdd1243dSDimitry Andric   ///     or missing
256bdd1243dSDimitry Andric   /// - mismatched exteral files
257bdd1243dSDimitry Andric   ///   - .dwo files in fission where the DWO ID doesn't match
258bdd1243dSDimitry Andric   ///   - .o files on darwin when modification timestamp doesn't match
259bdd1243dSDimitry Andric   /// - corrupted debug info
260bdd1243dSDimitry Andric   ///
261bdd1243dSDimitry Andric   /// \param[in] frame
262bdd1243dSDimitry Andric   ///   The stack frame to use as a basis for the context to check. The frame
263bdd1243dSDimitry Andric   ///   address can be used if there is not debug info due to it not being able
264bdd1243dSDimitry Andric   ///   to be loaded, or if there is a debug info context, like a compile unit,
265bdd1243dSDimitry Andric   ///   or function, it can be used to track down more information on why
266bdd1243dSDimitry Andric   ///   variables are missing.
267bdd1243dSDimitry Andric   ///
268bdd1243dSDimitry Andric   /// \returns
269bdd1243dSDimitry Andric   ///   An error specifying why there should have been debug info with variable
270bdd1243dSDimitry Andric   ///   information but the variables were not able to be resolved.
271bdd1243dSDimitry Andric   Status GetFrameVariableError(StackFrame &frame) {
272bdd1243dSDimitry Andric     Status err = CalculateFrameVariableError(frame);
273bdd1243dSDimitry Andric     if (err.Fail())
274bdd1243dSDimitry Andric       SetDebugInfoHadFrameVariableErrors();
275bdd1243dSDimitry Andric     return err;
276bdd1243dSDimitry Andric   }
277bdd1243dSDimitry Andric 
278bdd1243dSDimitry Andric   /// Subclasses will override this function to for GetFrameVariableError().
279bdd1243dSDimitry Andric   ///
280bdd1243dSDimitry Andric   /// This allows GetFrameVariableError() to set the member variable
281bdd1243dSDimitry Andric   /// m_debug_info_had_variable_errors correctly without users having to do it
282bdd1243dSDimitry Andric   /// manually which is error prone.
283bdd1243dSDimitry Andric   virtual Status CalculateFrameVariableError(StackFrame &frame) {
284bdd1243dSDimitry Andric     return Status();
285bdd1243dSDimitry Andric   }
286fe6060f1SDimitry Andric   virtual uint32_t
287fe6060f1SDimitry Andric   ResolveSymbolContext(const SourceLocationSpec &src_location_spec,
2880b57cec5SDimitry Andric                        lldb::SymbolContextItem resolve_scope,
2890b57cec5SDimitry Andric                        SymbolContextList &sc_list);
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric   virtual void DumpClangAST(Stream &s) {}
2925ffd83dbSDimitry Andric   virtual void FindGlobalVariables(ConstString name,
2935ffd83dbSDimitry Andric                                    const CompilerDeclContext &parent_decl_ctx,
2945ffd83dbSDimitry Andric                                    uint32_t max_matches,
2955ffd83dbSDimitry Andric                                    VariableList &variables);
2969dba64beSDimitry Andric   virtual void FindGlobalVariables(const RegularExpression &regex,
2970b57cec5SDimitry Andric                                    uint32_t max_matches,
2980b57cec5SDimitry Andric                                    VariableList &variables);
299bdd1243dSDimitry Andric   virtual void FindFunctions(const Module::LookupInfo &lookup_info,
3005ffd83dbSDimitry Andric                              const CompilerDeclContext &parent_decl_ctx,
3019dba64beSDimitry Andric                              bool include_inlines, SymbolContextList &sc_list);
3029dba64beSDimitry Andric   virtual void FindFunctions(const RegularExpression &regex,
3039dba64beSDimitry Andric                              bool include_inlines, SymbolContextList &sc_list);
3049dba64beSDimitry Andric 
3055f757f3fSDimitry Andric   /// Find types using a type-matching object that contains all search
3065f757f3fSDimitry Andric   /// parameters.
3075f757f3fSDimitry Andric   ///
3085f757f3fSDimitry Andric   /// \see lldb_private::TypeQuery
3095f757f3fSDimitry Andric   ///
3105f757f3fSDimitry Andric   /// \param[in] query
3115f757f3fSDimitry Andric   ///     A type matching object that contains all of the details of the type
3125f757f3fSDimitry Andric   ///     search.
3135f757f3fSDimitry Andric   ///
3145f757f3fSDimitry Andric   /// \param[in] results
3155f757f3fSDimitry Andric   ///     Any matching types will be populated into the \a results object using
3165f757f3fSDimitry Andric   ///     TypeMap::InsertUnique(...).
3175f757f3fSDimitry Andric   virtual void FindTypes(const TypeQuery &query, TypeResults &results) {}
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric   virtual void
3200b57cec5SDimitry Andric   GetMangledNamesForFunction(const std::string &scope_qualified_name,
3210b57cec5SDimitry Andric                              std::vector<ConstString> &mangled_names);
3229dba64beSDimitry Andric 
3239dba64beSDimitry Andric   virtual void GetTypes(lldb_private::SymbolContextScope *sc_scope,
3240b57cec5SDimitry Andric                         lldb::TypeClass type_mask,
3250b57cec5SDimitry Andric                         lldb_private::TypeList &type_list) = 0;
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric   virtual void PreloadSymbols();
3280b57cec5SDimitry Andric 
329bdd1243dSDimitry Andric   virtual llvm::Expected<lldb::TypeSystemSP>
33081ad6265SDimitry Andric   GetTypeSystemForLanguage(lldb::LanguageType language) = 0;
3310b57cec5SDimitry Andric 
33206c3fb27SDimitry Andric   /// Finds a namespace of name \ref name and whose parent
33306c3fb27SDimitry Andric   /// context is \ref parent_decl_ctx.
33406c3fb27SDimitry Andric   ///
33506c3fb27SDimitry Andric   /// If \code{.cpp} !parent_decl_ctx.IsValid() \endcode
33606c3fb27SDimitry Andric   /// then this function will consider all namespaces that
33706c3fb27SDimitry Andric   /// match the name. If \ref only_root_namespaces is
33806c3fb27SDimitry Andric   /// true, only consider in the search those DIEs that
33906c3fb27SDimitry Andric   /// represent top-level namespaces.
3400b57cec5SDimitry Andric   virtual CompilerDeclContext
34106c3fb27SDimitry Andric   FindNamespace(ConstString name, const CompilerDeclContext &parent_decl_ctx,
34206c3fb27SDimitry Andric                 bool only_root_namespaces = false) {
3430b57cec5SDimitry Andric     return CompilerDeclContext();
3440b57cec5SDimitry Andric   }
3450b57cec5SDimitry Andric 
34681ad6265SDimitry Andric   virtual ObjectFile *GetObjectFile() = 0;
34781ad6265SDimitry Andric   virtual const ObjectFile *GetObjectFile() const = 0;
34881ad6265SDimitry Andric   virtual ObjectFile *GetMainObjectFile() = 0;
3490b57cec5SDimitry Andric 
350480093f4SDimitry Andric   virtual std::vector<std::unique_ptr<CallEdge>>
351480093f4SDimitry Andric   ParseCallEdgesInFunction(UserID func_id) {
3520b57cec5SDimitry Andric     return {};
3530b57cec5SDimitry Andric   }
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric   virtual void AddSymbols(Symtab &symtab) {}
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric   /// Notify the SymbolFile that the file addresses in the Sections
3580b57cec5SDimitry Andric   /// for this module have been changed.
35981ad6265SDimitry Andric   virtual void SectionFileAddressesChanged() = 0;
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric   struct RegisterInfoResolver {
3620b57cec5SDimitry Andric     virtual ~RegisterInfoResolver(); // anchor
3630b57cec5SDimitry Andric 
3640b57cec5SDimitry Andric     virtual const RegisterInfo *ResolveName(llvm::StringRef name) const = 0;
3650b57cec5SDimitry Andric     virtual const RegisterInfo *ResolveNumber(lldb::RegisterKind kind,
3660b57cec5SDimitry Andric                                               uint32_t number) const = 0;
3670b57cec5SDimitry Andric   };
3680b57cec5SDimitry Andric   virtual lldb::UnwindPlanSP
3690b57cec5SDimitry Andric   GetUnwindPlan(const Address &address, const RegisterInfoResolver &resolver) {
3700b57cec5SDimitry Andric     return nullptr;
3710b57cec5SDimitry Andric   }
3720b57cec5SDimitry Andric 
3739dba64beSDimitry Andric   /// Return the number of stack bytes taken up by the parameters to this
3749dba64beSDimitry Andric   /// function.
3759dba64beSDimitry Andric   virtual llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) {
3769dba64beSDimitry Andric     return llvm::createStringError(make_error_code(llvm::errc::not_supported),
3779dba64beSDimitry Andric                                    "Operation not supported.");
3789dba64beSDimitry Andric   }
3799dba64beSDimitry Andric 
38081ad6265SDimitry Andric   virtual void Dump(Stream &s) = 0;
3810b57cec5SDimitry Andric 
382349cc55cSDimitry Andric   /// Metrics gathering functions
383349cc55cSDimitry Andric 
384349cc55cSDimitry Andric   /// Return the size in bytes of all debug information in the symbol file.
385349cc55cSDimitry Andric   ///
386349cc55cSDimitry Andric   /// If the debug information is contained in sections of an ObjectFile, then
387349cc55cSDimitry Andric   /// this call should add the size of all sections that contain debug
388349cc55cSDimitry Andric   /// information. Symbols the symbol tables are not considered debug
389349cc55cSDimitry Andric   /// information for this call to make it easy and quick for this number to be
390349cc55cSDimitry Andric   /// calculated. If the symbol file is all debug information, the size of the
391349cc55cSDimitry Andric   /// entire file should be returned. The default implementation of this
392349cc55cSDimitry Andric   /// function will iterate over all sections in a module and add up their
393349cc55cSDimitry Andric   /// debug info only section byte sizes.
39481ad6265SDimitry Andric   virtual uint64_t GetDebugInfoSize() = 0;
395349cc55cSDimitry Andric 
396349cc55cSDimitry Andric   /// Return the time taken to parse the debug information.
397349cc55cSDimitry Andric   ///
398349cc55cSDimitry Andric   /// \returns 0.0 if no information has been parsed or if there is
399349cc55cSDimitry Andric   /// no computational cost to parsing the debug information.
40004eeddc0SDimitry Andric   virtual StatsDuration::Duration GetDebugInfoParseTime() { return {}; }
401349cc55cSDimitry Andric 
402349cc55cSDimitry Andric   /// Return the time it took to index the debug information in the object
403349cc55cSDimitry Andric   /// file.
404349cc55cSDimitry Andric   ///
405349cc55cSDimitry Andric   /// \returns 0.0 if the file doesn't need to be indexed or if it
406349cc55cSDimitry Andric   /// hasn't been indexed yet, or a valid duration if it has.
40704eeddc0SDimitry Andric   virtual StatsDuration::Duration GetDebugInfoIndexTime() { return {}; }
40804eeddc0SDimitry Andric 
40981ad6265SDimitry Andric   /// Get the additional modules that this symbol file uses to parse debug info.
41081ad6265SDimitry Andric   ///
41181ad6265SDimitry Andric   /// Some debug info is stored in stand alone object files that are represented
41281ad6265SDimitry Andric   /// by unique modules that will show up in the statistics module list. Return
41381ad6265SDimitry Andric   /// a list of modules that are not in the target module list that this symbol
41481ad6265SDimitry Andric   /// file is currently using so that they can be tracked and assoicated with
41581ad6265SDimitry Andric   /// the module in the statistics.
41681ad6265SDimitry Andric   virtual ModuleList GetDebugInfoModules() { return ModuleList(); }
41781ad6265SDimitry Andric 
41804eeddc0SDimitry Andric   /// Accessors for the bool that indicates if the debug info index was loaded
41904eeddc0SDimitry Andric   /// from, or saved to the module index cache.
42004eeddc0SDimitry Andric   ///
42104eeddc0SDimitry Andric   /// In statistics it is handy to know if a module's debug info was loaded from
42204eeddc0SDimitry Andric   /// or saved to the cache. When the debug info index is loaded from the cache
42304eeddc0SDimitry Andric   /// startup times can be faster. When the cache is enabled and the debug info
42404eeddc0SDimitry Andric   /// index is saved to the cache, debug sessions can be slower. These accessors
42504eeddc0SDimitry Andric   /// can be accessed by the statistics and emitted to help track these costs.
42604eeddc0SDimitry Andric   /// \{
42781ad6265SDimitry Andric   virtual bool GetDebugInfoIndexWasLoadedFromCache() const = 0;
42881ad6265SDimitry Andric   virtual void SetDebugInfoIndexWasLoadedFromCache() = 0;
42981ad6265SDimitry Andric   virtual bool GetDebugInfoIndexWasSavedToCache() const = 0;
43081ad6265SDimitry Andric   virtual void SetDebugInfoIndexWasSavedToCache() = 0;
43104eeddc0SDimitry Andric   /// \}
432349cc55cSDimitry Andric 
433bdd1243dSDimitry Andric   /// Accessors for the bool that indicates if there was debug info, but errors
434bdd1243dSDimitry Andric   /// stopped variables from being able to be displayed correctly. See
435bdd1243dSDimitry Andric   /// GetFrameVariableError() for details on what are considered errors.
436bdd1243dSDimitry Andric   virtual bool GetDebugInfoHadFrameVariableErrors() const = 0;
437bdd1243dSDimitry Andric   virtual void SetDebugInfoHadFrameVariableErrors() = 0;
438bdd1243dSDimitry Andric 
4395f757f3fSDimitry Andric   /// Return true if separate debug info files are supported and this function
4405f757f3fSDimitry Andric   /// succeeded, false otherwise.
4415f757f3fSDimitry Andric   ///
4425f757f3fSDimitry Andric   /// \param[out] d
4435f757f3fSDimitry Andric   ///     If this function succeeded, then this will be a dictionary that
4445f757f3fSDimitry Andric   ///     contains the keys "type", "symfile", and "separate-debug-info-files".
4455f757f3fSDimitry Andric   ///     "type" can be used to assume the structure of each object in
4465f757f3fSDimitry Andric   ///     "separate-debug-info-files".
4475f757f3fSDimitry Andric   /// \param errors_only
4485f757f3fSDimitry Andric   ///     If true, then only return separate debug info files that encountered
4495f757f3fSDimitry Andric   ///     errors during loading. If false, then return all expected separate
4505f757f3fSDimitry Andric   ///     debug info files, regardless of whether they were successfully loaded.
4515f757f3fSDimitry Andric   virtual bool GetSeparateDebugInfo(StructuredData::Dictionary &d,
4525f757f3fSDimitry Andric                                     bool errors_only) {
4535f757f3fSDimitry Andric     return false;
4545f757f3fSDimitry Andric   };
4555f757f3fSDimitry Andric 
456bdd1243dSDimitry Andric   virtual lldb::TypeSP
457bdd1243dSDimitry Andric   MakeType(lldb::user_id_t uid, ConstString name,
458bdd1243dSDimitry Andric            std::optional<uint64_t> byte_size, SymbolContextScope *context,
459bdd1243dSDimitry Andric            lldb::user_id_t encoding_uid,
460bdd1243dSDimitry Andric            Type::EncodingDataType encoding_uid_type, const Declaration &decl,
461bdd1243dSDimitry Andric            const CompilerType &compiler_qual_type,
462bdd1243dSDimitry Andric            Type::ResolveState compiler_type_resolve_state,
463bdd1243dSDimitry Andric            uint32_t opaque_payload = 0) = 0;
464bdd1243dSDimitry Andric 
465bdd1243dSDimitry Andric   virtual lldb::TypeSP CopyType(const lldb::TypeSP &other_type) = 0;
466bdd1243dSDimitry Andric 
46706c3fb27SDimitry Andric   /// Returns a map of compilation unit to the compile option arguments
46806c3fb27SDimitry Andric   /// associated with that compilation unit.
46906c3fb27SDimitry Andric   std::unordered_map<lldb::CompUnitSP, Args> GetCompileOptions() {
47006c3fb27SDimitry Andric     std::unordered_map<lldb::CompUnitSP, Args> args;
47106c3fb27SDimitry Andric     GetCompileOptions(args);
47206c3fb27SDimitry Andric     return args;
47306c3fb27SDimitry Andric   }
47406c3fb27SDimitry Andric 
4750b57cec5SDimitry Andric protected:
4760b57cec5SDimitry Andric   void AssertModuleLock();
47781ad6265SDimitry Andric 
47806c3fb27SDimitry Andric   virtual void GetCompileOptions(
47906c3fb27SDimitry Andric       std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) {}
48006c3fb27SDimitry Andric 
48181ad6265SDimitry Andric private:
48281ad6265SDimitry Andric   SymbolFile(const SymbolFile &) = delete;
48381ad6265SDimitry Andric   const SymbolFile &operator=(const SymbolFile &) = delete;
48481ad6265SDimitry Andric };
48581ad6265SDimitry Andric 
48681ad6265SDimitry Andric /// Containing protected virtual methods for child classes to override.
48781ad6265SDimitry Andric /// Most actual SymbolFile implementations should inherit from this class.
48881ad6265SDimitry Andric class SymbolFileCommon : public SymbolFile {
48981ad6265SDimitry Andric   /// LLVM RTTI support.
49081ad6265SDimitry Andric   static char ID;
49181ad6265SDimitry Andric 
49281ad6265SDimitry Andric public:
49381ad6265SDimitry Andric   /// LLVM RTTI support.
49481ad6265SDimitry Andric   /// \{
49581ad6265SDimitry Andric   bool isA(const void *ClassID) const override {
49681ad6265SDimitry Andric     return ClassID == &ID || SymbolFile::isA(ClassID);
49781ad6265SDimitry Andric   }
49881ad6265SDimitry Andric   static bool classof(const SymbolFileCommon *obj) { return obj->isA(&ID); }
49981ad6265SDimitry Andric   /// \}
50081ad6265SDimitry Andric 
50181ad6265SDimitry Andric   // Constructors and Destructors
50281ad6265SDimitry Andric   SymbolFileCommon(lldb::ObjectFileSP objfile_sp)
50381ad6265SDimitry Andric       : m_objfile_sp(std::move(objfile_sp)) {}
50481ad6265SDimitry Andric 
50581ad6265SDimitry Andric   ~SymbolFileCommon() override = default;
50681ad6265SDimitry Andric 
50781ad6265SDimitry Andric   uint32_t GetAbilities() override {
50881ad6265SDimitry Andric     if (!m_calculated_abilities) {
50981ad6265SDimitry Andric       m_abilities = CalculateAbilities();
51081ad6265SDimitry Andric       m_calculated_abilities = true;
51181ad6265SDimitry Andric     }
51281ad6265SDimitry Andric     return m_abilities;
51381ad6265SDimitry Andric   }
51481ad6265SDimitry Andric 
51581ad6265SDimitry Andric   Symtab *GetSymtab() override;
51681ad6265SDimitry Andric 
51781ad6265SDimitry Andric   ObjectFile *GetObjectFile() override { return m_objfile_sp.get(); }
51881ad6265SDimitry Andric   const ObjectFile *GetObjectFile() const override {
51981ad6265SDimitry Andric     return m_objfile_sp.get();
52081ad6265SDimitry Andric   }
52181ad6265SDimitry Andric   ObjectFile *GetMainObjectFile() override;
52281ad6265SDimitry Andric 
52381ad6265SDimitry Andric   /// Notify the SymbolFile that the file addresses in the Sections
52481ad6265SDimitry Andric   /// for this module have been changed.
52581ad6265SDimitry Andric   void SectionFileAddressesChanged() override;
52681ad6265SDimitry Andric 
52781ad6265SDimitry Andric   // Compile Unit function calls
52881ad6265SDimitry Andric   // Approach 1 - iterator
52981ad6265SDimitry Andric   uint32_t GetNumCompileUnits() override;
53081ad6265SDimitry Andric   lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) override;
53181ad6265SDimitry Andric 
532bdd1243dSDimitry Andric   llvm::Expected<lldb::TypeSystemSP>
53381ad6265SDimitry Andric   GetTypeSystemForLanguage(lldb::LanguageType language) override;
53481ad6265SDimitry Andric 
53581ad6265SDimitry Andric   void Dump(Stream &s) override;
53681ad6265SDimitry Andric 
53781ad6265SDimitry Andric   uint64_t GetDebugInfoSize() override;
53881ad6265SDimitry Andric 
53981ad6265SDimitry Andric   bool GetDebugInfoIndexWasLoadedFromCache() const override {
54081ad6265SDimitry Andric     return m_index_was_loaded_from_cache;
54181ad6265SDimitry Andric   }
54281ad6265SDimitry Andric   void SetDebugInfoIndexWasLoadedFromCache() override {
54381ad6265SDimitry Andric     m_index_was_loaded_from_cache = true;
54481ad6265SDimitry Andric   }
54581ad6265SDimitry Andric   bool GetDebugInfoIndexWasSavedToCache() const override {
54681ad6265SDimitry Andric     return m_index_was_saved_to_cache;
54781ad6265SDimitry Andric   }
54881ad6265SDimitry Andric   void SetDebugInfoIndexWasSavedToCache() override {
54981ad6265SDimitry Andric     m_index_was_saved_to_cache = true;
55081ad6265SDimitry Andric   }
551bdd1243dSDimitry Andric   bool GetDebugInfoHadFrameVariableErrors() const override {
552bdd1243dSDimitry Andric     return m_debug_info_had_variable_errors;
553bdd1243dSDimitry Andric   }
554bdd1243dSDimitry Andric   void SetDebugInfoHadFrameVariableErrors() override {
555bdd1243dSDimitry Andric      m_debug_info_had_variable_errors = true;
556bdd1243dSDimitry Andric   }
557bdd1243dSDimitry Andric 
558bdd1243dSDimitry Andric   /// This function is used to create types that belong to a SymbolFile. The
559bdd1243dSDimitry Andric   /// symbol file will own a strong reference to the type in an internal type
560bdd1243dSDimitry Andric   /// list.
561bdd1243dSDimitry Andric   lldb::TypeSP MakeType(lldb::user_id_t uid, ConstString name,
562bdd1243dSDimitry Andric                         std::optional<uint64_t> byte_size,
563bdd1243dSDimitry Andric                         SymbolContextScope *context,
564bdd1243dSDimitry Andric                         lldb::user_id_t encoding_uid,
565bdd1243dSDimitry Andric                         Type::EncodingDataType encoding_uid_type,
566bdd1243dSDimitry Andric                         const Declaration &decl,
567bdd1243dSDimitry Andric                         const CompilerType &compiler_qual_type,
568bdd1243dSDimitry Andric                         Type::ResolveState compiler_type_resolve_state,
569bdd1243dSDimitry Andric                         uint32_t opaque_payload = 0) override {
570bdd1243dSDimitry Andric      lldb::TypeSP type_sp (new Type(
571bdd1243dSDimitry Andric          uid, this, name, byte_size, context, encoding_uid,
572bdd1243dSDimitry Andric          encoding_uid_type, decl, compiler_qual_type,
573bdd1243dSDimitry Andric          compiler_type_resolve_state, opaque_payload));
574bdd1243dSDimitry Andric      m_type_list.Insert(type_sp);
575bdd1243dSDimitry Andric      return type_sp;
576bdd1243dSDimitry Andric   }
577bdd1243dSDimitry Andric 
578bdd1243dSDimitry Andric   lldb::TypeSP CopyType(const lldb::TypeSP &other_type) override {
579bdd1243dSDimitry Andric      // Make sure the real symbol file matches when copying types.
580bdd1243dSDimitry Andric      if (GetBackingSymbolFile() != other_type->GetSymbolFile())
581bdd1243dSDimitry Andric       return lldb::TypeSP();
582bdd1243dSDimitry Andric      lldb::TypeSP type_sp(new Type(*other_type));
583bdd1243dSDimitry Andric      m_type_list.Insert(type_sp);
584bdd1243dSDimitry Andric      return type_sp;
585bdd1243dSDimitry Andric   }
58681ad6265SDimitry Andric 
58781ad6265SDimitry Andric protected:
5889dba64beSDimitry Andric   virtual uint32_t CalculateNumCompileUnits() = 0;
5899dba64beSDimitry Andric   virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx) = 0;
5909dba64beSDimitry Andric   virtual TypeList &GetTypeList() { return m_type_list; }
5919dba64beSDimitry Andric   void SetCompileUnitAtIndex(uint32_t idx, const lldb::CompUnitSP &cu_sp);
5929dba64beSDimitry Andric 
5939dba64beSDimitry Andric   lldb::ObjectFileSP m_objfile_sp; // Keep a reference to the object file in
5949dba64beSDimitry Andric                                    // case it isn't the same as the module
5959dba64beSDimitry Andric                                    // object file (debug symbols in a separate
5969dba64beSDimitry Andric                                    // file)
597bdd1243dSDimitry Andric   std::optional<std::vector<lldb::CompUnitSP>> m_compile_units;
5989dba64beSDimitry Andric   TypeList m_type_list;
59904eeddc0SDimitry Andric   uint32_t m_abilities = 0;
60004eeddc0SDimitry Andric   bool m_calculated_abilities = false;
60104eeddc0SDimitry Andric   bool m_index_was_loaded_from_cache = false;
60204eeddc0SDimitry Andric   bool m_index_was_saved_to_cache = false;
603bdd1243dSDimitry Andric   /// Set to true if any variable feteching errors have been found when calling
604bdd1243dSDimitry Andric   /// GetFrameVariableError(). This will be emitted in the "statistics dump"
605bdd1243dSDimitry Andric   /// information for a module.
606bdd1243dSDimitry Andric   bool m_debug_info_had_variable_errors = false;
6070b57cec5SDimitry Andric 
6080b57cec5SDimitry Andric private:
60981ad6265SDimitry Andric   SymbolFileCommon(const SymbolFileCommon &) = delete;
61081ad6265SDimitry Andric   const SymbolFileCommon &operator=(const SymbolFileCommon &) = delete;
611bdd1243dSDimitry Andric 
612bdd1243dSDimitry Andric   /// Do not use m_symtab directly, as it may be freed. Use GetSymtab()
613bdd1243dSDimitry Andric   /// to access it instead.
614bdd1243dSDimitry Andric   Symtab *m_symtab = nullptr;
6150b57cec5SDimitry Andric };
6160b57cec5SDimitry Andric 
6170b57cec5SDimitry Andric } // namespace lldb_private
6180b57cec5SDimitry Andric 
6195ffd83dbSDimitry Andric #endif // LLDB_SYMBOL_SYMBOLFILE_H
620