From efd69e13158e10700925b203e0d054c2aee9118d Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Mon, 22 Jul 2019 20:25:43 +0800 Subject: [PATCH] kernel, service: Add HLE request/reply recording Pretty much the same as LLE requests, the 'translate' part is chosen. A function is added to the context class to record requests that involves unimplemented HLE functions. --- src/core/hle/kernel/hle_ipc.cpp | 33 ++++++++++++++++++++++++++++++++ src/core/hle/kernel/hle_ipc.h | 3 +++ src/core/hle/service/service.cpp | 1 + 3 files changed, 37 insertions(+) diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index cd2f9fc87..ab4ecfd05 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -10,6 +10,7 @@ #include "core/hle/kernel/event.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/hle_ipc.h" +#include "core/hle/kernel/ipc_debugger/recorder.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" @@ -107,6 +108,13 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr std::copy_n(src_cmdbuf, untranslated_size, cmd_buf.begin()); + const bool should_record = kernel.GetIPCRecorder().IsEnabled(); + + std::vector untranslated_cmdbuf; + if (should_record) { + untranslated_cmdbuf = std::vector{src_cmdbuf, src_cmdbuf + command_size}; + } + std::size_t i = untranslated_size; while (i < command_size) { u32 descriptor = cmd_buf[i] = src_cmdbuf[i]; @@ -160,6 +168,12 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr } } + if (should_record) { + std::vector translated_cmdbuf{cmd_buf.begin(), cmd_buf.begin() + command_size}; + kernel.GetIPCRecorder().SetRequestInfo(SharedFrom(thread), std::move(untranslated_cmdbuf), + std::move(translated_cmdbuf)); + } + return RESULT_SUCCESS; } @@ -173,6 +187,13 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, std::copy_n(cmd_buf.begin(), untranslated_size, dst_cmdbuf); + const bool should_record = kernel.GetIPCRecorder().IsEnabled(); + + std::vector untranslated_cmdbuf; + if (should_record) { + untranslated_cmdbuf = std::vector{cmd_buf.begin(), cmd_buf.begin() + command_size}; + } + std::size_t i = untranslated_size; while (i < command_size) { u32 descriptor = dst_cmdbuf[i] = cmd_buf[i]; @@ -225,6 +246,12 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, } } + if (should_record) { + std::vector translated_cmdbuf{dst_cmdbuf, dst_cmdbuf + command_size}; + kernel.GetIPCRecorder().SetReplyInfo(SharedFrom(thread), std::move(untranslated_cmdbuf), + std::move(translated_cmdbuf)); + } + return RESULT_SUCCESS; } @@ -233,6 +260,12 @@ MappedBuffer& HLERequestContext::GetMappedBuffer(u32 id_from_cmdbuf) { return request_mapped_buffers[id_from_cmdbuf]; } +void HLERequestContext::ReportUnimplemented() const { + if (kernel.GetIPCRecorder().IsEnabled()) { + kernel.GetIPCRecorder().SetHLEUnimplemented(SharedFrom(thread)); + } +} + MappedBuffer::MappedBuffer(Memory::MemorySystem& memory, const Process& process, u32 descriptor, VAddr address, u32 id) : memory(&memory), id(id), address(address), process(&process) { diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index f684985d0..26942fe6b 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -234,6 +234,9 @@ public: /// Writes data from this context back to the requesting process/thread. ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process) const; + /// Reports an unimplemented function. + void ReportUnimplemented() const; + private: KernelSystem& kernel; std::array cmd_buf; diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 057562488..0310d4ad9 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -171,6 +171,7 @@ void ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& context) auto itr = handlers.find(header_code); const FunctionInfoBase* info = itr == handlers.end() ? nullptr : &itr->second; if (info == nullptr || info->handler_callback == nullptr) { + context.ReportUnimplemented(); return ReportUnimplementedFunction(context.CommandBuffer(), info); }