diff options
author | Gunnar Beutner <gbeutner@serenityos.org> | 2021-04-28 22:13:58 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-04-28 23:10:48 +0200 |
commit | 6b4448b62301fcb1faf47ccd34c94b162c05981d (patch) | |
tree | 62e079ee0a35274a7289dbdc01d7dda65160b7e4 | |
parent | a3f2af49f9dee706265016796a80c32076ee5569 (diff) | |
download | serenity-6b4448b62301fcb1faf47ccd34c94b162c05981d.zip |
LibDebug: Implement support for DWARF 5 compilation unit headers
4 files changed, 54 insertions, 8 deletions
diff --git a/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.cpp b/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.cpp index 2b6062639f..9f6e163d87 100644 --- a/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.cpp +++ b/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.cpp @@ -12,13 +12,14 @@ CompilationUnit::CompilationUnit(const DwarfInfo& dwarf_info, u32 offset, const : m_dwarf_info(dwarf_info) , m_offset(offset) , 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 { - return DIE(*this, m_offset + sizeof(CompilationUnitHeader)); + return DIE(*this, m_offset + m_header.header_size()); } } diff --git a/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.h b/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.h index 7a74c4eac5..d48c781b67 100644 --- a/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.h +++ b/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.h @@ -19,7 +19,7 @@ public: CompilationUnit(const DwarfInfo& dwarf_info, u32 offset, const CompilationUnitHeader&); 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; diff --git a/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp b/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp index 19d1793099..0ecc613596 100644 --- a/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp +++ b/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp @@ -38,11 +38,11 @@ void DwarfInfo::populate_compilation_units() auto unit_offset = stream.offset(); CompilationUnitHeader compilation_unit_header {}; - stream >> Bytes { &compilation_unit_header, sizeof(compilation_unit_header) }; - VERIFY(compilation_unit_header.address_size == sizeof(u32)); - VERIFY(compilation_unit_header.version <= 4); + stream >> compilation_unit_header; + VERIFY(compilation_unit_header.common.version <= 5); + 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); stream.discard_or_error(length_after_header); } diff --git a/Userland/Libraries/LibDebug/Dwarf/DwarfTypes.h b/Userland/Libraries/LibDebug/Dwarf/DwarfTypes.h index c11827e40d..19de2ea809 100644 --- a/Userland/Libraries/LibDebug/Dwarf/DwarfTypes.h +++ b/Userland/Libraries/LibDebug/Dwarf/DwarfTypes.h @@ -6,17 +6,62 @@ #pragma once +#include <AK/Stream.h> #include <AK/Types.h> namespace Debug::Dwarf { -struct [[gnu::packed]] CompilationUnitHeader { +enum class CompilationUnitType { + Full = 1, + Partial = 3 +}; + +struct [[gnu::packed]] CompilationUnitHeaderCommon { u32 length; u16 version; +}; + +struct [[gnu::packed]] CompilationUnitHeaderV4Ext { u32 abbrev_offset; 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 { None = 0, ArrayType = 0x1, |