浏览代码

LibDebug: Implement symbolication for x86_64

Gunnar Beutner 4 年之前
父节点
当前提交
2c41e89d08

+ 6 - 16
Userland/Libraries/LibCoreDump/Backtrace.cpp

@@ -35,10 +35,6 @@ ELFObjectInfo const* Backtrace::object_info_for_region(ELF::Core::MemoryRegionIn
         return nullptr;
 
     auto image = make<ELF::Image>(file_or_error.value()->bytes());
-#if !ARCH(I386)
-    // FIXME: Fix LibDebug
-    return nullptr;
-#endif
     auto info = make<ELFObjectInfo>(file_or_error.release_value(), make<Debug::DebugInfo>(move(image)));
     auto* info_ptr = info.ptr();
     m_debug_info_cache.set(path, move(info));
@@ -81,11 +77,11 @@ Backtrace::~Backtrace()
 {
 }
 
-void Backtrace::add_entry(const Reader& coredump, FlatPtr eip)
+void Backtrace::add_entry(const Reader& coredump, FlatPtr ip)
 {
-    auto* region = coredump.region_containing((FlatPtr)eip);
+    auto* region = coredump.region_containing((FlatPtr)ip);
     if (!region) {
-        m_entries.append({ eip, {}, {}, {} });
+        m_entries.append({ ip, {}, {}, {} });
         return;
     }
     auto object_name = region->object_name();
@@ -95,15 +91,9 @@ void Backtrace::add_entry(const Reader& coredump, FlatPtr eip)
     if (!object_info)
         return;
 
-#if ARCH(I386)
-    auto function_name = object_info->debug_info->elf().symbolicate(eip - region->region_start);
-    auto source_position = object_info->debug_info->get_source_position_with_inlines(eip - region->region_start);
-#else
-    // FIXME: Fix symbolication.
-    auto function_name = "";
-    Debug::DebugInfo::SourcePositionWithInlines source_position;
-#endif
-    m_entries.append({ eip, object_name, function_name, source_position });
+    auto function_name = object_info->debug_info->elf().symbolicate(ip - region->region_start);
+    auto source_position = object_info->debug_info->get_source_position_with_inlines(ip - region->region_start);
+    m_entries.append({ ip, object_name, function_name, source_position });
 }
 
 String Backtrace::Entry::to_string(bool color) const

+ 1 - 1
Userland/Libraries/LibCoreDump/Backtrace.h

@@ -42,7 +42,7 @@ public:
     const Vector<Entry> entries() const { return m_entries; }
 
 private:
-    void add_entry(const Reader&, FlatPtr eip);
+    void add_entry(const Reader&, FlatPtr ip);
     ELFObjectInfo const* object_info_for_region(ELF::Core::MemoryRegionInfo const&);
 
     ELF::Core::ThreadInfo m_thread_info;

+ 8 - 9
Userland/Libraries/LibDebug/DebugInfo.cpp

@@ -60,9 +60,9 @@ void DebugInfo::parse_scopes_impl(Dwarf::DIE const& die)
             dbgln_if(SPAM_DEBUG, "DWARF: Couldn't find attribute LowPc for scope");
             return;
         }
-        scope.address_low = child.get_attribute(Dwarf::Attribute::LowPc).value().data.as_u32;
+        scope.address_low = child.get_attribute(Dwarf::Attribute::LowPc).value().data.as_addr;
         // The attribute name HighPc is confusing. In this context, it seems to actually be a positive offset from LowPc
