mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 08:17:45 +00:00
Profiler: Load the actual kernel binary for disassembly
/boot/Kernel.debug only contains the symbol table and DWARF debug information, and has its `.text` and other PT_LOAD segments stripped out. When we try to parse its data as instructions, we get a crash from within LibX86. We now load the actual /boot/Kernel binary when we want to disassemble kernel functions.
This commit is contained in:
parent
80b660132c
commit
8e1f882ac9
1 changed files with 27 additions and 7 deletions
|
@ -34,17 +34,36 @@ static Color color_for_percent(int percent)
|
||||||
return heat_gradient().get_pixel(percent, 0);
|
return heat_gradient().get_pixel(percent, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Optional<MappedObject> s_kernel_binary;
|
||||||
|
|
||||||
|
static ELF::Image* try_load_kernel_binary()
|
||||||
|
{
|
||||||
|
if (s_kernel_binary.has_value())
|
||||||
|
return &s_kernel_binary->elf;
|
||||||
|
auto kernel_binary_or_error = MappedFile::map("/boot/Kernel");
|
||||||
|
if (!kernel_binary_or_error.is_error()) {
|
||||||
|
auto kernel_binary = kernel_binary_or_error.release_value();
|
||||||
|
s_kernel_binary = { { kernel_binary, ELF::Image(kernel_binary->bytes()) } };
|
||||||
|
return &s_kernel_binary->elf;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node)
|
DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node)
|
||||||
: m_profile(profile)
|
: m_profile(profile)
|
||||||
, m_node(node)
|
, m_node(node)
|
||||||
{
|
{
|
||||||
const ELF::Image* elf;
|
|
||||||
FlatPtr base_address = 0;
|
FlatPtr base_address = 0;
|
||||||
|
OwnPtr<Debug::DebugInfo> debug_info;
|
||||||
|
const ELF::Image* elf;
|
||||||
if (auto maybe_kernel_base = Symbolication::kernel_base(); maybe_kernel_base.has_value() && m_node.address() >= *maybe_kernel_base) {
|
if (auto maybe_kernel_base = Symbolication::kernel_base(); maybe_kernel_base.has_value() && m_node.address() >= *maybe_kernel_base) {
|
||||||
if (!g_kernel_debuginfo_object.has_value())
|
if (!g_kernel_debuginfo_object.has_value())
|
||||||
return;
|
return;
|
||||||
elf = &g_kernel_debuginfo_object->elf;
|
base_address = maybe_kernel_base.release_value();
|
||||||
base_address = maybe_kernel_base.value();
|
elf = try_load_kernel_binary();
|
||||||
|
if (elf == nullptr)
|
||||||
|
return;
|
||||||
|
debug_info = make<Debug::DebugInfo>(g_kernel_debuginfo_object->elf, String::empty(), base_address);
|
||||||
} else {
|
} else {
|
||||||
auto& process = node.process();
|
auto& process = node.process();
|
||||||
auto library_data = process.library_metadata.library_containing(node.address());
|
auto library_data = process.library_metadata.library_containing(node.address());
|
||||||
|
@ -52,16 +71,17 @@ DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node)
|
||||||
dbgln("no library data for address {:p}", node.address());
|
dbgln("no library data for address {:p}", node.address());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
elf = &library_data->object->elf;
|
|
||||||
base_address = library_data->base;
|
base_address = library_data->base;
|
||||||
|
elf = &library_data->object->elf;
|
||||||
|
debug_info = make<Debug::DebugInfo>(library_data->object->elf, String::empty(), base_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
VERIFY(elf != nullptr);
|
VERIFY(elf != nullptr);
|
||||||
|
VERIFY(debug_info != nullptr);
|
||||||
|
|
||||||
FlatPtr function_address = node.address() - base_address;
|
FlatPtr function_address = node.address() - base_address;
|
||||||
auto is_function_address = false;
|
auto is_function_address = false;
|
||||||
Debug::DebugInfo debug_info { *elf, {}, base_address };
|
auto function = debug_info->get_containing_function(function_address);
|
||||||
auto function = debug_info.get_containing_function(function_address);
|
|
||||||
if (function.has_value()) {
|
if (function.has_value()) {
|
||||||
if (function_address == function->address_low)
|
if (function_address == function->address_low)
|
||||||
is_function_address = true;
|
is_function_address = true;
|
||||||
|
@ -107,7 +127,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);
|
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;
|
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, debug_info.get_source_position_with_inlines(address_in_profiled_program - base_address) });
|
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();
|
offset_into_symbol += insn.value().length();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue