1343181Sdim//===-- SymbolFileBreakpad.h ------------------------------------*- C++ -*-===// 2343181Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6343181Sdim// 7343181Sdim//===----------------------------------------------------------------------===// 8343181Sdim 9343181Sdim#ifndef LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H 10343181Sdim#define LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H 11343181Sdim 12353358Sdim#include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h" 13353358Sdim#include "lldb/Core/FileSpecList.h" 14353358Sdim#include "lldb/Symbol/LineTable.h" 15360784Sdim#include "lldb/Symbol/PostfixExpression.h" 16343181Sdim#include "lldb/Symbol/SymbolFile.h" 17353358Sdim#include "lldb/Symbol/UnwindPlan.h" 18343181Sdim 19343181Sdimnamespace lldb_private { 20343181Sdim 21343181Sdimnamespace breakpad { 22343181Sdim 23343181Sdimclass SymbolFileBreakpad : public SymbolFile { 24360784Sdim /// LLVM RTTI support. 25360784Sdim static char ID; 26360784Sdim 27343181Sdimpublic: 28360784Sdim /// LLVM RTTI support. 29360784Sdim /// \{ 30360784Sdim bool isA(const void *ClassID) const override { 31360784Sdim return ClassID == &ID || SymbolFile::isA(ClassID); 32360784Sdim } 33360784Sdim static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } 34360784Sdim /// \} 35360784Sdim 36343181Sdim // Static Functions 37343181Sdim static void Initialize(); 38343181Sdim static void Terminate(); 39343181Sdim static void DebuggerInitialize(Debugger &debugger) {} 40343181Sdim static ConstString GetPluginNameStatic(); 41343181Sdim 42343181Sdim static const char *GetPluginDescriptionStatic() { 43343181Sdim return "Breakpad debug symbol file reader."; 44343181Sdim } 45343181Sdim 46360784Sdim static SymbolFile *CreateInstance(lldb::ObjectFileSP objfile_sp) { 47360784Sdim return new SymbolFileBreakpad(std::move(objfile_sp)); 48343181Sdim } 49343181Sdim 50343181Sdim // Constructors and Destructors 51360784Sdim SymbolFileBreakpad(lldb::ObjectFileSP objfile_sp) 52360784Sdim : SymbolFile(std::move(objfile_sp)) {} 53343181Sdim 54343181Sdim ~SymbolFileBreakpad() override {} 55343181Sdim 56343181Sdim uint32_t CalculateAbilities() override; 57343181Sdim 58343181Sdim void InitializeObject() override {} 59343181Sdim 60343181Sdim // Compile Unit function calls 61343181Sdim 62343181Sdim lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override { 63343181Sdim return lldb::eLanguageTypeUnknown; 64343181Sdim } 65343181Sdim 66343181Sdim size_t ParseFunctions(CompileUnit &comp_unit) override; 67343181Sdim 68343181Sdim bool ParseLineTable(CompileUnit &comp_unit) override; 69343181Sdim 70343181Sdim bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; } 71343181Sdim 72343181Sdim bool ParseSupportFiles(CompileUnit &comp_unit, 73353358Sdim FileSpecList &support_files) override; 74343181Sdim size_t ParseTypes(CompileUnit &cu) override { return 0; } 75343181Sdim 76353358Sdim bool ParseImportedModules( 77353358Sdim const SymbolContext &sc, 78353358Sdim std::vector<lldb_private::SourceModule> &imported_modules) override { 79343181Sdim return false; 80343181Sdim } 81343181Sdim 82343181Sdim size_t ParseBlocksRecursive(Function &func) override { return 0; } 83343181Sdim 84360784Sdim void FindGlobalVariables(ConstString name, 85360784Sdim const CompilerDeclContext *parent_decl_ctx, 86360784Sdim uint32_t max_matches, 87360784Sdim VariableList &variables) override {} 88343181Sdim 89343181Sdim size_t ParseVariablesForContext(const SymbolContext &sc) override { 90343181Sdim return 0; 91343181Sdim } 92343181Sdim Type *ResolveTypeUID(lldb::user_id_t type_uid) override { return nullptr; } 93343181Sdim llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID( 94343181Sdim lldb::user_id_t type_uid, 95343181Sdim const lldb_private::ExecutionContext *exe_ctx) override { 96343181Sdim return llvm::None; 97343181Sdim } 98343181Sdim 99343181Sdim bool CompleteType(CompilerType &compiler_type) override { return false; } 100343181Sdim uint32_t ResolveSymbolContext(const Address &so_addr, 101343181Sdim lldb::SymbolContextItem resolve_scope, 102343181Sdim SymbolContext &sc) override; 103343181Sdim 104353358Sdim uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, 105353358Sdim bool check_inlines, 106353358Sdim lldb::SymbolContextItem resolve_scope, 107353358Sdim SymbolContextList &sc_list) override; 108353358Sdim 109360784Sdim void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask, 110360784Sdim TypeList &type_list) override {} 111343181Sdim 112360784Sdim void FindFunctions(ConstString name, 113360784Sdim const CompilerDeclContext *parent_decl_ctx, 114360784Sdim lldb::FunctionNameType name_type_mask, 115360784Sdim bool include_inlines, SymbolContextList &sc_list) override; 116343181Sdim 117360784Sdim void FindFunctions(const RegularExpression ®ex, bool include_inlines, 118360784Sdim SymbolContextList &sc_list) override; 119343181Sdim 120360784Sdim void FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx, 121360784Sdim uint32_t max_matches, 122360784Sdim llvm::DenseSet<SymbolFile *> &searched_symbol_files, 123360784Sdim TypeMap &types) override; 124343181Sdim 125360784Sdim void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages, 126360784Sdim llvm::DenseSet<SymbolFile *> &searched_symbol_files, 127360784Sdim TypeMap &types) override; 128343181Sdim 129360784Sdim llvm::Expected<TypeSystem &> 130360784Sdim GetTypeSystemForLanguage(lldb::LanguageType language) override { 131360784Sdim return llvm::make_error<llvm::StringError>( 132360784Sdim "SymbolFileBreakpad does not support GetTypeSystemForLanguage", 133360784Sdim llvm::inconvertibleErrorCode()); 134343181Sdim } 135343181Sdim 136343181Sdim CompilerDeclContext 137353358Sdim FindNamespace(ConstString name, 138343181Sdim const CompilerDeclContext *parent_decl_ctx) override { 139343181Sdim return CompilerDeclContext(); 140343181Sdim } 141343181Sdim 142343181Sdim void AddSymbols(Symtab &symtab) override; 143343181Sdim 144360784Sdim llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) override; 145360784Sdim 146353358Sdim lldb::UnwindPlanSP 147353358Sdim GetUnwindPlan(const Address &address, 148353358Sdim const RegisterInfoResolver &resolver) override; 149353358Sdim 150343181Sdim ConstString GetPluginName() override { return GetPluginNameStatic(); } 151343181Sdim uint32_t GetPluginVersion() override { return 1; } 152343181Sdim 153343181Sdimprivate: 154353358Sdim // A class representing a position in the breakpad file. Useful for 155353358Sdim // remembering the position so we can go back to it later and parse more data. 156353358Sdim // Can be converted to/from a LineIterator, but it has a much smaller memory 157353358Sdim // footprint. 158353358Sdim struct Bookmark { 159353358Sdim uint32_t section; 160353358Sdim size_t offset; 161353358Sdim 162353358Sdim friend bool operator<(const Bookmark &lhs, const Bookmark &rhs) { 163353358Sdim return std::tie(lhs.section, lhs.offset) < 164353358Sdim std::tie(rhs.section, rhs.offset); 165353358Sdim } 166353358Sdim }; 167353358Sdim 168353358Sdim // At iterator class for simplifying algorithms reading data from the breakpad 169353358Sdim // file. It iterates over all records (lines) in the sections of a given type. 170353358Sdim // It also supports saving a specific position (via the GetBookmark() method) 171353358Sdim // and then resuming from it afterwards. 172353358Sdim class LineIterator; 173353358Sdim 174353358Sdim // Return an iterator range for all records in the given object file of the 175353358Sdim // given type. 176353358Sdim llvm::iterator_range<LineIterator> lines(Record::Kind section_type); 177353358Sdim 178353358Sdim // Breakpad files do not contain sufficient information to correctly 179353358Sdim // reconstruct compile units. The approach chosen here is to treat each 180353358Sdim // function as a compile unit. The compile unit name is the name if the first 181353358Sdim // line entry belonging to this function. 182353358Sdim // This class is our internal representation of a compile unit. It stores the 183353358Sdim // CompileUnit object and a bookmark pointing to the FUNC record of the 184353358Sdim // compile unit function. It also lazily construct the list of support files 185353358Sdim // and line table entries for the compile unit, when these are needed. 186353358Sdim class CompUnitData { 187353358Sdim public: 188353358Sdim CompUnitData(Bookmark bookmark) : bookmark(bookmark) {} 189353358Sdim 190353358Sdim CompUnitData() = default; 191353358Sdim CompUnitData(const CompUnitData &rhs) : bookmark(rhs.bookmark) {} 192353358Sdim CompUnitData &operator=(const CompUnitData &rhs) { 193353358Sdim bookmark = rhs.bookmark; 194353358Sdim support_files.reset(); 195353358Sdim line_table_up.reset(); 196353358Sdim return *this; 197353358Sdim } 198353358Sdim friend bool operator<(const CompUnitData &lhs, const CompUnitData &rhs) { 199353358Sdim return lhs.bookmark < rhs.bookmark; 200353358Sdim } 201353358Sdim 202353358Sdim Bookmark bookmark; 203353358Sdim llvm::Optional<FileSpecList> support_files; 204353358Sdim std::unique_ptr<LineTable> line_table_up; 205353358Sdim 206353358Sdim }; 207353358Sdim 208360784Sdim uint32_t CalculateNumCompileUnits() override; 209360784Sdim lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; 210360784Sdim 211353358Sdim lldb::addr_t GetBaseFileAddress(); 212353358Sdim void ParseFileRecords(); 213353358Sdim void ParseCUData(); 214353358Sdim void ParseLineTableAndSupportFiles(CompileUnit &cu, CompUnitData &data); 215353358Sdim void ParseUnwindData(); 216360784Sdim llvm::ArrayRef<uint8_t> SaveAsDWARF(postfix::Node &node); 217360784Sdim lldb::UnwindPlanSP ParseCFIUnwindPlan(const Bookmark &bookmark, 218360784Sdim const RegisterInfoResolver &resolver); 219360784Sdim bool ParseCFIUnwindRow(llvm::StringRef unwind_rules, 220360784Sdim const RegisterInfoResolver &resolver, 221360784Sdim UnwindPlan::Row &row); 222360784Sdim lldb::UnwindPlanSP ParseWinUnwindPlan(const Bookmark &bookmark, 223360784Sdim const RegisterInfoResolver &resolver); 224353358Sdim 225353358Sdim using CompUnitMap = RangeDataVector<lldb::addr_t, lldb::addr_t, CompUnitData>; 226353358Sdim 227353358Sdim llvm::Optional<std::vector<FileSpec>> m_files; 228353358Sdim llvm::Optional<CompUnitMap> m_cu_data; 229353358Sdim 230353358Sdim using UnwindMap = RangeDataVector<lldb::addr_t, lldb::addr_t, Bookmark>; 231360784Sdim struct UnwindData { 232360784Sdim UnwindMap cfi; 233360784Sdim UnwindMap win; 234360784Sdim }; 235360784Sdim llvm::Optional<UnwindData> m_unwind_data; 236353358Sdim llvm::BumpPtrAllocator m_allocator; 237343181Sdim}; 238343181Sdim 239343181Sdim} // namespace breakpad 240343181Sdim} // namespace lldb_private 241343181Sdim 242343181Sdim#endif 243