diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-08-08 04:32:28 +0430 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2021-08-10 05:13:44 +0430 |
commit | 2128ae4ab06c0e323f32c0d8490020732b89f3c0 (patch) | |
tree | 3d070ef84d29da7a1457f7e34a51019899aa226d /Userland | |
parent | 4bef63fa6adafdf6f0fd4ee159349565453afc7f (diff) | |
download | serenity-2128ae4ab06c0e323f32c0d8490020732b89f3c0.zip |
Profiler: Disassemble the containing function for non-function symbols
This can happen if the symbol is part of a switch-case, and not
a function, which would previously have made the disassembly view
appear empty.
Now we disassemble the containing function, starting at the given label
and continuing up until the last captured instruction.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/DevTools/Profiler/DisassemblyModel.cpp | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/Userland/DevTools/Profiler/DisassemblyModel.cpp b/Userland/DevTools/Profiler/DisassemblyModel.cpp index 39f1bbc648..88cd5d2fc1 100644 --- a/Userland/DevTools/Profiler/DisassemblyModel.cpp +++ b/Userland/DevTools/Profiler/DisassemblyModel.cpp @@ -64,26 +64,42 @@ DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node) VERIFY(elf != nullptr); - auto symbol = elf->find_symbol(node.address() - base_address); + FlatPtr function_address = node.address() - base_address; + Debug::DebugInfo debug_info { *elf, {}, base_address }; + auto function = debug_info.get_containing_function(function_address); + if (function.has_value()) + function_address = function->address_low; + else + dbgln("DisassemblyModel: Function containing {:p} ({}) not found", node.address() - base_address, node.symbol()); + + auto symbol = elf->find_symbol(function_address); if (!symbol.has_value()) { dbgln("DisassemblyModel: symbol not found"); return; } VERIFY(symbol.has_value()); - auto view = symbol.value().raw_data(); + auto symbol_offset_from_function_start = node.address() - base_address - symbol->value(); + auto view = symbol.value().raw_data().substring_view(symbol_offset_from_function_start); 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; + FlatPtr last_instruction_address = 0; + for (auto& event : node.events_per_address()) + last_instruction_address = max(event.key, last_instruction_address); + + auto last_instruction_offset = last_instruction_address - node.address(); for (;;) { + if (offset_into_symbol > last_instruction_offset) + break; + auto insn = disassembler.next(); if (!insn.has_value()) break; - FlatPtr address_in_profiled_program = base_address + symbol.value().value() + offset_into_symbol; + FlatPtr address_in_profiled_program = node.address() + offset_into_symbol; auto disassembly = insn.value().to_string(address_in_profiled_program, &symbol_provider); |