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