diff --git a/Userland/DevTools/Profiler/DisassemblyModel.cpp b/Userland/DevTools/Profiler/DisassemblyModel.cpp index 6190fad7c4..d68f9ac002 100644 --- a/Userland/DevTools/Profiler/DisassemblyModel.cpp +++ b/Userland/DevTools/Profiler/DisassemblyModel.cpp @@ -7,6 +7,7 @@ #include "DisassemblyModel.h" #include "Profile.h" #include +#include #include #include #include @@ -75,6 +76,7 @@ DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node) X86::ELFSymbolProvider symbol_provider(*elf); X86::SimpleInstructionStream stream((const u8*)view.characters_without_null_termination(), view.length()); X86::Disassembler disassembler(stream); + Debug::DebugInfo debug_info { *elf, {}, base_address }; size_t offset_into_symbol = 0; for (;;) { @@ -89,7 +91,7 @@ DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node) u32 samples_at_this_instruction = m_node.events_per_address().get(address_in_profiled_program).value_or(0); float percent = ((float)samples_at_this_instruction / (float)m_node.event_count()) * 100.0f; - m_instructions.append({ insn.value(), disassembly, instruction_bytes, address_in_profiled_program, samples_at_this_instruction, percent }); + m_instructions.append({ insn.value(), disassembly, instruction_bytes, address_in_profiled_program, samples_at_this_instruction, percent, debug_info.get_source_position_with_inlines(address_in_profiled_program - base_address) }); offset_into_symbol += insn.value().length(); } @@ -115,6 +117,8 @@ String DisassemblyModel::column_name(int column) const return "Insn Bytes"; case Column::Disassembly: return "Disassembly"; + case Column::SourceLocation: + return "Source Location"; default: VERIFY_NOT_REACHED(); return {}; @@ -164,8 +168,10 @@ GUI::Variant DisassemblyModel::data(const GUI::ModelIndex& index, GUI::ModelRole return ((float)insn.event_count / (float)m_node.event_count()) * 100.0f; return insn.event_count; } + if (index.column() == Column::Address) return String::formatted("{:p}", insn.address); + if (index.column() == Column::InstructionBytes) { StringBuilder builder; for (auto ch : insn.bytes) { @@ -173,8 +179,29 @@ GUI::Variant DisassemblyModel::data(const GUI::ModelIndex& index, GUI::ModelRole } return builder.to_string(); } + if (index.column() == Column::Disassembly) return insn.disassembly; + + if (index.column() == Column::SourceLocation) { + StringBuilder builder; + auto first = true; + for (auto& entry : insn.source_position_with_inlines.inline_chain) { + if (first) + first = false; + else + builder.append(" => "); + builder.appendff("{}:{}", entry.file_path, entry.line_number); + } + if (insn.source_position_with_inlines.source_position.has_value()) { + if (!first) + builder.append(" => "); + auto& entry = insn.source_position_with_inlines.source_position.value(); + builder.appendff("{}:{}", entry.file_path, entry.line_number); + } + return builder.build(); + } + return {}; } return {}; diff --git a/Userland/DevTools/Profiler/DisassemblyModel.h b/Userland/DevTools/Profiler/DisassemblyModel.h index dd882c35e8..ef36446477 100644 --- a/Userland/DevTools/Profiler/DisassemblyModel.h +++ b/Userland/DevTools/Profiler/DisassemblyModel.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include @@ -21,6 +22,7 @@ struct InstructionData { FlatPtr address { 0 }; u32 event_count { 0 }; float percent { 0 }; + Debug::DebugInfo::SourcePositionWithInlines source_position_with_inlines; }; class DisassemblyModel final : public GUI::Model { @@ -35,6 +37,7 @@ public: SampleCount, InstructionBytes, Disassembly, + SourceLocation, __Count };