diff options
author | Itamar <itamar8910@gmail.com> | 2021-09-28 13:35:28 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-09-28 16:54:39 +0200 |
commit | 09153b899776fe38c271eef08f675a1b31d71cb9 (patch) | |
tree | 41fb98b96b106b8c706ff9fade4088c19dd3c9c8 /Userland/Libraries/LibDebug/Dwarf | |
parent | 26a96d315ddc7f1753e7d3cb5246c7817fedfb8f (diff) | |
download | serenity-09153b899776fe38c271eef08f675a1b31d71cb9.zip |
LibDebug: Use DW_AT_ranges to get address ranges of DIEs
Previously, we only supported DIEs with a contiguous address ranges and
ignored ones with a non-contiguous set of ranges.
We now check if a DIE has the DW_AT_ranges attribute, and if it does we
parse its range list.
This improves the quality of our backtraces - we previously missed many
inlined function calls because their DIEs had non-contigues address
ranges.
Diffstat (limited to 'Userland/Libraries/LibDebug/Dwarf')
-rw-r--r-- | Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp | 18 | ||||
-rw-r--r-- | Userland/Libraries/LibDebug/Dwarf/DwarfInfo.h | 2 |
2 files changed, 18 insertions, 2 deletions
diff --git a/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp b/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp index 1195edaa9e..8f36efa31e 100644 --- a/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp +++ b/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp @@ -5,6 +5,7 @@ */ #include "DwarfInfo.h" +#include "AddressRanges.h" #include "AttributeValue.h" #include "CompilationUnit.h" @@ -21,6 +22,7 @@ DwarfInfo::DwarfInfo(ELF::Image const& elf) m_debug_strings_data = section_data(".debug_str"sv); m_debug_line_data = section_data(".debug_line"sv); m_debug_line_strings_data = section_data(".debug_line_str"sv); + m_debug_range_lists_data = section_data(".debug_rnglists"sv); populate_compilation_units(); } @@ -241,8 +243,20 @@ void DwarfInfo::build_cached_dies() const m_cached_dies_by_range.insert(range.start_address, DIEAndRange { die, range }); m_cached_dies_by_offset.insert(die.offset(), die); }; - auto get_ranges_of_die = [](DIE const& die) -> Vector<DIERange> { - // TODO support DW_AT_ranges (appears when range is non-contiguous) + auto get_ranges_of_die = [this](DIE const& die) -> Vector<DIERange> { + auto ranges = die.get_attribute(Attribute::Ranges); + if (ranges.has_value()) { + // TODO Support DW_FORM_rnglistx + if (ranges->form != AttributeDataForm::SecOffset) + return {}; + auto offset = ranges->data.as_addr; + AddressRanges address_ranges(debug_range_lists_data(), offset, die.compilation_unit()); + Vector<DIERange> entries; + address_ranges.for_each_range([&entries](auto range) { + entries.empend(range.start, range.end); + }); + return entries; + } auto start = die.get_attribute(Attribute::LowPc); auto end = die.get_attribute(Attribute::HighPc); diff --git a/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.h b/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.h index 105cebde29..24f7e9a2d3 100644 --- a/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.h +++ b/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.h @@ -30,6 +30,7 @@ public: ReadonlyBytes abbreviation_data() const { return m_abbreviation_data; } ReadonlyBytes debug_strings_data() const { return m_debug_strings_data; } ReadonlyBytes debug_line_strings_data() const { return m_debug_line_strings_data; } + ReadonlyBytes debug_range_lists_data() const { return m_debug_range_lists_data; } template<typename Callback> void for_each_compilation_unit(Callback) const; @@ -58,6 +59,7 @@ private: ReadonlyBytes m_debug_strings_data; ReadonlyBytes m_debug_line_data; ReadonlyBytes m_debug_line_strings_data; + ReadonlyBytes m_debug_range_lists_data; NonnullOwnPtrVector<Dwarf::CompilationUnit> m_compilation_units; |