diff --git a/Userland/Libraries/LibDebug/Dwarf/AddressRanges.cpp b/Userland/Libraries/LibDebug/Dwarf/AddressRanges.cpp index caa9a9e5dd..d1c5f648a4 100644 --- a/Userland/Libraries/LibDebug/Dwarf/AddressRanges.cpp +++ b/Userland/Libraries/LibDebug/Dwarf/AddressRanges.cpp @@ -6,34 +6,34 @@ #include "AddressRanges.h" #include "DwarfTypes.h" +#include +#include namespace Debug::Dwarf { -AddressRangesV5::AddressRangesV5(ReadonlyBytes range_lists_data, size_t offset, CompilationUnit const& compilation_unit) - : m_range_lists_stream(range_lists_data) +AddressRangesV5::AddressRangesV5(NonnullOwnPtr range_lists_stream, CompilationUnit const& compilation_unit) + : m_range_lists_stream(move(range_lists_stream)) , m_compilation_unit(compilation_unit) { - m_range_lists_stream.seek(offset); } -void AddressRangesV5::for_each_range(Function callback) +ErrorOr AddressRangesV5::for_each_range(Function callback) { // Dwarf version 5, section 2.17.3 "Non-Contiguous Address Ranges" + Core::Stream::WrapInAKInputStream wrapped_range_lists_stream { *m_range_lists_stream }; + Optional current_base_address; - while (!m_range_lists_stream.eof() && !m_range_lists_stream.has_any_error()) { - u8 entry_type; - m_range_lists_stream >> entry_type; + while (!m_range_lists_stream->is_eof()) { + auto entry_type = TRY(m_range_lists_stream->read_value()); switch (static_cast(entry_type)) { case RangeListEntryType::BaseAddress: { - FlatPtr base; - m_range_lists_stream >> base; - current_base_address = base; + current_base_address = TRY(m_range_lists_stream->read_value()); break; } case RangeListEntryType::BaseAddressX: { FlatPtr index; - m_range_lists_stream.read_LEB128_unsigned(index); + LEB128::read_unsigned(wrapped_range_lists_stream, index); current_base_address = m_compilation_unit.get_address(index); break; } @@ -43,68 +43,66 @@ void AddressRangesV5::for_each_range(Function callback) base_address = m_compilation_unit.base_address(); } - if (!base_address.has_value()) { - dbgln("expected base_address for rangelist"); - return; - } + if (!base_address.has_value()) + return Error::from_string_literal("Expected base_address for rangelist"); size_t start_offset, end_offset; - m_range_lists_stream.read_LEB128_unsigned(start_offset); - m_range_lists_stream.read_LEB128_unsigned(end_offset); + LEB128::read_unsigned(wrapped_range_lists_stream, start_offset); + LEB128::read_unsigned(wrapped_range_lists_stream, end_offset); callback(Range { start_offset + *base_address, end_offset + *base_address }); break; } case RangeListEntryType::StartLength: { - FlatPtr start; - m_range_lists_stream >> start; + auto start = TRY(m_range_lists_stream->read_value()); size_t length; - m_range_lists_stream.read_LEB128_unsigned(length); + LEB128::read_unsigned(wrapped_range_lists_stream, length); 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); + LEB128::read_unsigned(wrapped_range_lists_stream, start); + LEB128::read_unsigned(wrapped_range_lists_stream, 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); + LEB128::read_unsigned(wrapped_range_lists_stream, start); + LEB128::read_unsigned(wrapped_range_lists_stream, length); auto start_addr = m_compilation_unit.get_address(start); callback(Range { start_addr, start_addr + length }); break; } case RangeListEntryType::EndOfList: - return; + return {}; default: dbgln("unsupported range list entry type: 0x{:x}", entry_type); - return; + return Error::from_string_literal("Unsupported range list entry type"); } } + + return {}; } -AddressRangesV4::AddressRangesV4(ReadonlyBytes ranges_data, size_t offset, CompilationUnit const& compilation_unit) - : m_ranges_stream(ranges_data) +AddressRangesV4::AddressRangesV4(NonnullOwnPtr ranges_stream, CompilationUnit const& compilation_unit) + : m_ranges_stream(move(ranges_stream)) , m_compilation_unit(compilation_unit) { - m_ranges_stream.seek(offset); } -void AddressRangesV4::for_each_range(Function callback) +ErrorOr AddressRangesV4::for_each_range(Function callback) { // Dwarf version 4, section 2.17.3 "Non-Contiguous Address Ranges" Optional current_base_address; - while (!m_ranges_stream.eof() && !m_ranges_stream.has_any_error()) { - FlatPtr begin, end; - m_ranges_stream >> begin >> end; + while (!m_ranges_stream->is_eof()) { + auto begin = TRY(m_ranges_stream->read_value()); + auto end = TRY(m_ranges_stream->read_value()); if (begin == 0 && end == 0) { // end of list entry - return; + return {}; } else if (begin == explode_byte(0xff)) { current_base_address = end; } else { @@ -112,6 +110,8 @@ void AddressRangesV4::for_each_range(Function callback) callback({ base + begin, base + end }); } } + + return {}; } } diff --git a/Userland/Libraries/LibDebug/Dwarf/AddressRanges.h b/Userland/Libraries/LibDebug/Dwarf/AddressRanges.h index f14451d4ea..cb440832c2 100644 --- a/Userland/Libraries/LibDebug/Dwarf/AddressRanges.h +++ b/Userland/Libraries/LibDebug/Dwarf/AddressRanges.h @@ -11,6 +11,7 @@ #include #include #include +#include namespace Debug::Dwarf { @@ -24,12 +25,12 @@ class AddressRangesV5 { AK_MAKE_NONMOVABLE(AddressRangesV5); public: - AddressRangesV5(ReadonlyBytes range_lists_data, size_t offset, CompilationUnit const& compilation_unit); + AddressRangesV5(NonnullOwnPtr range_lists_stream, CompilationUnit const& compilation_unit); - void for_each_range(Function); + ErrorOr for_each_range(Function); private: - InputMemoryStream m_range_lists_stream; + NonnullOwnPtr m_range_lists_stream; CompilationUnit const& m_compilation_unit; }; @@ -38,12 +39,12 @@ class AddressRangesV4 { AK_MAKE_NONMOVABLE(AddressRangesV4); public: - AddressRangesV4(ReadonlyBytes ranges_data, size_t offset, CompilationUnit const&); + AddressRangesV4(NonnullOwnPtr ranges_stream, CompilationUnit const&); - void for_each_range(Function); + ErrorOr for_each_range(Function); private: - InputMemoryStream m_ranges_stream; + NonnullOwnPtr m_ranges_stream; CompilationUnit const& m_compilation_unit; }; diff --git a/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp b/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp index 67f941806c..3c2fc212dd 100644 --- a/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp +++ b/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp @@ -11,6 +11,7 @@ #include #include +#include #include namespace Debug::Dwarf { @@ -337,7 +338,7 @@ 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 = [this](DIE const& die) -> Vector { + auto get_ranges_of_die = [this](DIE const& die) -> ErrorOr> { auto ranges = die.get_attribute(Attribute::Ranges); if (ranges.has_value()) { size_t offset; @@ -353,15 +354,19 @@ void DwarfInfo::build_cached_dies() const Vector entries; if (die.compilation_unit().dwarf_version() == 5) { - AddressRangesV5 address_ranges(debug_range_lists_data(), offset, die.compilation_unit()); - address_ranges.for_each_range([&entries](auto range) { + auto range_lists_stream = TRY(Core::Stream::FixedMemoryStream::construct(debug_range_lists_data())); + TRY(range_lists_stream->seek(offset)); + AddressRangesV5 address_ranges(move(range_lists_stream), die.compilation_unit()); + TRY(address_ranges.for_each_range([&entries](auto range) { entries.empend(range.start, range.end); - }); + })); } else { - AddressRangesV4 address_ranges(debug_ranges_data(), offset, die.compilation_unit()); - address_ranges.for_each_range([&entries](auto range) { + auto ranges_stream = TRY(Core::Stream::FixedMemoryStream::construct(debug_ranges_data())); + TRY(ranges_stream->seek(offset)); + AddressRangesV4 address_ranges(move(ranges_stream), die.compilation_unit()); + TRY(address_ranges.for_each_range([&entries](auto range) { entries.empend(range.start, range.end); - }); + })); } return entries; } @@ -370,7 +375,7 @@ void DwarfInfo::build_cached_dies() const auto end = die.get_attribute(Attribute::HighPc); if (!start.has_value() || !end.has_value()) - return {}; + return Vector {}; VERIFY(start->type() == Dwarf::AttributeValue::Type::Address); @@ -383,14 +388,14 @@ void DwarfInfo::build_cached_dies() const else range_end = start->as_addr() + end->as_unsigned(); - return { DIERange { start.value().as_addr(), range_end } }; + return Vector { DIERange { start.value().as_addr(), range_end } }; }; // If we simply use a lambda, type deduction fails because it's used recursively. Function insert_to_cache_recursively; insert_to_cache_recursively = [&](DIE const& die) { if (die.offset() == 0 || die.parent_offset().has_value()) { - auto ranges = get_ranges_of_die(die); + auto ranges = get_ranges_of_die(die).release_value_but_fixme_should_propagate_errors(); for (auto& range : ranges) { insert_to_cache(die, range); }