diff --git a/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.cpp b/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.cpp index fd74dea5b28..1539c2ed33a 100644 --- a/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.cpp +++ b/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.cpp @@ -6,22 +6,46 @@ #include "CompilationUnit.h" #include +#include #include #include #include namespace Debug::Dwarf { -CompilationUnit::CompilationUnit(DwarfInfo const& dwarf_info, u32 offset, CompilationUnitHeader const& header, NonnullOwnPtr&& line_program) +CompilationUnit::CompilationUnit(DwarfInfo const& dwarf_info, u32 offset, CompilationUnitHeader const& header) : m_dwarf_info(dwarf_info) , m_offset(offset) , m_header(header) , m_abbreviations(dwarf_info, header.abbrev_offset()) - , m_line_program(move(line_program)) { VERIFY(header.version() < 5 || header.unit_type() == CompilationUnitType::Full); } +ErrorOr> CompilationUnit::create(DwarfInfo const& dwarf_info, u32 offset, CompilationUnitHeader const& header, ReadonlyBytes debug_line_data) +{ + auto compilation_unit = TRY(adopt_nonnull_own_or_enomem(new (nothrow) CompilationUnit(dwarf_info, offset, header))); + TRY(compilation_unit->populate_line_program(debug_line_data)); + return compilation_unit; +} + +ErrorOr CompilationUnit::populate_line_program(ReadonlyBytes debug_line_data) +{ + auto die = root_die(); + + auto res = TRY(die.get_attribute(Attribute::StmtList)); + if (!res.has_value()) + return EINVAL; + VERIFY(res->form() == AttributeDataForm::SecOffset); + + FixedMemoryStream debug_line_stream { debug_line_data }; + TRY(debug_line_stream.seek(res->as_unsigned())); + + m_line_program = TRY(LineProgram::create(m_dwarf_info, debug_line_stream)); + + return {}; +} + CompilationUnit::~CompilationUnit() = default; DIE CompilationUnit::root_die() const diff --git a/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.h b/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.h index 138f49c80d2..f8d8c850b54 100644 --- a/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.h +++ b/Userland/Libraries/LibDebug/Dwarf/CompilationUnit.h @@ -8,7 +8,7 @@ #include "AbbreviationsMap.h" #include -#include +#include #include namespace Debug::Dwarf { @@ -22,7 +22,7 @@ class CompilationUnit { AK_MAKE_NONMOVABLE(CompilationUnit); public: - CompilationUnit(DwarfInfo const& dwarf_info, u32 offset, CompilationUnitHeader const&, NonnullOwnPtr&& line_program); + static ErrorOr> create(DwarfInfo const& dwarf_info, u32 offset, CompilationUnitHeader const&, ReadonlyBytes debug_line_data); ~CompilationUnit(); u32 offset() const { return m_offset; } @@ -49,11 +49,14 @@ public: ErrorOr range_lists_base() const; private: + CompilationUnit(DwarfInfo const& dwarf_info, u32 offset, CompilationUnitHeader const&); + ErrorOr populate_line_program(ReadonlyBytes debug_line_data); + DwarfInfo const& m_dwarf_info; u32 m_offset { 0 }; CompilationUnitHeader m_header; AbbreviationsMap m_abbreviations; - NonnullOwnPtr m_line_program; + OwnPtr m_line_program; mutable bool m_has_cached_base_address : 1 { false }; mutable bool m_has_cached_address_table_base : 1 { false }; mutable bool m_has_cached_string_offsets_base : 1 { false }; diff --git a/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp b/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp index 230ac015b74..8405725627a 100644 --- a/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp +++ b/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp @@ -48,7 +48,6 @@ ErrorOr DwarfInfo::populate_compilation_units() return {}; FixedMemoryStream debug_info_stream { m_debug_info_data }; - FixedMemoryStream line_info_stream { m_debug_line_data }; while (!debug_info_stream.is_eof()) { auto unit_offset = TRY(debug_info_stream.tell()); @@ -59,23 +58,10 @@ ErrorOr DwarfInfo::populate_compilation_units() u32 length_after_header = compilation_unit_header.length() - (compilation_unit_header.header_size() - offsetof(CompilationUnitHeader, common.version)); - auto line_program = TRY(LineProgram::create(*this, line_info_stream)); - - // HACK: Clang generates line programs for embedded resource assembly files, but not compile units. - // Meaning that for graphical applications, some line info data would be unread, triggering the assertion below. - // As a fix, we don't create compilation units for line programs that come from resource files. -#if defined(AK_COMPILER_CLANG) - if (line_program->looks_like_embedded_resource()) { - TRY(debug_info_stream.seek(unit_offset)); - } else -#endif - { - m_compilation_units.append(make(*this, unit_offset, compilation_unit_header, move(line_program))); - TRY(debug_info_stream.discard(length_after_header)); - } + m_compilation_units.append(TRY(CompilationUnit::create(*this, unit_offset, compilation_unit_header, m_debug_line_data))); + TRY(debug_info_stream.discard(length_after_header)); } - VERIFY(line_info_stream.is_eof()); return {}; }