diff --git a/Userland/DevTools/Profiler/DisassemblyModel.cpp b/Userland/DevTools/Profiler/DisassemblyModel.cpp index cabcd56e1f..85af3dffa8 100644 --- a/Userland/DevTools/Profiler/DisassemblyModel.cpp +++ b/Userland/DevTools/Profiler/DisassemblyModel.cpp @@ -38,19 +38,12 @@ DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node) : m_profile(profile) , m_node(node) { - OwnPtr kernel_elf; const ELF::Image* elf; FlatPtr base_address = 0; - auto maybe_kernel_base = Symbolication::kernel_base(); - if (maybe_kernel_base.has_value() && m_node.address() >= maybe_kernel_base.value()) { - if (!m_kernel_file) { - auto file_or_error = MappedFile::map("/boot/Kernel.debug"); - if (file_or_error.is_error()) - return; - m_kernel_file = file_or_error.release_value(); - } - kernel_elf = make((const u8*)m_kernel_file->data(), m_kernel_file->size()); - elf = kernel_elf.ptr(); + 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()) + return; + elf = &g_kernel_debuginfo_object->elf; base_address = maybe_kernel_base.value(); } else { auto& process = node.process(); diff --git a/Userland/DevTools/Profiler/DisassemblyModel.h b/Userland/DevTools/Profiler/DisassemblyModel.h index 1cb07448b8..2889435d7f 100644 --- a/Userland/DevTools/Profiler/DisassemblyModel.h +++ b/Userland/DevTools/Profiler/DisassemblyModel.h @@ -54,7 +54,6 @@ private: Profile& m_profile; ProfileNode& m_node; - RefPtr m_kernel_file; Vector m_instructions; }; diff --git a/Userland/DevTools/Profiler/Profile.cpp b/Userland/DevTools/Profiler/Profile.cpp index 432bcf17ba..e40785e2a4 100644 --- a/Userland/DevTools/Profiler/Profile.cpp +++ b/Userland/DevTools/Profiler/Profile.cpp @@ -211,6 +211,8 @@ void Profile::rebuild_tree() m_model->invalidate(); } +Optional g_kernel_debuginfo_object; + Result, String> Profile::load_from_perfcore_file(const StringView& path) { auto file = Core::File::construct(path); @@ -223,10 +225,14 @@ Result, String> Profile::load_from_perfcore_file(const St auto& object = json.value().as_object(); - auto file_or_error = MappedFile::map("/boot/Kernel.debug"); - OwnPtr kernel_elf; - if (!file_or_error.is_error()) - kernel_elf = make(file_or_error.value()->bytes()); + if (!g_kernel_debuginfo_object.has_value()) { + auto debuginfo_file_or_error = MappedFile::map("/boot/Kernel.debug"); + if (!debuginfo_file_or_error.is_error()) { + auto debuginfo_file = debuginfo_file_or_error.release_value(); + auto debuginfo_image = ELF::Image(debuginfo_file->bytes()); + g_kernel_debuginfo_object = { { debuginfo_file, move(debuginfo_image) } }; + } + } auto strings_value = object.get_ptr("strings"sv); if (!strings_value || !strings_value->is_array()) @@ -380,8 +386,8 @@ Result, String> Profile::load_from_perfcore_file(const St String symbol; if (maybe_kernel_base.has_value() && ptr >= maybe_kernel_base.value()) { - if (kernel_elf) { - symbol = kernel_elf->symbolicate(ptr - maybe_kernel_base.value(), &offset); + if (g_kernel_debuginfo_object.has_value()) { + symbol = g_kernel_debuginfo_object->elf.symbolicate(ptr - maybe_kernel_base.value(), &offset); } else { symbol = String::formatted("?? <{:p}>", ptr); } diff --git a/Userland/DevTools/Profiler/Profile.h b/Userland/DevTools/Profiler/Profile.h index 4bd65b4f5c..4549c90288 100644 --- a/Userland/DevTools/Profiler/Profile.h +++ b/Userland/DevTools/Profiler/Profile.h @@ -28,6 +28,8 @@ namespace Profiler { +extern Optional g_kernel_debuginfo_object; + class ProfileNode : public RefCounted { public: static NonnullRefPtr create(Process const& process, FlyString object_name, String symbol, FlatPtr address, u32 offset, u64 timestamp, pid_t pid)