summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorGunnar Beutner <gbeutner@serenityos.org>2021-07-13 18:16:36 +0200
committerAndreas Kling <kling@serenityos.org>2021-07-13 23:19:33 +0200
commit2c41e89d08ad6b41eb960e53b06dafe1f5d905cc (patch)
tree2161f5df61cb1741edc180d2f15dad99fdb4f4db /Userland
parent567fa4b2f0ce6660fc0aa6a0f61a59a6fb094a5c (diff)
downloadserenity-2c41e89d08ad6b41eb960e53b06dafe1f5d905cc.zip
LibDebug: Implement symbolication for x86_64
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibCoreDump/Backtrace.cpp22
-rw-r--r--Userland/Libraries/LibCoreDump/Backtrace.h2
-rw-r--r--Userland/Libraries/LibDebug/DebugInfo.cpp17
-rw-r--r--Userland/Libraries/LibDebug/DebugInfo.h18
-rw-r--r--Userland/Libraries/LibDebug/Dwarf/AttributeValue.h1
-rw-r--r--Userland/Libraries/LibDebug/Dwarf/DwarfInfo.cpp9
-rw-r--r--Userland/Libraries/LibDebug/Dwarf/Expression.h1
-rw-r--r--Userland/Libraries/LibDebug/Dwarf/LineProgram.cpp2
-rw-r--r--Userland/Libraries/LibDebug/Dwarf/LineProgram.h4
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 };