diff options
| author | Pavel Labath <pavel@labath.sk> | 2019-02-07 13:42:32 +0000 |
|---|---|---|
| committer | Pavel Labath <pavel@labath.sk> | 2019-02-07 13:42:32 +0000 |
| commit | 3f35ab8b30001ca8038795320c48cf640e59b36b (patch) | |
| tree | f3ce69023b99cdb5c9a4eaefbbe6344cca51f3a2 /lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h | |
| parent | 67756c09f21ada07a3686601538e88da2ad1771e (diff) | |
| download | bcm5719-llvm-3f35ab8b30001ca8038795320c48cf640e59b36b.tar.gz bcm5719-llvm-3f35ab8b30001ca8038795320c48cf640e59b36b.zip | |
SymbolFileBreakpad: Add line table support
Summary:
This patch teaches SymbolFileBreakpad to parse the line information in
breakpad files and present it to lldb.
The trickiest question here was what kind of "compile units" to present
to lldb, as there really isn't enough information in breakpad files to
correctly reconstruct those.
A couple of options were considered
- have the entire file be one compile unit
- have one compile unit for each FILE record
- have one compile unit for each FUNC record
The main drawback of the first approach is that all of the files would
be considered "headers" by lldb, and so they wouldn't be searched if
target.inline-breakpoint-strategy=never. The single compile unit would
also be huge, and there isn't a good way to name it.
The second approach will create mostly correct compile units for cpp
files, but it will still be wrong for headers. However, the biggest
drawback here seemed to be the fact that this can cause a compile unit
to change mid-function (for example when a function from another file is
inlined or another file is #included into a function). While I don't
know of any specific thing that would break in this case, it does sound
like a thing that we should avoid.
In the end, we chose the third option, as it didn't seem to have any
major disadvantages, though it was not ideal either. One disadvantage
here is that this generates a large number of compile units, and there
is still a question on how to name it. We chose to simply name it after
the first line record in that function. This should be correct 99.99% of
the time, though it can produce somewhat strange results if the very
first line record comes from an #included file.
Reviewers: clayborg, zturner, lemo, markmentovai
Subscribers: lldb-commits
Differential Revision: https://reviews.llvm.org/D56595
llvm-svn: 353404
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h')
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h | 72 |
1 files changed, 69 insertions, 3 deletions
diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h index aa9f97cc13f..373a633403a 100644 --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -9,6 +9,9 @@ #ifndef LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H #define LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H +#include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h" +#include "lldb/Core/FileSpecList.h" +#include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/SymbolFile.h" namespace lldb_private { @@ -63,9 +66,7 @@ public: bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; } bool ParseSupportFiles(CompileUnit &comp_unit, - FileSpecList &support_files) override { - return false; - } + FileSpecList &support_files) override; size_t ParseTypes(CompileUnit &cu) override { return 0; } bool @@ -98,6 +99,11 @@ public: 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; + size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask, TypeList &type_list) override { return 0; @@ -137,6 +143,66 @@ public: 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; + }; + + // 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 std::tie(lhs.bookmark.section, lhs.bookmark.offset) < + std::tie(rhs.bookmark.section, rhs.bookmark.offset); + } + + Bookmark bookmark; + llvm::Optional<FileSpecList> support_files; + std::unique_ptr<LineTable> line_table_up; + + }; + + SymbolVendor &GetSymbolVendor(); + lldb::addr_t GetBaseFileAddress(); + void ParseFileRecords(); + void ParseCUData(); + void ParseLineTableAndSupportFiles(CompileUnit &cu, CompUnitData &data); + + using CompUnitMap = RangeDataVector<lldb::addr_t, lldb::addr_t, CompUnitData>; + + llvm::Optional<std::vector<FileSpec>> m_files; + llvm::Optional<CompUnitMap> m_cu_data; }; } // namespace breakpad |

