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