summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-08-08 04:32:28 +0430
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2021-08-10 05:13:44 +0430
commit2128ae4ab06c0e323f32c0d8490020732b89f3c0 (patch)
tree3d070ef84d29da7a1457f7e34a51019899aa226d /Userland
parent4bef63fa6adafdf6f0fd4ee159349565453afc7f (diff)
downloadserenity-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.cpp24
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);