1 //===-- SymbolFileBreakpad.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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H 10 #define LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H 11 12 #include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h" 13 #include "lldb/Core/FileSpecList.h" 14 #include "lldb/Symbol/LineTable.h" 15 #include "lldb/Symbol/SymbolFile.h" 16 17 namespace lldb_private { 18 19 namespace breakpad { 20 21 class SymbolFileBreakpad : public SymbolFile { 22 public: 23 // Static Functions 24 static void Initialize(); 25 static void Terminate(); 26 static void DebuggerInitialize(Debugger &debugger) {} 27 static ConstString GetPluginNameStatic(); 28 29 static const char *GetPluginDescriptionStatic() { 30 return "Breakpad debug symbol file reader."; 31 } 32 33 static SymbolFile *CreateInstance(ObjectFile *obj_file) { 34 return new SymbolFileBreakpad(obj_file); 35 } 36 37 // Constructors and Destructors 38 SymbolFileBreakpad(ObjectFile *object_file) : SymbolFile(object_file) {} 39 40 ~SymbolFileBreakpad() override {} 41 42 uint32_t CalculateAbilities() override; 43 44 void InitializeObject() override {} 45 46 // Compile Unit function calls 47 48 uint32_t GetNumCompileUnits() override; 49 50 lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; 51 52 lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override { 53 return lldb::eLanguageTypeUnknown; 54 } 55 56 size_t ParseFunctions(CompileUnit &comp_unit) override; 57 58 bool ParseLineTable(CompileUnit &comp_unit) override; 59 60 bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; } 61 62 bool ParseSupportFiles(CompileUnit &comp_unit, 63 FileSpecList &support_files) override; 64 size_t ParseTypes(CompileUnit &cu) override { return 0; } 65 66 bool ParseImportedModules( 67 const SymbolContext &sc, 68 std::vector<lldb_private::SourceModule> &imported_modules) override { 69 return false; 70 } 71 72 size_t ParseBlocksRecursive(Function &func) override { return 0; } 73 74 uint32_t FindGlobalVariables(ConstString name, 75 const CompilerDeclContext *parent_decl_ctx, 76 uint32_t max_matches, 77 VariableList &variables) override { 78 return 0; 79 } 80 81 size_t ParseVariablesForContext(const SymbolContext &sc) override { 82 return 0; 83 } 84 Type *ResolveTypeUID(lldb::user_id_t type_uid) override { return nullptr; } 85 llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID( 86 lldb::user_id_t type_uid, 87 const lldb_private::ExecutionContext *exe_ctx) override { 88 return llvm::None; 89 } 90 91 bool CompleteType(CompilerType &compiler_type) override { return false; } 92 uint32_t ResolveSymbolContext(const Address &so_addr, 93 lldb::SymbolContextItem resolve_scope, 94 SymbolContext &sc) override; 95 96 uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, 97 bool check_inlines, 98 lldb::SymbolContextItem resolve_scope, 99 SymbolContextList &sc_list) override; 100 101 size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask, 102 TypeList &type_list) override { 103 return 0; 104 } 105 106 uint32_t FindFunctions(ConstString name, 107 const CompilerDeclContext *parent_decl_ctx, 108 lldb::FunctionNameType name_type_mask, 109 bool include_inlines, bool append, 110 SymbolContextList &sc_list) override; 111 112 uint32_t FindFunctions(const RegularExpression ®ex, bool include_inlines, 113 bool append, SymbolContextList &sc_list) override; 114 115 uint32_t FindTypes(ConstString name, 116 const CompilerDeclContext *parent_decl_ctx, bool append, 117 uint32_t max_matches, 118 llvm::DenseSet<SymbolFile *> &searched_symbol_files, 119 TypeMap &types) override; 120 121 size_t FindTypes(const std::vector<CompilerContext> &context, bool append, 122 TypeMap &types) override; 123 124 TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language) override { 125 return nullptr; 126 } 127 128 CompilerDeclContext 129 FindNamespace(ConstString name, 130 const CompilerDeclContext *parent_decl_ctx) override { 131 return CompilerDeclContext(); 132 } 133 134 void AddSymbols(Symtab &symtab) override; 135 136 ConstString GetPluginName() override { return GetPluginNameStatic(); } 137 uint32_t GetPluginVersion() override { return 1; } 138 139 private: 140 // A class representing a position in the breakpad file. Useful for 141 // remembering the position so we can go back to it later and parse more data. 142 // Can be converted to/from a LineIterator, but it has a much smaller memory 143 // footprint. 144 struct Bookmark { 145 uint32_t section; 146 size_t offset; 147 }; 148 149 // At iterator class for simplifying algorithms reading data from the breakpad 150 // file. It iterates over all records (lines) in the sections of a given type. 151 // It also supports saving a specific position (via the GetBookmark() method) 152 // and then resuming from it afterwards. 153 class LineIterator; 154 155 // Return an iterator range for all records in the given object file of the 156 // given type. 157 llvm::iterator_range<LineIterator> lines(Record::Kind section_type); 158 159 // Breakpad files do not contain sufficient information to correctly 160 // reconstruct compile units. The approach chosen here is to treat each 161 // function as a compile unit. The compile unit name is the name if the first 162 // line entry belonging to this function. 163 // This class is our internal representation of a compile unit. It stores the 164 // CompileUnit object and a bookmark pointing to the FUNC record of the 165 // compile unit function. It also lazily construct the list of support files 166 // and line table entries for the compile unit, when these are needed. 167 class CompUnitData { 168 public: 169 CompUnitData(Bookmark bookmark) : bookmark(bookmark) {} 170 171 CompUnitData() = default; 172 CompUnitData(const CompUnitData &rhs) : bookmark(rhs.bookmark) {} 173 CompUnitData &operator=(const CompUnitData &rhs) { 174 bookmark = rhs.bookmark; 175 support_files.reset(); 176 line_table_up.reset(); 177 return *this; 178 } 179 friend bool operator<(const CompUnitData &lhs, const CompUnitData &rhs) { 180 return std::tie(lhs.bookmark.section, lhs.bookmark.offset) < 181 std::tie(rhs.bookmark.section, rhs.bookmark.offset); 182 } 183 184 Bookmark bookmark; 185 llvm::Optional<FileSpecList> support_files; 186 std::unique_ptr<LineTable> line_table_up; 187 188 }; 189 190 SymbolVendor &GetSymbolVendor(); 191 lldb::addr_t GetBaseFileAddress(); 192 void ParseFileRecords(); 193 void ParseCUData(); 194 void ParseLineTableAndSupportFiles(CompileUnit &cu, CompUnitData &data); 195 196 using CompUnitMap = RangeDataVector<lldb::addr_t, lldb::addr_t, CompUnitData>; 197 198 llvm::Optional<std::vector<FileSpec>> m_files; 199 llvm::Optional<CompUnitMap> m_cu_data; 200 }; 201 202 } // namespace breakpad 203 } // namespace lldb_private 204 205 #endif 206