summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibDebug/Dwarf/AddressRanges.cpp21
-rw-r--r--Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp14
2 files changed, 31 insertions, 4 deletions
diff --git a/Userland/Libraries/LibDebug/Dwarf/AddressRanges.cpp b/Userland/Libraries/LibDebug/Dwarf/AddressRanges.cpp
index ea7c199e72..cb77e95c65 100644
--- a/Userland/Libraries/LibDebug/Dwarf/AddressRanges.cpp
+++ b/Userland/Libraries/LibDebug/Dwarf/AddressRanges.cpp
@@ -31,6 +31,12 @@ void AddressRanges::for_each_range(Function<void(Range)> callback)
current_base_address = base;
break;
}
+ case RangeListEntryType::BaseAddressX: {
+ FlatPtr index;
+ m_range_lists_stream.read_LEB128_unsigned(index);
+ current_base_address = m_compilation_unit.get_address(index);
+ break;
+ }
case RangeListEntryType::OffsetPair: {
Optional<FlatPtr> base_address = current_base_address;
if (!base_address.has_value()) {
@@ -56,6 +62,21 @@ void AddressRanges::for_each_range(Function<void(Range)> callback)
callback(Range { start, start + length });
break;
}
+ case RangeListEntryType::StartXEndX: {
+ size_t start, end;
+ m_range_lists_stream.read_LEB128_unsigned(start);
+ m_range_lists_stream.read_LEB128_unsigned(end);
+ callback(Range { m_compilation_unit.get_address(start), m_compilation_unit.get_address(end) });
+ break;
+ }
+ case RangeListEntryType::StartXLength: {
+ size_t start, length;
+ m_range_lists_stream.read_LEB128_unsigned(start);
+ m_range_lists_stream.read_LEB128_unsigned(length);
+ auto start_addr = m_compilation_unit.get_address(start);
+ callback(Range { start_addr, start_addr + length });
+ break;
+ }
case RangeListEntryType::EndOfList:
return;
default:
diff --git a/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp b/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp
index 8cbc633c04..2a2c3bbd83 100644
--- a/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp
+++ b/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp
@@ -326,10 +326,16 @@ void DwarfInfo::build_cached_dies() const
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->as_unsigned();
+ size_t offset;
+ if (ranges->form() == AttributeDataForm::SecOffset) {
+ offset = ranges->as_unsigned();
+ } else {
+ auto index = ranges->as_unsigned();
+ auto base = die.compilation_unit().range_lists_base();
+ // FIXME: This assumes that the format is DWARf32
+ auto offsets = reinterpret_cast<u32 const*>(debug_range_lists_data().offset(base));
+ offset = offsets[index] + base;
+ }
AddressRanges address_ranges(debug_range_lists_data(), offset, die.compilation_unit());
Vector<DIERange> entries;
address_ranges.for_each_range([&entries](auto range) {