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