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