LibDebug: Move Dwarf::LineProgram into Dwarf::CompilationUnit

Previously, the LineProgram objects were short-lived, and only created
inside DebugInfo::prepare_lines() to create a vector of sorted LineInfo
data.

However, Dwarf::LineProgram also contains other useful data, such as
index-to-string mapping of source directories and filenames.

This commit makes each Dwarf::CompilationUnit own its
Dwarf::LineProgram.
DebugInfo::prepare_lines() then iterates over the compilation units to
prepare its sorted vector of lines.
This commit is contained in:
Itamar 2021-06-18 15:25:27 +03:00 committed by Andreas Kling
parent e9e4358a93
commit 0d89f70b66
Notes: sideshowbarker 2024-07-18 12:01:43 +09:00
6 changed files with 30 additions and 17 deletions

View file

@ -78,17 +78,11 @@ void DebugInfo::parse_scopes_impl(const Dwarf::DIE& die)
void DebugInfo::prepare_lines()
{
auto section = elf().lookup_section(".debug_line"sv);
if (!section.has_value())
return;
InputMemoryStream stream { section->bytes() };
Vector<Dwarf::LineProgram::LineInfo> all_lines;
while (!stream.eof()) {
Dwarf::LineProgram program(m_dwarf_info, stream);
all_lines.extend(program.lines());
}
m_dwarf_info.for_each_compilation_unit([&all_lines](const Dwarf::CompilationUnit& unit) {
all_lines.extend(unit.line_program().lines());
});
HashMap<FlyString, Optional<String>> memoized_full_paths;
auto compute_full_path = [&](FlyString const& file_path) -> Optional<String> {

View file

@ -9,11 +9,12 @@
namespace Debug::Dwarf {
CompilationUnit::CompilationUnit(const DwarfInfo& dwarf_info, u32 offset, const CompilationUnitHeader& header)
CompilationUnit::CompilationUnit(const DwarfInfo& dwarf_info, u32 offset, const CompilationUnitHeader& header, NonnullOwnPtr<LineProgram>&& line_program)
: 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);
}

View file

@ -7,6 +7,8 @@
#pragma once
#include "AbbreviationsMap.h"
#include "DIE.h"
#include "LineProgram.h"
#include <AK/Noncopyable.h>
#include <AK/Types.h>
@ -14,13 +16,14 @@ namespace Debug::Dwarf {
class DwarfInfo;
class DIE;
class LineProgram;
class CompilationUnit {
AK_MAKE_NONCOPYABLE(CompilationUnit);
AK_MAKE_NONMOVABLE(CompilationUnit);
public:
CompilationUnit(const DwarfInfo& dwarf_info, u32 offset, const CompilationUnitHeader&);
CompilationUnit(const DwarfInfo& dwarf_info, u32 offset, const CompilationUnitHeader&, NonnullOwnPtr<LineProgram>&& line_program);
u32 offset() const { return m_offset; }
u32 size() const { return m_header.length() + sizeof(u32); }
@ -30,12 +33,14 @@ public:
const DwarfInfo& dwarf_info() const { return m_dwarf_info; }
const AbbreviationsMap& abbreviations_map() const { return m_abbreviations; }
const LineProgram& line_program() const { return *m_line_program; }
private:
const DwarfInfo& m_dwarf_info;
u32 m_offset { 0 };
CompilationUnitHeader m_header;
AbbreviationsMap m_abbreviations;
NonnullOwnPtr<LineProgram> m_line_program;
};
}

View file

@ -16,6 +16,7 @@ DwarfInfo::DwarfInfo(const ELF::Image& elf)
m_debug_info_data = section_data(".debug_info"sv);
m_abbreviation_data = section_data(".debug_abbrev"sv);
m_debug_strings_data = section_data(".debug_str"sv);
m_debug_line_data = section_data(".debug_line"sv);
m_debug_line_strings_data = section_data(".debug_line_str"sv);
populate_compilation_units();
@ -34,19 +35,26 @@ void DwarfInfo::populate_compilation_units()
if (!m_debug_info_data.data())
return;
InputMemoryStream stream { m_debug_info_data };
while (!stream.eof()) {
auto unit_offset = stream.offset();
InputMemoryStream debug_info_stream { m_debug_info_data };
InputMemoryStream line_info_stream { m_debug_line_data };
while (!debug_info_stream.eof()) {
auto unit_offset = debug_info_stream.offset();
CompilationUnitHeader compilation_unit_header {};
stream >> compilation_unit_header;
debug_info_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() - (compilation_unit_header.header_size() - offsetof(CompilationUnitHeader, common.version));
m_compilation_units.append(make<CompilationUnit>(*this, unit_offset, compilation_unit_header));
stream.discard_or_error(length_after_header);
auto line_program = make<LineProgram>(*this, line_info_stream);
m_compilation_units.append(make<CompilationUnit>(*this, unit_offset, compilation_unit_header, move(line_program)));
debug_info_stream.discard_or_error(length_after_header);
}
VERIFY(line_info_stream.eof());
}
AttributeValue DwarfInfo::get_attribute_value(AttributeDataForm form, ssize_t implicit_const_value,

View file

@ -12,6 +12,7 @@
#include <AK/ByteBuffer.h>
#include <AK/NonnullOwnPtrVector.h>
#include <AK/NonnullRefPtr.h>
#include <AK/RedBlackTree.h>
#include <AK/RefCounted.h>
#include <AK/String.h>
#include <LibELF/Image.h>
@ -45,6 +46,7 @@ private:
ReadonlyBytes m_debug_info_data;
ReadonlyBytes m_abbreviation_data;
ReadonlyBytes m_debug_strings_data;
ReadonlyBytes m_debug_line_data;
ReadonlyBytes m_debug_line_strings_data;
NonnullOwnPtrVector<Dwarf::CompilationUnit> m_compilation_units;

View file

@ -102,6 +102,9 @@ inline InputStream& operator>>(InputStream& stream, LineProgramUnitHeader32& hea
}
class LineProgram {
AK_MAKE_NONCOPYABLE(LineProgram);
AK_MAKE_NONMOVABLE(LineProgram);
public:
explicit LineProgram(DwarfInfo& dwarf_info, InputMemoryStream& stream);