mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 20:07:36 +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
5 changed files with 70 additions and 14 deletions
|
@ -9,14 +9,14 @@
|
||||||
|
|
||||||
namespace Debug::Dwarf {
|
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_range_lists_stream(range_lists_data)
|
||||||
, m_compilation_unit(compilation_unit)
|
, m_compilation_unit(compilation_unit)
|
||||||
{
|
{
|
||||||
m_range_lists_stream.seek(offset);
|
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"
|
// 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 {
|
namespace Debug::Dwarf {
|
||||||
|
|
||||||
class AddressRanges {
|
struct Range {
|
||||||
AK_MAKE_NONCOPYABLE(AddressRanges);
|
|
||||||
AK_MAKE_NONMOVABLE(AddressRanges);
|
|
||||||
|
|
||||||
public:
|
|
||||||
AddressRanges(ReadonlyBytes range_lists_data, size_t offset, CompilationUnit const& compilation_unit);
|
|
||||||
|
|
||||||
struct Range {
|
|
||||||
FlatPtr start { 0 };
|
FlatPtr start { 0 };
|
||||||
FlatPtr end { 0 };
|
FlatPtr end { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class AddressRangesV5 {
|
||||||
|
AK_MAKE_NONCOPYABLE(AddressRangesV5);
|
||||||
|
AK_MAKE_NONMOVABLE(AddressRangesV5);
|
||||||
|
|
||||||
|
public:
|
||||||
|
AddressRangesV5(ReadonlyBytes range_lists_data, size_t offset, CompilationUnit const& compilation_unit);
|
||||||
|
|
||||||
void for_each_range(Function<void(Range)>);
|
void for_each_range(Function<void(Range)>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -32,4 +33,18 @@ private:
|
||||||
CompilationUnit const& m_compilation_unit;
|
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;
|
FlatPtr get_address(size_t index) const;
|
||||||
char const* get_string(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; }
|
DwarfInfo const& dwarf_info() const { return m_dwarf_info; }
|
||||||
AbbreviationsMap const& abbreviations_map() const { return m_abbreviations; }
|
AbbreviationsMap const& abbreviations_map() const { return m_abbreviations; }
|
||||||
LineProgram const& line_program() const { return *m_line_program; }
|
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_range_lists_data = section_data(".debug_rnglists"sv);
|
||||||
m_debug_str_offsets_data = section_data(".debug_str_offsets"sv);
|
m_debug_str_offsets_data = section_data(".debug_str_offsets"sv);
|
||||||
m_debug_addr_data = section_data(".debug_addr"sv);
|
m_debug_addr_data = section_data(".debug_addr"sv);
|
||||||
|
m_debug_ranges_data = section_data(".debug_ranges"sv);
|
||||||
|
|
||||||
populate_compilation_units();
|
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));
|
auto offsets = reinterpret_cast<u32 const*>(debug_range_lists_data().offset(base));
|
||||||
offset = offsets[index] + base;
|
offset = offsets[index] + base;
|
||||||
}
|
}
|
||||||
AddressRanges address_ranges(debug_range_lists_data(), offset, die.compilation_unit());
|
|
||||||
Vector<DIERange> entries;
|
Vector<DIERange> 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) {
|
address_ranges.for_each_range([&entries](auto range) {
|
||||||
entries.empend(range.start, range.end);
|
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;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ public:
|
||||||
ReadonlyBytes debug_range_lists_data() const { return m_debug_range_lists_data; }
|
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_str_offsets_data() const { return m_debug_str_offsets_data; }
|
||||||
ReadonlyBytes debug_addr_data() const { return m_debug_addr_data; }
|
ReadonlyBytes debug_addr_data() const { return m_debug_addr_data; }
|
||||||
|
ReadonlyBytes debug_ranges_data() const { return m_debug_ranges_data; }
|
||||||
|
|
||||||
template<typename Callback>
|
template<typename Callback>
|
||||||
void for_each_compilation_unit(Callback) const;
|
void for_each_compilation_unit(Callback) const;
|
||||||
|
@ -64,6 +65,7 @@ private:
|
||||||
ReadonlyBytes m_debug_range_lists_data;
|
ReadonlyBytes m_debug_range_lists_data;
|
||||||
ReadonlyBytes m_debug_str_offsets_data;
|
ReadonlyBytes m_debug_str_offsets_data;
|
||||||
ReadonlyBytes m_debug_addr_data;
|
ReadonlyBytes m_debug_addr_data;
|
||||||
|
ReadonlyBytes m_debug_ranges_data;
|
||||||
|
|
||||||
NonnullOwnPtrVector<Dwarf::CompilationUnit> m_compilation_units;
|
NonnullOwnPtrVector<Dwarf::CompilationUnit> m_compilation_units;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue