mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	kernel: Add LLE request/reply recording
The 'translate' function is a great place to put this in IMO as it is possible to get both untranslated and translated cmdbufs. However a kernel reference has to be passed here, but it is not too hard fortunately.
This commit is contained in:
		
							parent
							
								
									cb0bd6530c
								
							
						
					
					
						commit
						a27dfc269a
					
				
					 3 changed files with 38 additions and 14 deletions
				
			
		|  | @ -8,6 +8,7 @@ | |||
| #include "core/hle/ipc.h" | ||||
| #include "core/hle/kernel/handle_table.h" | ||||
| #include "core/hle/kernel/ipc.h" | ||||
| #include "core/hle/kernel/ipc_debugger/recorder.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/memory.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
|  | @ -16,7 +17,8 @@ | |||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| ResultCode TranslateCommandBuffer(Memory::MemorySystem& memory, std::shared_ptr<Thread> src_thread, | ||||
| ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySystem& memory, | ||||
|                                   std::shared_ptr<Thread> src_thread, | ||||
|                                   std::shared_ptr<Thread> dst_thread, VAddr src_address, | ||||
|                                   VAddr dst_address, | ||||
|                                   std::vector<MappedBufferContext>& mapped_buffer_context, | ||||
|  | @ -37,6 +39,13 @@ ResultCode TranslateCommandBuffer(Memory::MemorySystem& memory, std::shared_ptr< | |||
|     std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; | ||||
|     memory.ReadBlock(*src_process, src_address, cmd_buf.data(), command_size * sizeof(u32)); | ||||
| 
 | ||||
|     const bool should_record = kernel.GetIPCRecorder().IsEnabled(); | ||||
| 
 | ||||
|     std::vector<u32> untranslated_cmdbuf; | ||||
|     if (should_record) { | ||||
|         untranslated_cmdbuf = std::vector<u32>{cmd_buf.begin(), cmd_buf.begin() + command_size}; | ||||
|     } | ||||
| 
 | ||||
|     std::size_t i = untranslated_size; | ||||
|     while (i < command_size) { | ||||
|         u32 descriptor = cmd_buf[i]; | ||||
|  | @ -218,6 +227,17 @@ ResultCode TranslateCommandBuffer(Memory::MemorySystem& memory, std::shared_ptr< | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (should_record) { | ||||
|         std::vector<u32> translated_cmdbuf{cmd_buf.begin(), cmd_buf.begin() + command_size}; | ||||
|         if (reply) { | ||||
|             kernel.GetIPCRecorder().SetReplyInfo(dst_thread, std::move(untranslated_cmdbuf), | ||||
|                                                  std::move(translated_cmdbuf)); | ||||
|         } else { | ||||
|             kernel.GetIPCRecorder().SetRequestInfo(src_thread, std::move(untranslated_cmdbuf), | ||||
|                                                    std::move(translated_cmdbuf), dst_thread); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     memory.WriteBlock(*dst_process, dst_address, cmd_buf.data(), command_size * sizeof(u32)); | ||||
| 
 | ||||
|     return RESULT_SUCCESS; | ||||
|  |  | |||
|  | @ -16,6 +16,8 @@ class MemorySystem; | |||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| class KernelSystem; | ||||
| 
 | ||||
| struct MappedBufferContext { | ||||
|     IPC::MappedBufferPermissions permissions; | ||||
|     u32 size; | ||||
|  | @ -27,7 +29,8 @@ struct MappedBufferContext { | |||
| }; | ||||
| 
 | ||||
| /// Performs IPC command buffer translation from one process to another.
 | ||||
| ResultCode TranslateCommandBuffer(Memory::MemorySystem& memory, std::shared_ptr<Thread> src_thread, | ||||
| ResultCode TranslateCommandBuffer(KernelSystem& system, Memory::MemorySystem& memory, | ||||
|                                   std::shared_ptr<Thread> src_thread, | ||||
|                                   std::shared_ptr<Thread> dst_thread, VAddr src_address, | ||||
|                                   VAddr dst_address, | ||||
|                                   std::vector<MappedBufferContext>& mapped_buffer_context, | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ | |||
| #include "core/hle/kernel/event.h" | ||||
| #include "core/hle/kernel/handle_table.h" | ||||
| #include "core/hle/kernel/ipc.h" | ||||
| #include "core/hle/kernel/ipc_debugger/recorder.h" | ||||
| #include "core/hle/kernel/memory.h" | ||||
| #include "core/hle/kernel/mutex.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
|  | @ -599,7 +600,7 @@ ResultCode SVC::WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle | |||
|     } | ||||
| } | ||||
| 
 | ||||
| static ResultCode ReceiveIPCRequest(Memory::MemorySystem& memory, | ||||
| static ResultCode ReceiveIPCRequest(Kernel::KernelSystem& kernel, Memory::MemorySystem& memory, | ||||
|                                     std::shared_ptr<ServerSession> server_session, | ||||
|                                     std::shared_ptr<Thread> thread) { | ||||
|     if (server_session->parent->client == nullptr) { | ||||
|  | @ -609,9 +610,9 @@ static ResultCode ReceiveIPCRequest(Memory::MemorySystem& memory, | |||
|     VAddr target_address = thread->GetCommandBufferAddress(); | ||||
|     VAddr source_address = server_session->currently_handling->GetCommandBufferAddress(); | ||||
| 
 | ||||
|     ResultCode translation_result = | ||||
|         TranslateCommandBuffer(memory, server_session->currently_handling, thread, source_address, | ||||
|                                target_address, server_session->mapped_buffer_context, false); | ||||
|     ResultCode translation_result = TranslateCommandBuffer( | ||||
|         kernel, memory, server_session->currently_handling, thread, source_address, target_address, | ||||
|         server_session->mapped_buffer_context, false); | ||||
| 
 | ||||
|     // If a translation error occurred, immediately resume the client thread.
 | ||||
|     if (translation_result.IsError()) { | ||||
|  | @ -676,9 +677,9 @@ ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_co | |||
|         VAddr source_address = thread->GetCommandBufferAddress(); | ||||
|         VAddr target_address = request_thread->GetCommandBufferAddress(); | ||||
| 
 | ||||
|         ResultCode translation_result = | ||||
|             TranslateCommandBuffer(memory, SharedFrom(thread), request_thread, source_address, | ||||
|                                    target_address, session->mapped_buffer_context, true); | ||||
|         ResultCode translation_result = TranslateCommandBuffer( | ||||
|             kernel, memory, SharedFrom(thread), request_thread, source_address, target_address, | ||||
|             session->mapped_buffer_context, true); | ||||
| 
 | ||||
|         // Note: The real kernel seems to always panic if the Server->Client buffer translation
 | ||||
|         // fails for whatever reason.
 | ||||
|  | @ -713,7 +714,7 @@ ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_co | |||
|             return RESULT_SUCCESS; | ||||
| 
 | ||||
|         auto server_session = static_cast<ServerSession*>(object); | ||||
|         return ReceiveIPCRequest(memory, SharedFrom(server_session), SharedFrom(thread)); | ||||
|         return ReceiveIPCRequest(kernel, memory, SharedFrom(server_session), SharedFrom(thread)); | ||||
|     } | ||||
| 
 | ||||
|     // No objects were ready to be acquired, prepare to suspend the thread.
 | ||||
|  | @ -729,9 +730,9 @@ ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_co | |||
| 
 | ||||
|     thread->wait_objects = std::move(objects); | ||||
| 
 | ||||
|     thread->wakeup_callback = [& memory = this->memory](ThreadWakeupReason reason, | ||||
|                                                         std::shared_ptr<Thread> thread, | ||||
|                                                         std::shared_ptr<WaitObject> object) { | ||||
|     thread->wakeup_callback = [& kernel = this->kernel, &memory = this->memory]( | ||||
|                                   ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | ||||
|                                   std::shared_ptr<WaitObject> object) { | ||||
|         ASSERT(thread->status == ThreadStatus::WaitSynchAny); | ||||
|         ASSERT(reason == ThreadWakeupReason::Signal); | ||||
| 
 | ||||
|  | @ -739,7 +740,7 @@ ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_co | |||
| 
 | ||||
|         if (object->GetHandleType() == HandleType::ServerSession) { | ||||
|             auto server_session = DynamicObjectCast<ServerSession>(object); | ||||
|             result = ReceiveIPCRequest(memory, server_session, thread); | ||||
|             result = ReceiveIPCRequest(kernel, memory, server_session, thread); | ||||
|         } | ||||
| 
 | ||||
|         thread->SetWaitSynchronizationResult(result); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue