Jelajahi Sumber

LibDebug: Move get_attribute_value to the DwarfInfo class

Gunnar Beutner 4 tahun lalu
induk
melakukan
ea6fdad88b

+ 6 - 6
Userland/Libraries/LibDebug/DebugInfo.cpp

@@ -187,7 +187,7 @@ static Optional<Dwarf::DIE> parse_variable_type_die(const Dwarf::DIE& variable_d
     if (!type_die_offset.has_value())
         return {};
 
-    VERIFY(type_die_offset.value().type == Dwarf::DIE::AttributeValue::Type::DieReference);
+    VERIFY(type_die_offset.value().type == Dwarf::AttributeValue::Type::DieReference);
 
     auto type_die = variable_die.get_die_at_offset(type_die_offset.value().data.as_u32);
     auto type_name = type_die.get_attribute(Dwarf::Attribute::Name);
@@ -212,11 +212,11 @@ static void parse_variable_location(const Dwarf::DIE& variable_die, DebugInfo::V
         return;
 
     switch (location_info.value().type) {
-    case Dwarf::DIE::AttributeValue::Type::UnsignedNumber:
+    case Dwarf::AttributeValue::Type::UnsignedNumber:
         variable_info.location_type = DebugInfo::VariableInfo::LocationType::Address;
         variable_info.location_data.address = location_info.value().data.as_u32;
         break;
-    case Dwarf::DIE::AttributeValue::Type::DwarfExpression: {
+    case Dwarf::AttributeValue::Type::DwarfExpression: {
         auto expression_bytes = ReadonlyBytes { location_info.value().data.as_raw_bytes.bytes, location_info.value().data.as_raw_bytes.length };
         auto value = Dwarf::Expression::evaluate(expression_bytes, regs);
 
@@ -253,13 +253,13 @@ OwnPtr<DebugInfo::VariableInfo> DebugInfo::create_variable_info(const Dwarf::DIE
         auto constant = variable_die.get_attribute(Dwarf::Attribute::ConstValue);
         VERIFY(constant.has_value());
         switch (constant.value().type) {
-        case Dwarf::DIE::AttributeValue::Type::UnsignedNumber:
+        case Dwarf::AttributeValue::Type::UnsignedNumber:
             variable_info->constant_data.as_u32 = constant.value().data.as_u32;
             break;
-        case Dwarf::DIE::AttributeValue::Type::SignedNumber:
+        case Dwarf::AttributeValue::Type::SignedNumber:
             variable_info->constant_data.as_i32 = constant.value().data.as_i32;
             break;
-        case Dwarf::DIE::AttributeValue::Type::String:
+        case Dwarf::AttributeValue::Type::String:
             variable_info->constant_data.as_string = constant.value().data.as_string;
             break;
         default:

+ 3 - 152
Userland/Libraries/LibDebug/Dwarf/DIE.cpp

@@ -33,162 +33,13 @@ DIE::DIE(const CompilationUnit& unit, u32 offset)
 
         // We iterate the attributes data only to calculate this DIE's size
         for (auto& attribute_spec : abbreviation_info.value().attribute_specifications) {
-            get_attribute_value(attribute_spec.form, stream);
+            m_compilation_unit.dwarf_info().get_attribute_value(attribute_spec.form, stream, &m_compilation_unit);
         }
     }
     m_size = stream.offset() - m_offset;
 }
 
-DIE::AttributeValue DIE::get_attribute_value(AttributeDataForm form,
-    InputMemoryStream& debug_info_stream) const
-{
-    AttributeValue value;
-
-    auto assign_raw_bytes_value = [&](size_t length) {
-        value.data.as_raw_bytes.length = length;
-        value.data.as_raw_bytes.bytes = reinterpret_cast<const u8*>(m_compilation_unit.dwarf_info().debug_info_data().data()
-            + debug_info_stream.offset());
-
-        debug_info_stream.discard_or_error(length);
-    };
-
-    switch (form) {
-    case AttributeDataForm::StringPointer: {
-        u32 offset;
-        debug_info_stream >> offset;
-        VERIFY(!debug_info_stream.has_any_error());
-        value.type = AttributeValue::Type::String;
-
-        auto strings_data = m_compilation_unit.dwarf_info().debug_strings_data();
-        value.data.as_string = reinterpret_cast<const char*>(strings_data.data() + offset);
-        break;
-    }
-    case AttributeDataForm::Data1: {
-        u8 data;
-        debug_info_stream >> data;
-        VERIFY(!debug_info_stream.has_any_error());
-        value.type = AttributeValue::Type::UnsignedNumber;
-        value.data.as_u32 = data;
-        break;
-    }
-    case AttributeDataForm::Data2: {
-        u16 data;
-        debug_info_stream >> data;
-        VERIFY(!debug_info_stream.has_any_error());
-        value.type = AttributeValue::Type::UnsignedNumber;
-        value.data.as_u32 = data;
-        break;
-    }
-    case AttributeDataForm::Addr: {
-        u32 address;
-        debug_info_stream >> address;
-        VERIFY(!debug_info_stream.has_any_error());
-        value.type = AttributeValue::Type::UnsignedNumber;
-        value.data.as_u32 = address;
-        break;
-    }
-    case AttributeDataForm::SData: {
-        ssize_t data;
-        debug_info_stream.read_LEB128_signed(data);
-        VERIFY(!debug_info_stream.has_any_error());
-        value.type = AttributeValue::Type::SignedNumber;
-        value.data.as_i32 = data;
-        break;
-    }
-    case AttributeDataForm::SecOffset: {
-        u32 data;
-        debug_info_stream >> data;
-        VERIFY(!debug_info_stream.has_any_error());
-        value.type = AttributeValue::Type::SecOffset;
-        value.data.as_u32 = data;
-        break;
-    }
-    case AttributeDataForm::Data4: {
-        u32 data;
-        debug_info_stream >> data;
-        VERIFY(!debug_info_stream.has_any_error());
-        value.type = AttributeValue::Type::UnsignedNumber;
-        value.data.as_u32 = data;
-        break;
-    }
-    case AttributeDataForm::Data8: {
-        u64 data;
-        debug_info_stream >> data;
-        VERIFY(!debug_info_stream.has_any_error());
-        value.type = AttributeValue::Type::LongUnsignedNumber;
-        value.data.as_u64 = data;
-        break;
-    }
-    case AttributeDataForm::Ref4: {
-        u32 data;
-        debug_info_stream >> data;
-        VERIFY(!debug_info_stream.has_any_error());
-        value.type = AttributeValue::Type::DieReference;
-        value.data.as_u32 = data + m_compilation_unit.offset();
-        break;
-    }
-    case AttributeDataForm::FlagPresent: {
-        value.type = AttributeValue::Type::Boolean;
-        value.data.as_bool = true;
-        break;
-    }
-    case AttributeDataForm::ExprLoc: {
-        size_t length;
-        debug_info_stream.read_LEB128_unsigned(length);
-        VERIFY(!debug_info_stream.has_any_error());
-        value.type = AttributeValue::Type::DwarfExpression;
-        assign_raw_bytes_value(length);
-        break;
-    }
-    case AttributeDataForm::String: {
-        String str;
-        u32 str_offset = debug_info_stream.offset();
-        debug_info_stream >> str;
-        VERIFY(!debug_info_stream.has_any_error());
-        value.type = AttributeValue::Type::String;
-        value.data.as_string = reinterpret_cast<const char*>(str_offset + m_compilation_unit.dwarf_info().debug_info_data().data());
-        break;
-    }
-    case AttributeDataForm::Block1: {
-        value.type = AttributeValue::Type::RawBytes;
-        u8 length;
-        debug_info_stream >> length;
-        VERIFY(!debug_info_stream.has_any_error());
-        assign_raw_bytes_value(length);
-        break;
-    }
-    case AttributeDataForm::Block2: {
-        value.type = AttributeValue::Type::RawBytes;
-        u16 length;
-        debug_info_stream >> length;
-        VERIFY(!debug_info_stream.has_any_error());
-        assign_raw_bytes_value(length);
-        break;
-    }
-    case AttributeDataForm::Block4: {
-        value.type = AttributeValue::Type::RawBytes;
-        u32 length;
-        debug_info_stream >> length;
-        VERIFY(!debug_info_stream.has_any_error());
-        assign_raw_bytes_value(length);
-        break;
-    }
-    case AttributeDataForm::Block: {
-        value.type = AttributeValue::Type::RawBytes;
-        size_t length;
-        debug_info_stream.read_LEB128_unsigned(length);
-        VERIFY(!debug_info_stream.has_any_error());
-        assign_raw_bytes_value(length);
-        break;
-    }
-    default:
-        dbgln("Unimplemented AttributeDataForm: {}", (u32)form);
-        VERIFY_NOT_REACHED();
-    }
-    return value;
-}
-
-Optional<DIE::AttributeValue> DIE::get_attribute(const Attribute& attribute) const
+Optional<AttributeValue> DIE::get_attribute(const Attribute& attribute) const
 {
     InputMemoryStream stream { m_compilation_unit.dwarf_info().debug_info_data() };
     stream.discard_or_error(m_data_offset);
@@ -197,7 +48,7 @@ Optional<DIE::AttributeValue> DIE::get_attribute(const Attribute& attribute) con
     VERIFY(abbreviation_info.has_value());
 
     for (const auto& attribute_spec : abbreviation_info.value().attribute_specifications) {
-        auto value = get_attribute_value(attribute_spec.form, stream);
+        auto value = m_compilation_unit.dwarf_info().get_attribute_value(attribute_spec.form, stream, &m_compilation_unit);
         if (attribute_spec.attribute == attribute) {
             return value;
         }

+ 1 - 29
Userland/Libraries/LibDebug/Dwarf/DIE.h

@@ -7,6 +7,7 @@
 #pragma once
 
 #include "CompilationUnit.h"
+#include "DwarfInfo.h"
 #include "DwarfTypes.h"
 #include <AK/Function.h>
 #include <AK/NonnullOwnPtr.h>
@@ -22,32 +23,6 @@ class DIE {
 public:
     DIE(const CompilationUnit&, u32 offset);
 
-    struct AttributeValue {
-        enum class Type : u8 {
-            UnsignedNumber,
-            SignedNumber,
-            LongUnsignedNumber,
-            String,
-            DieReference, // Reference to another DIE in the same compilation unit
-            Boolean,
-            DwarfExpression,
-            SecOffset,
-            RawBytes,
-        } type;
-
-        union {
-            u32 as_u32;
-            i32 as_i32;
-            u64 as_u64;
-            const char* as_string; // points to bytes in the memory mapped elf image
-            bool as_bool;
-            struct {
-                u32 length;
-                const u8* bytes; // points to bytes in the memory mapped elf image
-            } as_raw_bytes;
-        } data {};
-    };
-
     u32 offset() const { return m_offset; }
     u32 size() const { return m_size; }
     bool has_children() const { return m_has_children; }
@@ -62,9 +37,6 @@ public:
     DIE get_die_at_offset(u32 offset) const;
 
 private:
-    AttributeValue get_attribute_value(AttributeDataForm form,
-        InputMemoryStream& debug_info_stream) const;
-
     const CompilationUnit& m_compilation_unit;
     u32 m_offset { 0 };
     u32 m_data_offset { 0 };

+ 150 - 0
Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp

@@ -48,4 +48,154 @@ void DwarfInfo::populate_compilation_units()
     }
 }
 
+AttributeValue DwarfInfo::get_attribute_value(AttributeDataForm form,
+    InputMemoryStream& debug_info_stream, const CompilationUnit* unit) const
+{
+    AttributeValue value;
+
+    auto assign_raw_bytes_value = [&](size_t length) {
+        value.data.as_raw_bytes.length = length;
+        value.data.as_raw_bytes.bytes = reinterpret_cast<const u8*>(debug_info_data().data()
+            + debug_info_stream.offset());
+
+        debug_info_stream.discard_or_error(length);
+    };
+
+    switch (form) {
+    case AttributeDataForm::StringPointer: {
+        u32 offset;
+        debug_info_stream >> offset;
+        VERIFY(!debug_info_stream.has_any_error());
+        value.type = AttributeValue::Type::String;
+
+        auto strings_data = debug_strings_data();
+        value.data.as_string = reinterpret_cast<const char*>(strings_data.data() + offset);
+        break;
+    }
+    case AttributeDataForm::Data1: {
+        u8 data;
+        debug_info_stream >> data;
+        VERIFY(!debug_info_stream.has_any_error());
+        value.type = AttributeValue::Type::UnsignedNumber;
+        value.data.as_u32 = data;
+        break;
+    }
+    case AttributeDataForm::Data2: {
+        u16 data;
+        debug_info_stream >> data;
+        VERIFY(!debug_info_stream.has_any_error());
+        value.type = AttributeValue::Type::UnsignedNumber;
+        value.data.as_u32 = data;
+        break;
+    }
+    case AttributeDataForm::Addr: {
+        u32 address;
+        debug_info_stream >> address;
+        VERIFY(!debug_info_stream.has_any_error());
+        value.type = AttributeValue::Type::UnsignedNumber;
+        value.data.as_u32 = address;
+        break;
+    }
+    case AttributeDataForm::SData: {
+        ssize_t data;
+        debug_info_stream.read_LEB128_signed(data);
+        VERIFY(!debug_info_stream.has_any_error());
+        value.type = AttributeValue::Type::SignedNumber;
+        value.data.as_i32 = data;
+        break;
+    }
+    case AttributeDataForm::SecOffset: {
+        u32 data;
+        debug_info_stream >> data;
+        VERIFY(!debug_info_stream.has_any_error());
+        value.type = AttributeValue::Type::SecOffset;
+        value.data.as_u32 = data;
+        break;
+    }
+    case AttributeDataForm::Data4: {
+        u32 data;
+        debug_info_stream >> data;
+        VERIFY(!debug_info_stream.has_any_error());
+        value.type = AttributeValue::Type::UnsignedNumber;
+        value.data.as_u32 = data;
+        break;
+    }
+    case AttributeDataForm::Data8: {
+        u64 data;
+        debug_info_stream >> data;
+        VERIFY(!debug_info_stream.has_any_error());
+        value.type = AttributeValue::Type::LongUnsignedNumber;
+        value.data.as_u64 = data;
+        break;
+    }
+    case AttributeDataForm::Ref4: {
+        u32 data;
+        debug_info_stream >> data;
+        VERIFY(!debug_info_stream.has_any_error());
+        value.type = AttributeValue::Type::DieReference;
+        VERIFY(unit);
+        value.data.as_u32 = data + unit->offset();
+        break;
+    }
+    case AttributeDataForm::FlagPresent: {
+        value.type = AttributeValue::Type::Boolean;
+        value.data.as_bool = true;
+        break;
+    }
+    case AttributeDataForm::ExprLoc: {
+        size_t length;
+        debug_info_stream.read_LEB128_unsigned(length);
+        VERIFY(!debug_info_stream.has_any_error());
+        value.type = AttributeValue::Type::DwarfExpression;
+        assign_raw_bytes_value(length);
+        break;
+    }
+    case AttributeDataForm::String: {
+        String str;
+        u32 str_offset = debug_info_stream.offset();
+        debug_info_stream >> str;
+        VERIFY(!debug_info_stream.has_any_error());
+        value.type = AttributeValue::Type::String;
+        value.data.as_string = reinterpret_cast<const char*>(str_offset + debug_info_data().data());
+        break;
+    }
+    case AttributeDataForm::Block1: {
+        value.type = AttributeValue::Type::RawBytes;
+        u8 length;
+        debug_info_stream >> length;
+        VERIFY(!debug_info_stream.has_any_error());
+        assign_raw_bytes_value(length);
+        break;
+    }
+    case AttributeDataForm::Block2: {
+        value.type = AttributeValue::Type::RawBytes;
+        u16 length;
+        debug_info_stream >> length;
+        VERIFY(!debug_info_stream.has_any_error());
+        assign_raw_bytes_value(length);
+        break;
+    }
+    case AttributeDataForm::Block4: {
+        value.type = AttributeValue::Type::RawBytes;
+        u32 length;
+        debug_info_stream >> length;
+        VERIFY(!debug_info_stream.has_any_error());
+        assign_raw_bytes_value(length);
+        break;
+    }
+    case AttributeDataForm::Block: {
+        value.type = AttributeValue::Type::RawBytes;
+        size_t length;
+        debug_info_stream.read_LEB128_unsigned(length);
+        VERIFY(!debug_info_stream.has_any_error());
+        assign_raw_bytes_value(length);
+        break;
+    }
+    default:
+        dbgln("Unimplemented AttributeDataForm: {}", (u32)form);
+        VERIFY_NOT_REACHED();
+    }
+    return value;
+}
+
 }

+ 29 - 0
Userland/Libraries/LibDebug/Dwarf/DwarfInfo.h

@@ -16,6 +16,32 @@
 
 namespace Debug::Dwarf {
 
+struct AttributeValue {
+    enum class Type : u8 {
+        UnsignedNumber,
+        SignedNumber,
+        LongUnsignedNumber,
+        String,
+        DieReference, // Reference to another DIE in the same compilation unit
+        Boolean,
+        DwarfExpression,
+        SecOffset,
+        RawBytes,
+    } type;
+
+    union {
+        u32 as_u32;
+        i32 as_i32;
+        u64 as_u64;
+        const char* as_string; // points to bytes in the memory mapped elf image
+        bool as_bool;
+        struct {
+            u32 length;
+            const u8* bytes; // points to bytes in the memory mapped elf image
+        } as_raw_bytes;
+    } data {};
+};
+
 class DwarfInfo {
 public:
     explicit DwarfInfo(const ELF::Image&);
@@ -27,6 +53,9 @@ public:
     template<typename Callback>
     void for_each_compilation_unit(Callback) const;
 
+    AttributeValue get_attribute_value(AttributeDataForm form,
+        InputMemoryStream& debug_info_stream, const CompilationUnit* unit = nullptr) const;
+
 private:
     void populate_compilation_units();