diff options
author | Gunnar Beutner <gbeutner@serenityos.org> | 2021-07-13 18:16:36 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-07-13 23:19:33 +0200 |
commit | 2c41e89d08ad6b41eb960e53b06dafe1f5d905cc (patch) | |
tree | 2161f5df61cb1741edc180d2f15dad99fdb4f4db /Userland | |
parent | 567fa4b2f0ce6660fc0aa6a0f61a59a6fb094a5c (diff) | |
download | serenity-2c41e89d08ad6b41eb960e53b06dafe1f5d905cc.zip |
LibDebug: Implement symbolication for x86_64
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibCoreDump/Backtrace.cpp | 22 | ||||
-rw-r--r-- | Userland/Libraries/LibCoreDump/Backtrace.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibDebug/DebugInfo.cpp | 17 | ||||
-rw-r--r-- | Userland/Libraries/LibDebug/DebugInfo.h | 18 | ||||
-rw-r--r-- | Userland/Libraries/LibDebug/Dwarf/AttributeValue.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp | 9 | ||||
-rw-r--r-- | Userland/Libraries/LibDebug/Dwarf/Expression.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibDebug/Dwarf/LineProgram.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibDebug/Dwarf/LineProgram.h | 4 |
9 files changed, 33 insertions, 43 deletions
diff --git a/Userland/Libraries/LibCoreDump/Backtrace.cpp b/Userland/Libraries/LibCoreDump/Backtrace.cpp index f13d415f94..9ce5c64695 100644 --- a/Userland/Libraries/LibCoreDump/Backtrace.cpp +++ b/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 diff --git a/Userland/Libraries/LibCoreDump/Backtrace.h b/Userland/Libraries/LibCoreDump/Backtrace.h index 769bddd47a..722b2d0a47 100644 --- a/Userland/Libraries/LibCoreDump/Backtrace.h +++ b/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; diff --git a/Userland/Libraries/LibDebug/DebugInfo.cpp b/Userland/Libraries/LibDebug/DebugInfo.cpp index e84bf569a7..3047bba9c9 100644 --- a/Userland/Libraries/LibDebug/DebugInfo.cpp +++ b/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); diff --git a/Userland/Libraries/LibDebug/DebugInfo.h b/Userland/Libraries/LibDebug/DebugInfo.h index d920a74851..c238ff63cf 100644 --- a/Userland/Libraries/LibDebug/DebugInfo.h +++ b/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(); diff --git a/Userland/Libraries/LibDebug/Dwarf/AttributeValue.h b/Userland/Libraries/LibDebug/Dwarf/AttributeValue.h index d2a5e045e0..258f60e55b 100644 --- a/Userland/Libraries/LibDebug/Dwarf/AttributeValue.h +++ b/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; diff --git a/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp b/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp index e912740bd7..a2364b3d7e 100644 --- a/Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp +++ b/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; diff --git a/Userland/Libraries/LibDebug/Dwarf/Expression.h b/Userland/Libraries/LibDebug/Dwarf/Expression.h index 0355a0a648..90f0737e8d 100644 --- a/Userland/Libraries/LibDebug/Dwarf/Expression.h +++ b/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 }; }; diff --git a/Userland/Libraries/LibDebug/Dwarf/LineProgram.cpp b/Userland/Libraries/LibDebug/Dwarf/LineProgram.cpp index e1d6da2406..86106dfb14 100644 --- a/Userland/Libraries/LibDebug/Dwarf/LineProgram.cpp +++ b/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(); } } diff --git a/Userland/Libraries/LibDebug/Dwarf/LineProgram.h b/Userland/Libraries/LibDebug/Dwarf/LineProgram.h index 8eecbff86a..d5fc9cacc2 100644 --- a/Userland/Libraries/LibDebug/Dwarf/LineProgram.h +++ b/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 }; |