xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1061da546Spatrick //===-- SymbolFileBreakpad.h ------------------------------------*- C++ -*-===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H
10dda28197Spatrick #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H
11061da546Spatrick 
12061da546Spatrick #include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h"
13061da546Spatrick #include "lldb/Core/FileSpecList.h"
14061da546Spatrick #include "lldb/Symbol/LineTable.h"
15061da546Spatrick #include "lldb/Symbol/PostfixExpression.h"
16061da546Spatrick #include "lldb/Symbol/SymbolFile.h"
17061da546Spatrick #include "lldb/Symbol/UnwindPlan.h"
18*f6aab3d8Srobert #include <optional>
19061da546Spatrick 
20061da546Spatrick namespace lldb_private {
21061da546Spatrick 
22061da546Spatrick namespace breakpad {
23061da546Spatrick 
24*f6aab3d8Srobert class SymbolFileBreakpad : public SymbolFileCommon {
25061da546Spatrick   /// LLVM RTTI support.
26061da546Spatrick   static char ID;
27061da546Spatrick 
28061da546Spatrick public:
29061da546Spatrick   /// LLVM RTTI support.
30061da546Spatrick   /// \{
isA(const void * ClassID)31061da546Spatrick   bool isA(const void *ClassID) const override {
32*f6aab3d8Srobert     return ClassID == &ID || SymbolFileCommon::isA(ClassID);
33061da546Spatrick   }
classof(const SymbolFile * obj)34061da546Spatrick   static bool classof(const SymbolFile *obj) { return obj->isA(&ID); }
35061da546Spatrick   /// \}
36061da546Spatrick 
37061da546Spatrick   // Static Functions
38061da546Spatrick   static void Initialize();
39061da546Spatrick   static void Terminate();
DebuggerInitialize(Debugger & debugger)40061da546Spatrick   static void DebuggerInitialize(Debugger &debugger) {}
GetPluginNameStatic()41*f6aab3d8Srobert   static llvm::StringRef GetPluginNameStatic() { return "breakpad"; }
42061da546Spatrick 
GetPluginDescriptionStatic()43*f6aab3d8Srobert   static llvm::StringRef GetPluginDescriptionStatic() {
44061da546Spatrick     return "Breakpad debug symbol file reader.";
45061da546Spatrick   }
46061da546Spatrick 
CreateInstance(lldb::ObjectFileSP objfile_sp)47061da546Spatrick   static SymbolFile *CreateInstance(lldb::ObjectFileSP objfile_sp) {
48061da546Spatrick     return new SymbolFileBreakpad(std::move(objfile_sp));
49061da546Spatrick   }
50061da546Spatrick 
51061da546Spatrick   // Constructors and Destructors
SymbolFileBreakpad(lldb::ObjectFileSP objfile_sp)52061da546Spatrick   SymbolFileBreakpad(lldb::ObjectFileSP objfile_sp)
53*f6aab3d8Srobert       : SymbolFileCommon(std::move(objfile_sp)) {}
54061da546Spatrick 
55be691f3bSpatrick   ~SymbolFileBreakpad() override = default;
56061da546Spatrick 
57061da546Spatrick   uint32_t CalculateAbilities() override;
58061da546Spatrick 
InitializeObject()59061da546Spatrick   void InitializeObject() override {}
60061da546Spatrick 
61061da546Spatrick   // Compile Unit function calls
62061da546Spatrick 
ParseLanguage(CompileUnit & comp_unit)63061da546Spatrick   lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override {
64061da546Spatrick     return lldb::eLanguageTypeUnknown;
65061da546Spatrick   }
66061da546Spatrick 
67*f6aab3d8Srobert   lldb::FunctionSP GetOrCreateFunction(CompileUnit &comp_unit);
68*f6aab3d8Srobert 
69061da546Spatrick   size_t ParseFunctions(CompileUnit &comp_unit) override;
70061da546Spatrick 
71061da546Spatrick   bool ParseLineTable(CompileUnit &comp_unit) override;
72061da546Spatrick 
ParseDebugMacros(CompileUnit & comp_unit)73061da546Spatrick   bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; }
74061da546Spatrick 
75061da546Spatrick   bool ParseSupportFiles(CompileUnit &comp_unit,
76061da546Spatrick                          FileSpecList &support_files) override;
ParseTypes(CompileUnit & cu)77061da546Spatrick   size_t ParseTypes(CompileUnit &cu) override { return 0; }
78061da546Spatrick 
ParseImportedModules(const SymbolContext & sc,std::vector<lldb_private::SourceModule> & imported_modules)79061da546Spatrick   bool ParseImportedModules(
80061da546Spatrick       const SymbolContext &sc,
81061da546Spatrick       std::vector<lldb_private::SourceModule> &imported_modules) override {
82061da546Spatrick     return false;
83061da546Spatrick   }
84061da546Spatrick 
85*f6aab3d8Srobert   size_t ParseBlocksRecursive(Function &func) override;
86061da546Spatrick 
FindGlobalVariables(ConstString name,const CompilerDeclContext & parent_decl_ctx,uint32_t max_matches,VariableList & variables)87061da546Spatrick   void FindGlobalVariables(ConstString name,
88dda28197Spatrick                            const CompilerDeclContext &parent_decl_ctx,
89061da546Spatrick                            uint32_t max_matches,
90061da546Spatrick                            VariableList &variables) override {}
91061da546Spatrick 
ParseVariablesForContext(const SymbolContext & sc)92061da546Spatrick   size_t ParseVariablesForContext(const SymbolContext &sc) override {
93061da546Spatrick     return 0;
94061da546Spatrick   }
ResolveTypeUID(lldb::user_id_t type_uid)95061da546Spatrick   Type *ResolveTypeUID(lldb::user_id_t type_uid) override { return nullptr; }
GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,const lldb_private::ExecutionContext * exe_ctx)96*f6aab3d8Srobert   std::optional<ArrayInfo> GetDynamicArrayInfoForUID(
97061da546Spatrick       lldb::user_id_t type_uid,
98061da546Spatrick       const lldb_private::ExecutionContext *exe_ctx) override {
99*f6aab3d8Srobert     return std::nullopt;
100061da546Spatrick   }
101061da546Spatrick 
CompleteType(CompilerType & compiler_type)102061da546Spatrick   bool CompleteType(CompilerType &compiler_type) override { return false; }
103061da546Spatrick   uint32_t ResolveSymbolContext(const Address &so_addr,
104061da546Spatrick                                 lldb::SymbolContextItem resolve_scope,
105061da546Spatrick                                 SymbolContext &sc) override;
106061da546Spatrick 
107be691f3bSpatrick   uint32_t ResolveSymbolContext(const SourceLocationSpec &src_location_spec,
108061da546Spatrick                                 lldb::SymbolContextItem resolve_scope,
109061da546Spatrick                                 SymbolContextList &sc_list) override;
110061da546Spatrick 
GetTypes(SymbolContextScope * sc_scope,lldb::TypeClass type_mask,TypeList & type_list)111061da546Spatrick   void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
112061da546Spatrick                 TypeList &type_list) override {}
113061da546Spatrick 
114*f6aab3d8Srobert   void FindFunctions(const Module::LookupInfo &lookup_info,
115dda28197Spatrick                      const CompilerDeclContext &parent_decl_ctx,
116061da546Spatrick                      bool include_inlines, SymbolContextList &sc_list) override;
117061da546Spatrick 
118061da546Spatrick   void FindFunctions(const RegularExpression &regex, bool include_inlines,
119061da546Spatrick                      SymbolContextList &sc_list) override;
120061da546Spatrick 
121dda28197Spatrick   void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx,
122061da546Spatrick                  uint32_t max_matches,
123061da546Spatrick                  llvm::DenseSet<SymbolFile *> &searched_symbol_files,
124061da546Spatrick                  TypeMap &types) override;
125061da546Spatrick 
126061da546Spatrick   void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
127061da546Spatrick                  llvm::DenseSet<SymbolFile *> &searched_symbol_files,
128061da546Spatrick                  TypeMap &types) override;
129061da546Spatrick 
130*f6aab3d8Srobert   llvm::Expected<lldb::TypeSystemSP>
GetTypeSystemForLanguage(lldb::LanguageType language)131061da546Spatrick   GetTypeSystemForLanguage(lldb::LanguageType language) override {
132061da546Spatrick     return llvm::make_error<llvm::StringError>(
133061da546Spatrick         "SymbolFileBreakpad does not support GetTypeSystemForLanguage",
134061da546Spatrick         llvm::inconvertibleErrorCode());
135061da546Spatrick   }
136061da546Spatrick 
137061da546Spatrick   CompilerDeclContext
FindNamespace(ConstString name,const CompilerDeclContext & parent_decl_ctx)138061da546Spatrick   FindNamespace(ConstString name,
139dda28197Spatrick                 const CompilerDeclContext &parent_decl_ctx) override {
140061da546Spatrick     return CompilerDeclContext();
141061da546Spatrick   }
142061da546Spatrick 
143061da546Spatrick   void AddSymbols(Symtab &symtab) override;
144061da546Spatrick 
145061da546Spatrick   llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) override;
146061da546Spatrick 
147061da546Spatrick   lldb::UnwindPlanSP
148061da546Spatrick   GetUnwindPlan(const Address &address,
149061da546Spatrick                 const RegisterInfoResolver &resolver) override;
150061da546Spatrick 
GetPluginName()151*f6aab3d8Srobert   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
152*f6aab3d8Srobert 
153*f6aab3d8Srobert   uint64_t GetDebugInfoSize() override;
154061da546Spatrick 
155061da546Spatrick private:
156061da546Spatrick   // A class representing a position in the breakpad file. Useful for
157061da546Spatrick   // remembering the position so we can go back to it later and parse more data.
158061da546Spatrick   // Can be converted to/from a LineIterator, but it has a much smaller memory
159061da546Spatrick   // footprint.
160061da546Spatrick   struct Bookmark {
161061da546Spatrick     uint32_t section;
162061da546Spatrick     size_t offset;
163061da546Spatrick 
164061da546Spatrick     friend bool operator<(const Bookmark &lhs, const Bookmark &rhs) {
165061da546Spatrick       return std::tie(lhs.section, lhs.offset) <
166061da546Spatrick              std::tie(rhs.section, rhs.offset);
167061da546Spatrick     }
168061da546Spatrick   };
169061da546Spatrick 
170061da546Spatrick   // At iterator class for simplifying algorithms reading data from the breakpad
171061da546Spatrick   // file. It iterates over all records (lines) in the sections of a given type.
172061da546Spatrick   // It also supports saving a specific position (via the GetBookmark() method)
173061da546Spatrick   // and then resuming from it afterwards.
174061da546Spatrick   class LineIterator;
175061da546Spatrick 
176061da546Spatrick   // Return an iterator range for all records in the given object file of the
177061da546Spatrick   // given type.
178061da546Spatrick   llvm::iterator_range<LineIterator> lines(Record::Kind section_type);
179061da546Spatrick 
180061da546Spatrick   // Breakpad files do not contain sufficient information to correctly
181061da546Spatrick   // reconstruct compile units. The approach chosen here is to treat each
182061da546Spatrick   // function as a compile unit. The compile unit name is the name if the first
183061da546Spatrick   // line entry belonging to this function.
184061da546Spatrick   // This class is our internal representation of a compile unit. It stores the
185061da546Spatrick   // CompileUnit object and a bookmark pointing to the FUNC record of the
186061da546Spatrick   // compile unit function. It also lazily construct the list of support files
187061da546Spatrick   // and line table entries for the compile unit, when these are needed.
188061da546Spatrick   class CompUnitData {
189061da546Spatrick   public:
CompUnitData(Bookmark bookmark)190061da546Spatrick     CompUnitData(Bookmark bookmark) : bookmark(bookmark) {}
191061da546Spatrick 
192061da546Spatrick     CompUnitData() = default;
CompUnitData(const CompUnitData & rhs)193061da546Spatrick     CompUnitData(const CompUnitData &rhs) : bookmark(rhs.bookmark) {}
194061da546Spatrick     CompUnitData &operator=(const CompUnitData &rhs) {
195061da546Spatrick       bookmark = rhs.bookmark;
196061da546Spatrick       support_files.reset();
197061da546Spatrick       line_table_up.reset();
198061da546Spatrick       return *this;
199061da546Spatrick     }
200061da546Spatrick     friend bool operator<(const CompUnitData &lhs, const CompUnitData &rhs) {
201061da546Spatrick       return lhs.bookmark < rhs.bookmark;
202061da546Spatrick     }
203061da546Spatrick 
204061da546Spatrick     Bookmark bookmark;
205*f6aab3d8Srobert     std::optional<FileSpecList> support_files;
206061da546Spatrick     std::unique_ptr<LineTable> line_table_up;
207061da546Spatrick 
208061da546Spatrick   };
209061da546Spatrick 
210061da546Spatrick   uint32_t CalculateNumCompileUnits() override;
211061da546Spatrick   lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
212061da546Spatrick 
213061da546Spatrick   lldb::addr_t GetBaseFileAddress();
214061da546Spatrick   void ParseFileRecords();
215061da546Spatrick   void ParseCUData();
216061da546Spatrick   void ParseLineTableAndSupportFiles(CompileUnit &cu, CompUnitData &data);
217061da546Spatrick   void ParseUnwindData();
218061da546Spatrick   llvm::ArrayRef<uint8_t> SaveAsDWARF(postfix::Node &node);
219061da546Spatrick   lldb::UnwindPlanSP ParseCFIUnwindPlan(const Bookmark &bookmark,
220061da546Spatrick                                         const RegisterInfoResolver &resolver);
221061da546Spatrick   bool ParseCFIUnwindRow(llvm::StringRef unwind_rules,
222061da546Spatrick                          const RegisterInfoResolver &resolver,
223061da546Spatrick                          UnwindPlan::Row &row);
224061da546Spatrick   lldb::UnwindPlanSP ParseWinUnwindPlan(const Bookmark &bookmark,
225061da546Spatrick                                         const RegisterInfoResolver &resolver);
226*f6aab3d8Srobert   void ParseInlineOriginRecords();
227061da546Spatrick 
228061da546Spatrick   using CompUnitMap = RangeDataVector<lldb::addr_t, lldb::addr_t, CompUnitData>;
229061da546Spatrick 
230*f6aab3d8Srobert   std::optional<std::vector<FileSpec>> m_files;
231*f6aab3d8Srobert   std::optional<CompUnitMap> m_cu_data;
232*f6aab3d8Srobert   std::optional<std::vector<llvm::StringRef>> m_inline_origins;
233061da546Spatrick 
234061da546Spatrick   using UnwindMap = RangeDataVector<lldb::addr_t, lldb::addr_t, Bookmark>;
235061da546Spatrick   struct UnwindData {
236061da546Spatrick     UnwindMap cfi;
237061da546Spatrick     UnwindMap win;
238061da546Spatrick   };
239*f6aab3d8Srobert   std::optional<UnwindData> m_unwind_data;
240061da546Spatrick   llvm::BumpPtrAllocator m_allocator;
241061da546Spatrick };
242061da546Spatrick 
243061da546Spatrick } // namespace breakpad
244061da546Spatrick } // namespace lldb_private
245061da546Spatrick 
246061da546Spatrick #endif
247