summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibDebug/Dwarf
diff options
context:
space:
mode:
authorItamar <itamar8910@gmail.com>2021-09-28 13:35:28 +0300
committerAndreas Kling <kling@serenityos.org>2021-09-28 16:54:39 +0200
commit09153b899776fe38c271eef08f675a1b31d71cb9 (patch)
tree41fb98b96b106b8c706ff9fade4088c19dd3c9c8 /Userland/Libraries/LibDebug/Dwarf
parent26a96d315ddc7f1753e7d3cb5246c7817fedfb8f (diff)
downloadserenity-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.cpp18
-rw-r--r--Userland/Libraries/LibDebug/Dwarf/DwarfInfo.h2
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;