mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-15 04:13:11 +00:00
LibDebug: Handle DWARF 4 address ranges
The format of the address range section is different between DWARF version 4 and version 5. This meant that we parsed programs compiled with `-gdwarf-4` incorrectly.
This commit is contained in:
parent
7546295abe
commit
815f15f82c
|
@ -9,14 +9,14 @@
|
|||
|
||||
namespace Debug::Dwarf {
|
||||
|
||||
AddressRanges::AddressRanges(ReadonlyBytes range_lists_data, size_t offset, CompilationUnit const& compilation_unit)
|
||||
AddressRangesV5::AddressRangesV5(ReadonlyBytes range_lists_data, size_t offset, CompilationUnit const& compilation_unit)
|
||||
: m_range_lists_stream(range_lists_data)
|
||||
, m_compilation_unit(compilation_unit)
|
||||
{
|
||||
m_range_lists_stream.seek(offset);
|
||||
}
|
||||
|
||||
void AddressRanges::for_each_range(Function<void(Range)> callback)
|
||||
void AddressRangesV5::for_each_range(Function<void(Range)> callback)
|
||||
{
|
||||
// Dwarf version 5, section 2.17.3 "Non-Contiguous Address Ranges"
|
||||
|
||||
|
@ -86,4 +86,32 @@ void AddressRanges::for_each_range(Function<void(Range)> callback)
|
|||
}
|
||||
}
|
||||
|
||||
AddressRangesV4::AddressRangesV4(ReadonlyBytes ranges_data, size_t offset, CompilationUnit const& compilation_unit)
|
||||
: m_ranges_stream(ranges_data)
|
||||
, m_compilation_unit(compilation_unit)
|
||||
{
|
||||
m_ranges_stream.seek(offset);
|
||||
}
|
||||
|
||||
void AddressRangesV4::for_each_range(Function<void(Range)> callback)
|
||||
{
|
||||
// Dwarf version 4, section 2.17.3 "Non-Contiguous Address Ranges"
|
||||
|
||||
Optional<FlatPtr> current_base_address;
|
||||
while (!m_ranges_stream.eof() && !m_ranges_stream.has_any_error()) {
|
||||
FlatPtr begin, end;
|
||||
m_ranges_stream >> begin >> end;
|
||||
|
||||
if (begin == 0 && end == 0) {
|
||||
// end of list entry
|
||||
return;
|
||||
} else if (begin == explode_byte(0xff)) {
|
||||
current_base_address = end;
|
||||
} else {
|
||||
FlatPtr base = current_base_address.value_or(m_compilation_unit.base_address().value_or(0));
|
||||
callback({ base + begin, base + end });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,17 +14,18 @@
|
|||
|
||||
namespace Debug::Dwarf {
|
||||
|
||||
class AddressRanges {
|
||||
AK_MAKE_NONCOPYABLE(AddressRanges);
|
||||
AK_MAKE_NONMOVABLE(AddressRanges);
|
||||
struct Range {
|
||||
FlatPtr start { 0 };
|
||||
FlatPtr end { 0 };
|
||||
};
|
||||
|
||||
class AddressRangesV5 {
|
||||
AK_MAKE_NONCOPYABLE(AddressRangesV5);
|
||||
AK_MAKE_NONMOVABLE(AddressRangesV5);
|
||||
|
||||
public:
|
||||
AddressRanges(ReadonlyBytes range_lists_data, size_t offset, CompilationUnit const& compilation_unit);
|
||||
AddressRangesV5(ReadonlyBytes range_lists_data, size_t offset, CompilationUnit const& compilation_unit);
|
||||
|
||||
struct Range {
|
||||
FlatPtr start { 0 };
|
||||
FlatPtr end { 0 };
|
||||
};
|
||||
void for_each_range(Function<void(Range)>);
|
||||
|
||||
private:
|
||||
|
@ -32,4 +33,18 @@ private:
|
|||
CompilationUnit const& m_compilation_unit;
|
||||
};
|
||||
|
||||
class AddressRangesV4 {
|
||||
AK_MAKE_NONCOPYABLE(AddressRangesV4);
|
||||
AK_MAKE_NONMOVABLE(AddressRangesV4);
|
||||
|
||||
public:
|
||||
AddressRangesV4(ReadonlyBytes ranges_data, size_t offset, CompilationUnit const&);
|
||||
|
||||
void for_each_range(Function<void(Range)>);
|
||||
|
||||
private:
|
||||
InputMemoryStream m_ranges_stream;
|
||||
CompilationUnit const& m_compilation_unit;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ public:
|
|||
FlatPtr get_address(size_t index) const;
|
||||
char const* get_string(size_t index) const;
|
||||
|
||||
u8 dwarf_version() const { return m_header.version(); }
|
||||
|
||||
DwarfInfo const& dwarf_info() const { return m_dwarf_info; }
|
||||
AbbreviationsMap const& abbreviations_map() const { return m_abbreviations; }
|
||||
LineProgram const& line_program() const { return *m_line_program; }
|
||||
|
|
|
@ -25,6 +25,7 @@ DwarfInfo::DwarfInfo(ELF::Image const& elf)
|
|||
m_debug_range_lists_data = section_data(".debug_rnglists"sv);
|
||||
m_debug_str_offsets_data = section_data(".debug_str_offsets"sv);
|
||||
m_debug_addr_data = section_data(".debug_addr"sv);
|
||||
m_debug_ranges_data = section_data(".debug_ranges"sv);
|
||||
|
||||
populate_compilation_units();
|
||||
}
|
||||
|
@ -346,11 +347,19 @@ void DwarfInfo::build_cached_dies() const
|
|||
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) {
|
||||
entries.empend(range.start, range.end);
|
||||
});
|
||||
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) {
|
||||
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) {
|
||||
entries.empend(range.start, range.end);
|
||||
});
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
ReadonlyBytes debug_range_lists_data() const { return m_debug_range_lists_data; }
|
||||
ReadonlyBytes debug_str_offsets_data() const { return m_debug_str_offsets_data; }
|
||||
ReadonlyBytes debug_addr_data() const { return m_debug_addr_data; }
|
||||
ReadonlyBytes debug_ranges_data() const { return m_debug_ranges_data; }
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_compilation_unit(Callback) const;
|
||||
|
@ -64,6 +65,7 @@ private:
|
|||
ReadonlyBytes m_debug_range_lists_data;
|
||||
ReadonlyBytes m_debug_str_offsets_data;
|
||||
ReadonlyBytes m_debug_addr_data;
|
||||
ReadonlyBytes m_debug_ranges_data;
|
||||
|
||||
NonnullOwnPtrVector<Dwarf::CompilationUnit> m_compilation_units;
|
||||
|
||||
|
|
Loading…
Reference in a new issue