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