brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.3 KiB · 11b982e Raw
344 lines · c
1//===-- SymbolFileNativePDB.h -----------------------------------*- 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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H10#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H11 12#include "lldb/Symbol/LineTable.h"13#include "lldb/Symbol/SymbolFile.h"14 15#include "llvm/ADT/DenseMap.h"16#include "llvm/DebugInfo/CodeView/CVRecord.h"17#include "llvm/DebugInfo/CodeView/SymbolRecord.h"18#include "llvm/DebugInfo/PDB/PDBTypes.h"19 20#include "CompileUnitIndex.h"21#include "PdbIndex.h"22#include "PdbAstBuilder.h"23#include <optional>24 25namespace clang {26class TagDecl;27}28 29namespace llvm {30namespace codeview {31class ClassRecord;32class EnumRecord;33class ModifierRecord;34class PointerRecord;35struct UnionRecord;36} // namespace codeview37} // namespace llvm38 39namespace lldb_private {40 41namespace npdb {42 43class SymbolFileNativePDB : public SymbolFileCommon {44  friend class UdtRecordCompleter;45 46  /// LLVM RTTI support.47  static char ID;48 49public:50  /// LLVM RTTI support.51  /// \{52  bool isA(const void *ClassID) const override {53    return ClassID == &ID || SymbolFileCommon::isA(ClassID);54  }55  static bool classof(const SymbolFile *obj) { return obj->isA(&ID); }56  /// \}57 58  // Static Functions59  static void Initialize();60 61  static void Terminate();62 63  static void DebuggerInitialize(Debugger &debugger);64 65  static llvm::StringRef GetPluginNameStatic() { return "native-pdb"; }66 67  static llvm::StringRef GetPluginDescriptionStatic();68 69  static SymbolFile *CreateInstance(lldb::ObjectFileSP objfile_sp);70 71  // Constructors and Destructors72  SymbolFileNativePDB(lldb::ObjectFileSP objfile_sp);73 74  ~SymbolFileNativePDB() override;75 76  uint32_t CalculateAbilities() override;77 78  void InitializeObject() override;79 80  uint64_t GetDebugInfoSize(bool load_all_debug_info = false) override;81 82  // Compile Unit function calls83 84  void85  ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;86 87  lldb::LanguageType88  ParseLanguage(lldb_private::CompileUnit &comp_unit) override;89 90  size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;91 92  bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;93 94  bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;95 96  bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,97                         SupportFileList &support_files) override;98  size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override;99 100  bool ParseImportedModules(101      const SymbolContext &sc,102      std::vector<lldb_private::SourceModule> &imported_modules) override;103 104  size_t ParseBlocksRecursive(Function &func) override;105 106  void FindGlobalVariables(ConstString name,107                           const CompilerDeclContext &parent_decl_ctx,108                           uint32_t max_matches,109                           VariableList &variables) override;110 111  size_t ParseVariablesForContext(const SymbolContext &sc) override;112 113  void AddSymbols(Symtab &symtab) override;114 115  CompilerDecl GetDeclForUID(lldb::user_id_t uid) override;116  CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override;117  CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override;118  Type *ResolveTypeUID(lldb::user_id_t type_uid) override;119  std::optional<ArrayInfo> GetDynamicArrayInfoForUID(120      lldb::user_id_t type_uid,121      const lldb_private::ExecutionContext *exe_ctx) override;122 123  bool CompleteType(CompilerType &compiler_type) override;124  uint32_t ResolveSymbolContext(const Address &so_addr,125                                lldb::SymbolContextItem resolve_scope,126                                SymbolContext &sc) override;127  uint32_t ResolveSymbolContext(const SourceLocationSpec &src_location_spec,128                                lldb::SymbolContextItem resolve_scope,129                                SymbolContextList &sc_list) override;130 131  void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,132                TypeList &type_list) override;133 134  void FindFunctions(const Module::LookupInfo &lookup_info,135                     const CompilerDeclContext &parent_decl_ctx,136                     bool include_inlines, SymbolContextList &sc_list) override;137 138  void FindFunctions(const RegularExpression &regex, bool include_inlines,139                     SymbolContextList &sc_list) override;140 141  std::optional<PdbCompilandSymId> FindSymbolScope(PdbCompilandSymId id);142 143  /// Find the mangled name for a function144  ///145  /// \param id A symbol ID of a S_LPROC32/S_GPROC32 record146  /// \returns The mangled name of the function (if available)147  std::optional<llvm::StringRef> FindMangledFunctionName(PdbCompilandSymId id);148 149  void FindTypes(const lldb_private::TypeQuery &match,150                 lldb_private::TypeResults &results) override;151 152  llvm::Expected<lldb::TypeSystemSP>153  GetTypeSystemForLanguage(lldb::LanguageType language) override;154 155  CompilerDeclContext FindNamespace(ConstString name,156                                    const CompilerDeclContext &parent_decl_ctx,157                                    bool only_root_namespaces) override;158 159  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }160 161  llvm::pdb::PDBFile &GetPDBFile() { return m_index->pdb(); }162  const llvm::pdb::PDBFile &GetPDBFile() const { return m_index->pdb(); }163 164  PdbIndex &GetIndex() { return *m_index; };165 166  void DumpClangAST(Stream &s, llvm::StringRef filter,167                    bool show_color) override;168 169  std::optional<llvm::codeview::TypeIndex>170  GetParentType(llvm::codeview::TypeIndex ti);171 172private:173  struct LineTableEntryComparator {174    bool operator()(const lldb_private::LineTable::Entry &lhs,175                    const lldb_private::LineTable::Entry &rhs) const {176      return lhs.file_addr < rhs.file_addr;177    }178  };179 180  // From address range relative to function base to source line number.181  using RangeSourceLineVector =182      lldb_private::RangeDataVector<uint32_t, uint32_t, int32_t>;183  // InlineSite contains information in a S_INLINESITE record.184  struct InlineSite {185    PdbCompilandSymId parent_id;186    std::shared_ptr<InlineFunctionInfo> inline_function_info;187    RangeSourceLineVector ranges;188    std::vector<lldb_private::LineTable::Entry> line_entries;189    InlineSite(PdbCompilandSymId parent_id) : parent_id(parent_id){};190  };191 192  void BuildParentMap();193 194  uint32_t CalculateNumCompileUnits() override;195 196  lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;197 198  void FindTypesByName(llvm::StringRef name, uint32_t max_matches,199                       TypeMap &types);200 201  lldb::TypeSP CreateModifierType(PdbTypeSymId type_id,202                                  const llvm::codeview::ModifierRecord &mr,203                                  CompilerType ct);204  lldb::TypeSP CreatePointerType(PdbTypeSymId type_id,205                                 const llvm::codeview::PointerRecord &pr,206                                 CompilerType ct);207  lldb::TypeSP CreateSimpleType(llvm::codeview::TypeIndex ti, CompilerType ct);208  lldb::TypeSP CreateTagType(PdbTypeSymId type_id,209                             const llvm::codeview::ClassRecord &cr,210                             CompilerType ct);211  lldb::TypeSP CreateTagType(PdbTypeSymId type_id,212                             const llvm::codeview::EnumRecord &er,213                             CompilerType ct);214  lldb::TypeSP CreateTagType(PdbTypeSymId type_id,215                             const llvm::codeview::UnionRecord &ur,216                             CompilerType ct);217  lldb::TypeSP CreateArrayType(PdbTypeSymId type_id,218                               const llvm::codeview::ArrayRecord &ar,219                               CompilerType ct);220  lldb::TypeSP CreateFunctionType(PdbTypeSymId type_id,221                                  const llvm::codeview::MemberFunctionRecord &pr,222                                  CompilerType ct);223  lldb::TypeSP CreateProcedureType(PdbTypeSymId type_id,224                                   const llvm::codeview::ProcedureRecord &pr,225                                   CompilerType ct);226  lldb::TypeSP CreateClassStructUnion(PdbTypeSymId type_id,227                                      const llvm::codeview::TagRecord &record,228                                      size_t size, CompilerType ct);229 230  lldb::FunctionSP GetOrCreateFunction(PdbCompilandSymId func_id,231                                       CompileUnit &comp_unit);232  lldb::CompUnitSP GetOrCreateCompileUnit(const CompilandIndexItem &cci);233  lldb::TypeSP GetOrCreateType(PdbTypeSymId type_id);234  lldb::TypeSP GetOrCreateType(llvm::codeview::TypeIndex ti);235  lldb::VariableSP GetOrCreateGlobalVariable(PdbGlobalSymId var_id);236  Block *GetOrCreateBlock(PdbCompilandSymId block_id);237  lldb::VariableSP GetOrCreateLocalVariable(PdbCompilandSymId scope_id,238                                            PdbCompilandSymId var_id,239                                            bool is_param);240  lldb::TypeSP GetOrCreateTypedef(PdbGlobalSymId id);241 242  lldb::FunctionSP CreateFunction(PdbCompilandSymId func_id,243                                  CompileUnit &comp_unit);244  Block *CreateBlock(PdbCompilandSymId block_id);245  lldb::VariableSP CreateLocalVariable(PdbCompilandSymId scope_id,246                                       PdbCompilandSymId var_id, bool is_param);247  lldb::TypeSP CreateTypedef(PdbGlobalSymId id);248  lldb::CompUnitSP CreateCompileUnit(const CompilandIndexItem &cci);249  lldb::TypeSP CreateType(PdbTypeSymId type_id, CompilerType ct);250  lldb::TypeSP CreateAndCacheType(PdbTypeSymId type_id);251  lldb::VariableSP CreateGlobalVariable(PdbGlobalSymId var_id);252  lldb::VariableSP CreateConstantSymbol(PdbGlobalSymId var_id,253                                        const llvm::codeview::CVSymbol &cvs);254  size_t ParseVariablesForCompileUnit(CompileUnit &comp_unit,255                                      VariableList &variables);256  size_t ParseVariablesForBlock(PdbCompilandSymId block_id);257 258  void CreateSimpleArgumentListTypes(llvm::codeview::TypeIndex arglist_ti);259 260  llvm::Expected<uint32_t> GetFileIndex(const CompilandIndexItem &cii,261                                        uint32_t file_id);262 263  size_t ParseSymbolArrayInScope(264      PdbCompilandSymId parent,265      llvm::function_ref<bool(llvm::codeview::SymbolKind, PdbCompilandSymId)>266          fn);267 268  void ParseInlineSite(PdbCompilandSymId inline_site_id, Address func_addr);269 270  std::vector<CompilerContext> GetContextForType(llvm::codeview::TypeIndex ti);271 272  /// Caches the basenames of symbols found in the globals stream.273  ///274  /// This includes functions and global variables275  void CacheGlobalBaseNames();276 277  void CacheUdtDeclarations();278  llvm::Expected<Declaration> ResolveUdtDeclaration(PdbTypeSymId type_id);279 280  /// Find a symbol name at a specific address (`so`).281  ///282  /// \param[in] so The segment and offset where the symbol is located.283  /// \param[in] function_type If the symbol is expected to be a function, this284  ///     has to be the type of the function. It's used to strip the name of285  ///     __cdecl functions on x86.286  /// \returns The mangled symbol name if found, otherwise `std::nullopt`.287  std::optional<llvm::StringRef> FindMangledSymbol(288      SegmentOffset so,289      llvm::codeview::TypeIndex function_type = llvm::codeview::TypeIndex());290 291  llvm::StringRef StripMangledFunctionName(llvm::StringRef mangled,292                                           PdbTypeSymId func_ty);293 294  llvm::BumpPtrAllocator m_allocator;295 296  lldb::addr_t m_obj_load_address = 0;297  bool m_done_full_type_scan = false;298  // UID for anonymous union and anonymous struct as they don't have entities in299  // pdb debug info.300  lldb::user_id_t anonymous_id = LLDB_INVALID_UID - 1;301 302  std::unique_ptr<llvm::pdb::PDBFile> m_file_up;303  std::unique_ptr<PdbIndex> m_index;304 305  llvm::DenseMap<lldb::user_id_t, lldb::VariableSP> m_global_vars;306  llvm::DenseMap<lldb::user_id_t, lldb::VariableSP> m_local_variables;307  llvm::DenseMap<lldb::user_id_t, lldb::BlockSP> m_blocks;308  llvm::DenseMap<lldb::user_id_t, lldb::FunctionSP> m_functions;309  llvm::DenseMap<lldb::user_id_t, lldb::CompUnitSP> m_compilands;310  llvm::DenseMap<lldb::user_id_t, lldb::TypeSP> m_types;311  llvm::DenseMap<lldb::user_id_t, std::shared_ptr<InlineSite>> m_inline_sites;312  llvm::DenseMap<llvm::codeview::TypeIndex, llvm::codeview::TypeIndex>313      m_parent_types;314 315  struct UdtDeclaration {316    /// This could either be an index into the `/names` section (string table,317    /// LF_UDT_MOD_SRC_LINE) or, this could be an index into the IPI stream to a318    /// LF_STRING_ID record (LF_UDT_SRC_LINE).319    llvm::codeview::TypeIndex FileNameIndex;320    bool IsIpiIndex;321 322    uint32_t Line;323  };324  llvm::DenseMap<llvm::codeview::TypeIndex, UdtDeclaration> m_udt_declarations;325  std::once_flag m_cached_udt_declarations;326 327  lldb_private::UniqueCStringMap<uint32_t> m_type_base_names;328 329  /// mangled name/full function name -> Global ID(s)330  lldb_private::UniqueCStringMap<uint32_t> m_func_full_names;331  /// basename -> Global ID(s)332  lldb_private::UniqueCStringMap<uint32_t> m_func_base_names;333  /// method basename -> Global ID(s)334  lldb_private::UniqueCStringMap<uint32_t> m_func_method_names;335 336  /// global variable basename -> Global ID(s)337  lldb_private::UniqueCStringMap<uint32_t> m_global_variable_base_names;338};339 340} // namespace npdb341} // namespace lldb_private342 343#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H344