-        scope.address_high = scope.address_low + child.get_attribute(Dwarf::Attribute::HighPc).value().data.as_u32;
+        scope.address_high = scope.address_low + child.get_attribute(Dwarf::Attribute::HighPc).value().data.as_addr;
 
         child.for_each_child([&](Dwarf::DIE const& variable_entry) {
             if (!(variable_entry.tag() == Dwarf::EntryTag::Variable
@@ -78,7 +78,6 @@ void DebugInfo::parse_scopes_impl(Dwarf::DIE const& die)
 
 void DebugInfo::prepare_lines()
 {
-
     Vector<Dwarf::LineProgram::LineInfo> all_lines;
     m_dwarf_info.for_each_compilation_unit([&all_lines](Dwarf::CompilationUnit const& unit) {
         all_lines.extend(unit.line_program().lines());
@@ -115,7 +114,7 @@ void DebugInfo::prepare_lines()
     });
 }
 
-Optional<DebugInfo::SourcePosition> DebugInfo::get_source_position(u32 target_address) const
+Optional<DebugInfo::SourcePosition> DebugInfo::get_source_position(FlatPtr target_address) const
 {
     if (m_sorted_lines.is_empty())
         return {};
@@ -219,7 +218,7 @@ static void parse_variable_location(Dwarf::DIE const& variable_die, DebugInfo::V
     switch (location_info.value().type) {
     case Dwarf::AttributeValue::Type::UnsignedNumber:
         variable_info.location_type = DebugInfo::VariableInfo::LocationType::Address;
-        variable_info.location_data.address = location_info.value().data.as_u32;
+        variable_info.location_data.address = location_info.value().data.as_addr;
         break;
     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 };
@@ -228,7 +227,7 @@ static void parse_variable_location(Dwarf::DIE const& variable_die, DebugInfo::V
         if (value.type != Dwarf::Expression::Type::None) {
             VERIFY(value.type == Dwarf::Expression::Type::UnsignedInteger);
             variable_info.location_type = DebugInfo::VariableInfo::LocationType::Address;
-            variable_info.location_data.address = value.data.as_u32;
+            variable_info.location_data.address = value.data.as_addr;
         }
         break;
     }
@@ -349,7 +348,7 @@ bool DebugInfo::is_variable_tag_supported(Dwarf::EntryTag const& tag)
         || tag == Dwarf::EntryTag::ArrayType;
 }
 
-String DebugInfo::name_of_containing_function(u32 address) const
+String DebugInfo::name_of_containing_function(FlatPtr address) const
 {
     auto function = get_containing_function(address);
     if (!function.has_value())
@@ -357,7 +356,7 @@ String DebugInfo::name_of_containing_function(u32 address) const
     return function.value().name;
 }
 
-Optional<DebugInfo::VariablesScope> DebugInfo::get_containing_function(u32 address) const
+Optional<DebugInfo::VariablesScope> DebugInfo::get_containing_function(FlatPtr address) const
 {
     for (const auto& scope : m_scopes) {
         if (!scope.is_function || address < scope.address_low || address >= scope.address_high)
@@ -386,7 +385,7 @@ DebugInfo::SourcePosition DebugInfo::SourcePosition::from_line_info(Dwarf::LineP
     return { line.file, line.line, line.address };
 }
 
-DebugInfo::SourcePositionWithInlines DebugInfo::get_source_position_with_inlines(u32 address) const
+DebugInfo::SourcePositionWithInlines DebugInfo::get_source_position_with_inlines(FlatPtr address) const
 {
     // If the address is in an "inline chain", this is the inner-most inlined position.
     auto inner_source_position = get_source_position(address);

+ 9 - 9
Userland/Libraries/LibDebug/DebugInfo.h

@@ -31,7 +31,7 @@ public:
     struct SourcePosition {
         FlyString file_path;
         size_t line_number { 0 };
-        Optional<u32> address_of_first_statement;
+        Optional<FlatPtr> address_of_first_statement;
 
         SourcePosition()
             : SourcePosition(String::empty(), 0)
@@ -42,7 +42,7 @@ public:
             , line_number(line_number)
         {
         }
-        SourcePosition(String file_path, size_t line_number, u32 address_of_first_statement)
+        SourcePosition(String file_path, size_t line_number, FlatPtr address_of_first_statement)
             : file_path(file_path)
             , line_number(line_number)
             , address_of_first_statement(address_of_first_statement)
@@ -65,7 +65,7 @@ public:
         String type_name;
         LocationType location_type { LocationType::None };
         union {
-            u32 address;
+            FlatPtr address;
         } location_data { 0 };
 
         union {
@@ -86,20 +86,20 @@ public:
     struct VariablesScope {
         bool is_function { false };
         String name;
-        u32 address_low { 0 };
-        u32 address_high { 0 }; // Non-inclusive - the lowest address after address_low that's not in this scope
+        FlatPtr address_low { 0 };
+        FlatPtr address_high { 0 }; // Non-inclusive - the lowest address after address_low that's not in this scope
         Vector<Dwarf::DIE> dies_of_variables;
     };
 
     NonnullOwnPtrVector<VariableInfo> get_variables_in_current_scope(PtraceRegisters const&) const;
 
-    Optional<SourcePosition> get_source_position(u32 address) const;
+    Optional<SourcePosition> get_source_position(FlatPtr address) const;
 
     struct SourcePositionWithInlines {
         Optional<SourcePosition> source_position;
         Vector<SourcePosition> inline_chain;
     };
-    SourcePositionWithInlines get_source_position_with_inlines(u32 address) const;
+    SourcePositionWithInlines get_source_position_with_inlines(FlatPtr address) const;
 
     struct SourcePositionAndAddress {
         String file;
@@ -109,9 +109,9 @@ public:
 
     Optional<SourcePositionAndAddress> get_address_from_source_position(const String& file, size_t line) const;
 
-    String name_of_containing_function(u32 address) const;
+    String name_of_containing_function(FlatPtr address) const;
     Vector<SourcePosition> source_lines_in_scope(const VariablesScope&) const;
-    Optional<VariablesScope> get_containing_function(u32 address) const;
+    Optional<VariablesScope> get_containing_function(FlatPtr address) const;
 
 private:
     void prepare_variable_scopes();

+ 1 - 0
Userland/Libraries/LibDebug/Dwarf/AttributeValue.h

@@ -25,6 +25,7 @@ struct AttributeValue {
     } type;
 
     union {
+        FlatPtr as_addr;
         u32 as_u32;
         i32 as_i32;
         u64 as_u64;

+ 4 - 5
Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp

@@ -47,7 +47,7 @@ void DwarfInfo::populate_compilation_units()
 
         debug_info_stream >> compilation_unit_header;
         VERIFY(compilation_unit_header.common.version <= 5);
-        VERIFY(compilation_unit_header.address_size() == sizeof(u32));
+        VERIFY(compilation_unit_header.address_size() == sizeof(FlatPtr));
 
         u32 length_after_header = compilation_unit_header.length() - (compilation_unit_header.header_size() - offsetof(CompilationUnitHeader, common.version));
 
@@ -102,11 +102,11 @@ AttributeValue DwarfInfo::get_attribute_value(AttributeDataForm form, ssize_t im
         break;
     }
     case AttributeDataForm::Addr: {
-        u32 address;
+        FlatPtr address;
         debug_info_stream >> address;
         VERIFY(!debug_info_stream.has_any_error());
         value.type = AttributeValue::Type::UnsignedNumber;
-        value.data.as_u32 = address;
+        value.data.as_addr = address;
         break;
     }
     case AttributeDataForm::SData: {
@@ -250,7 +250,6 @@ void DwarfInfo::build_cached_dies() const
         if (!start.has_value() || !end.has_value())
             return {};
 
-        VERIFY(sizeof(FlatPtr) == sizeof(u32));
         VERIFY(start->type == Dwarf::AttributeValue::Type::UnsignedNumber);
 
         // DW_AT_high_pc attribute can have different meanings depending on the attribute form.
@@ -258,7 +257,7 @@ void DwarfInfo::build_cached_dies() const
 
         uint32_t range_end = 0;
         if (end->form == Dwarf::AttributeDataForm::Addr)
-            range_end = end->data.as_u32;
+            range_end = end->data.as_addr;
         else
             range_end = start->data.as_u32 + end->data.as_u32;
 

+ 1 - 0
Userland/Libraries/LibDebug/Dwarf/Expression.h

@@ -22,6 +22,7 @@ enum class Type {
 struct Value {
     Type type;
     union {
+        FlatPtr as_addr;
         u32 as_u32;
     } data { 0 };
 };

+ 1 - 1
Userland/Libraries/LibDebug/Dwarf/LineProgram.cpp

@@ -174,7 +174,7 @@ void LineProgram::handle_extended_opcode()
         break;
     }
     default:
-        dbgln_if(DWARF_DEBUG, "offset: {:p}", m_stream.offset());
+        dbgln("Encountered unknown sub opcode {} at stream offset {:p}", sub_opcode, m_stream.offset());
         VERIFY_NOT_REACHED();
     }
 }

+ 2 - 2
Userland/Libraries/LibDebug/Dwarf/LineProgram.h

@@ -109,7 +109,7 @@ public:
     explicit LineProgram(DwarfInfo& dwarf_info, InputMemoryStream& stream);
 
     struct LineInfo {
-        u32 address { 0 };
+        FlatPtr address { 0 };
         FlyString file;
         size_t line { 0 };
     };
@@ -176,7 +176,7 @@ private:
     Vector<FileEntry> m_source_files;
 
     // The registers of the "line program" virtual machine
-    u32 m_address { 0 };
+    FlatPtr m_address { 0 };
     size_t m_line { 0 };
     size_t m_file_index { 0 };
     bool m_is_statement { false };