mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:17:34 +00:00
LibDebug: Implement support for DWARF 5 compilation unit headers
This commit is contained in:
parent
a3f2af49f9
commit
6b4448b623
4 changed files with 54 additions and 8 deletions
|
@ -12,13 +12,14 @@ CompilationUnit::CompilationUnit(const DwarfInfo& dwarf_info, u32 offset, const
|
||||||
: m_dwarf_info(dwarf_info)
|
: m_dwarf_info(dwarf_info)
|
||||||
, m_offset(offset)
|
, m_offset(offset)
|
||||||
, m_header(header)
|
, m_header(header)
|
||||||
, m_abbreviations(dwarf_info, header.abbrev_offset)
|
, m_abbreviations(dwarf_info, header.abbrev_offset())
|
||||||
{
|
{
|
||||||
|
VERIFY(header.version() < 5 || header.unit_type() == CompilationUnitType::Full);
|
||||||
}
|
}
|
||||||
|
|
||||||
DIE CompilationUnit::root_die() const
|
DIE CompilationUnit::root_die() const
|
||||||
{
|
{
|
||||||
return DIE(*this, m_offset + sizeof(CompilationUnitHeader));
|
return DIE(*this, m_offset + m_header.header_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ public:
|
||||||
CompilationUnit(const DwarfInfo& dwarf_info, u32 offset, const CompilationUnitHeader&);
|
CompilationUnit(const DwarfInfo& dwarf_info, u32 offset, const CompilationUnitHeader&);
|
||||||
|
|
||||||
u32 offset() const { return m_offset; }
|
u32 offset() const { return m_offset; }
|
||||||
u32 size() const { return m_header.length + sizeof(u32); }
|
u32 size() const { return m_header.length() + sizeof(u32); }
|
||||||
|
|
||||||
DIE root_die() const;
|
DIE root_die() const;
|
||||||
|
|
||||||
|
|
|
@ -38,11 +38,11 @@ void DwarfInfo::populate_compilation_units()
|
||||||
auto unit_offset = stream.offset();
|
auto unit_offset = stream.offset();
|
||||||
CompilationUnitHeader compilation_unit_header {};
|
CompilationUnitHeader compilation_unit_header {};
|
||||||
|
|
||||||
stream >> Bytes { &compilation_unit_header, sizeof(compilation_unit_header) };
|
stream >> compilation_unit_header;
|
||||||
VERIFY(compilation_unit_header.address_size == sizeof(u32));
|
VERIFY(compilation_unit_header.common.version <= 5);
|
||||||
VERIFY(compilation_unit_header.version <= 4);
|
VERIFY(compilation_unit_header.address_size() == sizeof(u32));
|
||||||
|
|
||||||
u32 length_after_header = compilation_unit_header.length - (sizeof(CompilationUnitHeader) - offsetof(CompilationUnitHeader, version));
|
u32 length_after_header = compilation_unit_header.length() - (compilation_unit_header.header_size() - offsetof(CompilationUnitHeader, common.version));
|
||||||
m_compilation_units.empend(*this, unit_offset, compilation_unit_header);
|
m_compilation_units.empend(*this, unit_offset, compilation_unit_header);
|
||||||
stream.discard_or_error(length_after_header);
|
stream.discard_or_error(length_after_header);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,17 +6,62 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Stream.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
|
|
||||||
namespace Debug::Dwarf {
|
namespace Debug::Dwarf {
|
||||||
|
|
||||||
struct [[gnu::packed]] CompilationUnitHeader {
|
enum class CompilationUnitType {
|
||||||
|
Full = 1,
|
||||||
|
Partial = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
struct [[gnu::packed]] CompilationUnitHeaderCommon {
|
||||||
u32 length;
|
u32 length;
|
||||||
u16 version;
|
u16 version;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct [[gnu::packed]] CompilationUnitHeaderV4Ext {
|
||||||
u32 abbrev_offset;
|
u32 abbrev_offset;
|
||||||
u8 address_size;
|
u8 address_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct [[gnu::packed]] CompilationUnitHeaderV5Ext {
|
||||||
|
u8 unit_type;
|
||||||
|
u8 address_size;
|
||||||
|
u32 abbrev_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct [[gnu::packed]] CompilationUnitHeader {
|
||||||
|
CompilationUnitHeaderCommon common;
|
||||||
|
|
||||||
|
union {
|
||||||
|
CompilationUnitHeaderV4Ext v4;
|
||||||
|
CompilationUnitHeaderV5Ext v5;
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t header_size() const
|
||||||
|
{
|
||||||
|
return sizeof(common) + ((common.version <= 4) ? sizeof(v4) : sizeof(v5));
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 length() const { return common.length; }
|
||||||
|
u16 version() const { return common.version; }
|
||||||
|
CompilationUnitType unit_type() const { return (common.version <= 4) ? CompilationUnitType::Full : (CompilationUnitType)v5.unit_type; }
|
||||||
|
u32 abbrev_offset() const { return (common.version <= 4) ? v4.abbrev_offset : v5.abbrev_offset; }
|
||||||
|
u8 address_size() const { return (common.version <= 4) ? v4.address_size : v5.address_size; }
|
||||||
|
};
|
||||||
|
|
||||||
|
inline InputStream& operator>>(InputStream& stream, CompilationUnitHeader& header)
|
||||||
|
{
|
||||||
|
stream.read_or_error(Bytes { &header.common, sizeof(header.common) });
|
||||||
|
if (header.common.version <= 4)
|
||||||
|
stream.read_or_error(Bytes { &header.v4, sizeof(header.v4) });
|
||||||
|
else
|
||||||
|
stream.read_or_error(Bytes { &header.v5, sizeof(header.v5) });
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
enum class EntryTag : u16 {
|
enum class EntryTag : u16 {
|
||||||
None = 0,
|
None = 0,
|
||||||
ArrayType = 0x1,
|
ArrayType = 0x1,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue