| //===-- SymbolFileBreakpad.h ------------------------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H |
| #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H |
| |
| #include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h" |
| #include "lldb/Core/FileSpecList.h" |
| #include "lldb/Symbol/LineTable.h" |
| #include "lldb/Symbol/PostfixExpression.h" |
| #include "lldb/Symbol/SymbolFile.h" |
| #include "lldb/Symbol/UnwindPlan.h" |
| |
| namespace lldb_private { |
| |
| namespace breakpad { |
| |
| class SymbolFileBreakpad : public SymbolFile { |
| /// LLVM RTTI support. |
| static char ID; |
| |
| public: |
| /// LLVM RTTI support. |
| /// \{ |
| bool isA(const void *ClassID) const override { |
| return ClassID == &ID || SymbolFile::isA(ClassID); |
| } |
| static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } |
| /// \} |
| |
| // Static Functions |
| static void Initialize(); |
| static void Terminate(); |
| static void DebuggerInitialize(Debugger &debugger) {} |
| static ConstString GetPluginNameStatic(); |
| |
| static const char *GetPluginDescriptionStatic() { |
| return "Breakpad debug symbol file reader."; |
| } |
| |
| static SymbolFile *CreateInstance(lldb::ObjectFileSP objfile_sp) { |
| return new SymbolFileBreakpad(std::move(objfile_sp)); |
| } |
| |
| // Constructors and Destructors |
| SymbolFileBreakpad(lldb::ObjectFileSP objfile_sp) |
| : SymbolFile(std::move(objfile_sp)) {} |
| |
| ~SymbolFileBreakpad() override {} |
| |
| uint32_t CalculateAbilities() override; |
| |
| void InitializeObject() override {} |
| |
| // Compile Unit function calls |
| |
| lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override { |
| return lldb::eLanguageTypeUnknown; |
| } |
| |
| size_t ParseFunctions(CompileUnit &comp_unit) override; |
| |
| bool ParseLineTable(CompileUnit &comp_unit) override; |
| |
| bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; } |
| |
| bool ParseSupportFiles(CompileUnit &comp_unit, |
| FileSpecList &support_files) override; |
| size_t ParseTypes(CompileUnit &cu) override { return 0; } |
| |
| bool ParseImportedModules( |
| const SymbolContext &sc, |
| std::vector<lldb_private::SourceModule> &imported_modules) override { |
| return false; |
| } |
| |
| size_t ParseBlocksRecursive(Function &func) override { return 0; } |
| |
| void FindGlobalVariables(ConstString name, |
| const CompilerDeclContext &parent_decl_ctx, |
| uint32_t max_matches, |
| VariableList &variables) override {} |
| |
| size_t ParseVariablesForContext(const SymbolContext &sc) override { |
| return 0; |
| } |
| Type *ResolveTypeUID(lldb::user_id_t type_uid) override { return nullptr; } |
| llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID( |
| lldb::user_id_t type_uid, |
| const lldb_private::ExecutionContext *exe_ctx) override { |
| return llvm::None; |
| } |
| |
| bool CompleteType(CompilerType &compiler_type) override { return false; } |
| uint32_t ResolveSymbolContext(const Address &so_addr, |
| lldb::SymbolContextItem resolve_scope, |
| SymbolContext &sc) override; |
| |
| uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, |
| bool check_inlines, |
| lldb::SymbolContextItem resolve_scope, |
| SymbolContextList &sc_list) override; |
| |
| void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask, |
| TypeList &type_list) override {} |
| |
| void FindFunctions(ConstString name, |
| const CompilerDeclContext &parent_decl_ctx, |
| lldb::FunctionNameType name_type_mask, |
| bool include_inlines, SymbolContextList &sc_list) override; |
| |
| void FindFunctions(const RegularExpression ®ex, bool include_inlines, |
| SymbolContextList &sc_list) override; |
| |
| void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx, |
| uint32_t max_matches, |
| llvm::DenseSet<SymbolFile *> &searched_symbol_files, |
| TypeMap &types) override; |
| |
| void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages, |
| llvm::DenseSet<SymbolFile *> &searched_symbol_files, |
| TypeMap &types) override; |
| |
| llvm::Expected<TypeSystem &> |
| GetTypeSystemForLanguage(lldb::LanguageType language) override { |
| return llvm::make_error<llvm::StringError>( |
| "SymbolFileBreakpad does not support GetTypeSystemForLanguage", |
| llvm::inconvertibleErrorCode()); |
| } |
| |
| CompilerDeclContext |
| FindNamespace(ConstString name, |
| const CompilerDeclContext &parent_decl_ctx) override { |
| return CompilerDeclContext(); |
| } |
| |
| void AddSymbols(Symtab &symtab) override; |
| |
| llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) override; |
| |
| lldb::UnwindPlanSP |
| GetUnwindPlan(const Address &address, |
| const RegisterInfoResolver &resolver) override; |
| |
| ConstString GetPluginName() override { return GetPluginNameStatic(); } |
| uint32_t GetPluginVersion() override { return 1; } |
| |
| private: |
| // A class representing a position in the breakpad file. Useful for |
| // remembering the position so we can go back to it later and parse more data. |
| // Can be converted to/from a LineIterator, but it has a much smaller memory |
| // footprint. |
| struct Bookmark { |
| uint32_t section; |
| size_t offset; |
| |
| friend bool operator<(const Bookmark &lhs, const Bookmark &rhs) { |
| return std::tie(lhs.section, lhs.offset) < |
| std::tie(rhs.section, rhs.offset); |
| } |
| }; |
| |
| // At iterator class for simplifying algorithms reading data from the breakpad |
| // file. It iterates over all records (lines) in the sections of a given type. |
| // It also supports saving a specific position (via the GetBookmark() method) |
| // and then resuming from it afterwards. |
| class LineIterator; |
| |
| // Return an iterator range for all records in the given object file of the |
| // given type. |
| llvm::iterator_range<LineIterator> lines(Record::Kind section_type); |
| |
| // Breakpad files do not contain sufficient information to correctly |
| // reconstruct compile units. The approach chosen here is to treat each |
| // function as a compile unit. The compile unit name is the name if the first |
| // line entry belonging to this function. |
| // This class is our internal representation of a compile unit. It stores the |
| // CompileUnit object and a bookmark pointing to the FUNC record of the |
| // compile unit function. It also lazily construct the list of support files |
| // and line table entries for the compile unit, when these are needed. |
| class CompUnitData { |
| public: |
| CompUnitData(Bookmark bookmark) : bookmark(bookmark) {} |
| |
| CompUnitData() = default; |
| CompUnitData(const CompUnitData &rhs) : bookmark(rhs.bookmark) {} |
| CompUnitData &operator=(const CompUnitData &rhs) { |
| bookmark = rhs.bookmark; |
| support_files.reset(); |
| line_table_up.reset(); |
| return *this; |
| } |
| friend bool operator<(const CompUnitData &lhs, const CompUnitData &rhs) { |
| return lhs.bookmark < rhs.bookmark; |
| } |
| |
| Bookmark bookmark; |
| llvm::Optional<FileSpecList> support_files; |
| std::unique_ptr<LineTable> line_table_up; |
| |
| }; |
| |
| uint32_t CalculateNumCompileUnits() override; |
| lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; |
| |
| lldb::addr_t GetBaseFileAddress(); |
| void ParseFileRecords(); |
| void ParseCUData(); |
| void ParseLineTableAndSupportFiles(CompileUnit &cu, CompUnitData &data); |
| void ParseUnwindData(); |
| llvm::ArrayRef<uint8_t> SaveAsDWARF(postfix::Node &node); |
| lldb::UnwindPlanSP ParseCFIUnwindPlan(const Bookmark &bookmark, |
| const RegisterInfoResolver &resolver); |
| bool ParseCFIUnwindRow(llvm::StringRef unwind_rules, |
| const RegisterInfoResolver &resolver, |
| UnwindPlan::Row &row); |
| lldb::UnwindPlanSP ParseWinUnwindPlan(const Bookmark &bookmark, |
| const RegisterInfoResolver &resolver); |
| |
| using CompUnitMap = RangeDataVector<lldb::addr_t, lldb::addr_t, CompUnitData>; |
| |
| llvm::Optional<std::vector<FileSpec>> m_files; |
| llvm::Optional<CompUnitMap> m_cu_data; |
| |
| using UnwindMap = RangeDataVector<lldb::addr_t, lldb::addr_t, Bookmark>; |
| struct UnwindData { |
| UnwindMap cfi; |
| UnwindMap win; |
| }; |
| llvm::Optional<UnwindData> m_unwind_data; |
| llvm::BumpPtrAllocator m_allocator; |
| }; |
| |
| } // namespace breakpad |
| } // namespace lldb_private |
| |
| #endif |