1 //===-- SymbolFileBreakpad.h ------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H
10 #define LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H
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"
19 namespace lldb_private {
23 class SymbolFileBreakpad : public SymbolFile {
26 static void Initialize();
27 static void Terminate();
28 static void DebuggerInitialize(Debugger &debugger) {}
29 static ConstString GetPluginNameStatic();
31 static const char *GetPluginDescriptionStatic() {
32 return "Breakpad debug symbol file reader.";
35 static SymbolFile *CreateInstance(lldb::ObjectFileSP objfile_sp) {
36 return new SymbolFileBreakpad(std::move(objfile_sp));
39 // Constructors and Destructors
40 SymbolFileBreakpad(lldb::ObjectFileSP objfile_sp)
41 : SymbolFile(std::move(objfile_sp)) {}
43 ~SymbolFileBreakpad() override {}
45 uint32_t CalculateAbilities() override;
47 void InitializeObject() override {}
49 // Compile Unit function calls
51 lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override {
52 return lldb::eLanguageTypeUnknown;
55 size_t ParseFunctions(CompileUnit &comp_unit) override;
57 bool ParseLineTable(CompileUnit &comp_unit) override;
59 bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; }
61 bool ParseSupportFiles(CompileUnit &comp_unit,
62 FileSpecList &support_files) override;
63 size_t ParseTypes(CompileUnit &cu) override { return 0; }
65 bool ParseImportedModules(
66 const SymbolContext &sc,
67 std::vector<lldb_private::SourceModule> &imported_modules) override {
71 size_t ParseBlocksRecursive(Function &func) override { return 0; }
73 void FindGlobalVariables(ConstString name,
74 const CompilerDeclContext *parent_decl_ctx,
76 VariableList &variables) override {}
78 size_t ParseVariablesForContext(const SymbolContext &sc) override {
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 {
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;
93 uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line,
95 lldb::SymbolContextItem resolve_scope,
96 SymbolContextList &sc_list) override;
98 void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
99 TypeList &type_list) override {}
101 void FindFunctions(ConstString name,
102 const CompilerDeclContext *parent_decl_ctx,
103 lldb::FunctionNameType name_type_mask,
104 bool include_inlines, SymbolContextList &sc_list) override;
106 void FindFunctions(const RegularExpression ®ex, bool include_inlines,
107 SymbolContextList &sc_list) override;
109 void FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx,
110 uint32_t max_matches,
111 llvm::DenseSet<SymbolFile *> &searched_symbol_files,
112 TypeMap &types) override;
114 void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
115 TypeMap &types) override;
117 llvm::Expected<TypeSystem &>
118 GetTypeSystemForLanguage(lldb::LanguageType language) override {
119 return llvm::make_error<llvm::StringError>(
120 "SymbolFileBreakpad does not support GetTypeSystemForLanguage",
121 llvm::inconvertibleErrorCode());
125 FindNamespace(ConstString name,
126 const CompilerDeclContext *parent_decl_ctx) override {
127 return CompilerDeclContext();
130 void AddSymbols(Symtab &symtab) override;
132 llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) override;
135 GetUnwindPlan(const Address &address,
136 const RegisterInfoResolver &resolver) override;
138 ConstString GetPluginName() override { return GetPluginNameStatic(); }
139 uint32_t GetPluginVersion() override { return 1; }
142 // A class representing a position in the breakpad file. Useful for
143 // remembering the position so we can go back to it later and parse more data.
144 // Can be converted to/from a LineIterator, but it has a much smaller memory
150 friend bool operator<(const Bookmark &lhs, const Bookmark &rhs) {
151 return std::tie(lhs.section, lhs.offset) <
152 std::tie(rhs.section, rhs.offset);
156 // At iterator class for simplifying algorithms reading data from the breakpad
157 // file. It iterates over all records (lines) in the sections of a given type.
158 // It also supports saving a specific position (via the GetBookmark() method)
159 // and then resuming from it afterwards.
162 // Return an iterator range for all records in the given object file of the
164 llvm::iterator_range<LineIterator> lines(Record::Kind section_type);
166 // Breakpad files do not contain sufficient information to correctly
167 // reconstruct compile units. The approach chosen here is to treat each
168 // function as a compile unit. The compile unit name is the name if the first
169 // line entry belonging to this function.
170 // This class is our internal representation of a compile unit. It stores the
171 // CompileUnit object and a bookmark pointing to the FUNC record of the
172 // compile unit function. It also lazily construct the list of support files
173 // and line table entries for the compile unit, when these are needed.
176 CompUnitData(Bookmark bookmark) : bookmark(bookmark) {}
178 CompUnitData() = default;
179 CompUnitData(const CompUnitData &rhs) : bookmark(rhs.bookmark) {}
180 CompUnitData &operator=(const CompUnitData &rhs) {
181 bookmark = rhs.bookmark;
182 support_files.reset();
183 line_table_up.reset();
186 friend bool operator<(const CompUnitData &lhs, const CompUnitData &rhs) {
187 return lhs.bookmark < rhs.bookmark;
191 llvm::Optional<FileSpecList> support_files;
192 std::unique_ptr<LineTable> line_table_up;
196 uint32_t CalculateNumCompileUnits() override;
197 lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
199 lldb::addr_t GetBaseFileAddress();
200 void ParseFileRecords();
202 void ParseLineTableAndSupportFiles(CompileUnit &cu, CompUnitData &data);
203 void ParseUnwindData();
204 llvm::ArrayRef<uint8_t> SaveAsDWARF(postfix::Node &node);
205 lldb::UnwindPlanSP ParseCFIUnwindPlan(const Bookmark &bookmark,
206 const RegisterInfoResolver &resolver);
207 bool ParseCFIUnwindRow(llvm::StringRef unwind_rules,
208 const RegisterInfoResolver &resolver,
209 UnwindPlan::Row &row);
210 lldb::UnwindPlanSP ParseWinUnwindPlan(const Bookmark &bookmark,
211 const RegisterInfoResolver &resolver);
213 using CompUnitMap = RangeDataVector<lldb::addr_t, lldb::addr_t, CompUnitData>;
215 llvm::Optional<std::vector<FileSpec>> m_files;
216 llvm::Optional<CompUnitMap> m_cu_data;
218 using UnwindMap = RangeDataVector<lldb::addr_t, lldb::addr_t, Bookmark>;
223 llvm::Optional<UnwindData> m_unwind_data;
224 llvm::BumpPtrAllocator m_allocator;
227 } // namespace breakpad
228 } // namespace lldb_private