mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Kernel/IPC: Add tests for HLERequestContext buffer translation
This commit is contained in:
		
							parent
							
								
									0dfafdbe59
								
							
						
					
					
						commit
						60a882cd50
					
				
					 2 changed files with 196 additions and 2 deletions
				
			
		|  | @ -1,8 +1,9 @@ | |||
| set(SRCS | ||||
|             glad.cpp | ||||
|             tests.cpp | ||||
|             common/param_package.cpp | ||||
|             core/file_sys/path_parser.cpp | ||||
|             core/hle/kernel/hle_ipc.cpp | ||||
|             glad.cpp | ||||
|             tests.cpp | ||||
|             ) | ||||
| 
 | ||||
| set(HEADERS | ||||
|  |  | |||
							
								
								
									
										193
									
								
								src/tests/core/hle/kernel/hle_ipc.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								src/tests/core/hle/kernel/hle_ipc.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,193 @@ | |||
| // Copyright 2017 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <catch.hpp> | ||||
| #include "core/hle/ipc.h" | ||||
| #include "core/hle/kernel/client_port.h" | ||||
| #include "core/hle/kernel/client_session.h" | ||||
| #include "core/hle/kernel/event.h" | ||||
| #include "core/hle/kernel/handle_table.h" | ||||
| #include "core/hle/kernel/hle_ipc.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/kernel/server_session.h" | ||||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| static SharedPtr<Object> MakeObject() { | ||||
|     return Event::Create(ResetType::OneShot); | ||||
| } | ||||
| 
 | ||||
| TEST_CASE("HLERequestContext::PopoulateFromIncomingCommandBuffer", "[core][kernel]") { | ||||
|     auto session = std::get<SharedPtr<ServerSession>>(ServerSession::CreateSessionPair()); | ||||
|     HLERequestContext context(std::move(session)); | ||||
| 
 | ||||
|     auto process = Process::Create(CodeSet::Create("", 0)); | ||||
|     HandleTable handle_table; | ||||
| 
 | ||||
|     SECTION("works with empty cmdbuf") { | ||||
|         const u32_le input[]{ | ||||
|             IPC::MakeHeader(0x1234, 0, 0), | ||||
|         }; | ||||
| 
 | ||||
|         context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); | ||||
| 
 | ||||
|         REQUIRE(context.CommandBuffer()[0] == 0x12340000); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("translates regular params") { | ||||
|         const u32_le input[]{ | ||||
|             IPC::MakeHeader(0, 3, 0), 0x12345678, 0x21122112, 0xAABBCCDD, | ||||
|         }; | ||||
| 
 | ||||
|         context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); | ||||
| 
 | ||||
|         auto* output = context.CommandBuffer(); | ||||
|         REQUIRE(output[1] == 0x12345678); | ||||
|         REQUIRE(output[2] == 0x21122112); | ||||
|         REQUIRE(output[3] == 0xAABBCCDD); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("translates move handles") { | ||||
|         auto a = MakeObject(); | ||||
|         Handle a_handle = handle_table.Create(a).Unwrap(); | ||||
|         const u32_le input[]{ | ||||
|             IPC::MakeHeader(0, 0, 2), IPC::MoveHandleDesc(1), a_handle, | ||||
|         }; | ||||
| 
 | ||||
|         context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); | ||||
| 
 | ||||
|         auto* output = context.CommandBuffer(); | ||||
|         REQUIRE(context.GetIncomingHandle(output[2]) == a); | ||||
|         REQUIRE(handle_table.GetGeneric(a_handle) == nullptr); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("translates copy handles") { | ||||
|         auto a = MakeObject(); | ||||
|         Handle a_handle = handle_table.Create(a).Unwrap(); | ||||
|         const u32_le input[]{ | ||||
|             IPC::MakeHeader(0, 0, 2), IPC::CopyHandleDesc(1), a_handle, | ||||
|         }; | ||||
| 
 | ||||
|         context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); | ||||
| 
 | ||||
|         auto* output = context.CommandBuffer(); | ||||
|         REQUIRE(context.GetIncomingHandle(output[2]) == a); | ||||
|         REQUIRE(handle_table.GetGeneric(a_handle) == a); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("translates multi-handle descriptors") { | ||||
|         auto a = MakeObject(); | ||||
|         auto b = MakeObject(); | ||||
|         auto c = MakeObject(); | ||||
|         const u32_le input[]{ | ||||
|             IPC::MakeHeader(0, 0, 5),        IPC::MoveHandleDesc(2), | ||||
|             handle_table.Create(a).Unwrap(), handle_table.Create(b).Unwrap(), | ||||
|             IPC::MoveHandleDesc(1),          handle_table.Create(c).Unwrap(), | ||||
|         }; | ||||
| 
 | ||||
|         context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); | ||||
| 
 | ||||
|         auto* output = context.CommandBuffer(); | ||||
|         REQUIRE(context.GetIncomingHandle(output[2]) == a); | ||||
|         REQUIRE(context.GetIncomingHandle(output[3]) == b); | ||||
|         REQUIRE(context.GetIncomingHandle(output[5]) == c); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("translates CallingPid descriptors") { | ||||
|         const u32_le input[]{ | ||||
|             IPC::MakeHeader(0, 0, 2), IPC::CallingPidDesc(), 0x98989898, | ||||
|         }; | ||||
| 
 | ||||
|         context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); | ||||
| 
 | ||||
|         REQUIRE(context.CommandBuffer()[2] == process->process_id); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("translates mixed params") { | ||||
|         auto a = MakeObject(); | ||||
|         const u32_le input[]{ | ||||
|             IPC::MakeHeader(0, 2, 4), | ||||
|             0x12345678, | ||||
|             0xABCDEF00, | ||||
|             IPC::MoveHandleDesc(1), | ||||
|             handle_table.Create(a).Unwrap(), | ||||
|             IPC::CallingPidDesc(), | ||||
|             0, | ||||
|         }; | ||||
| 
 | ||||
|         context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); | ||||
| 
 | ||||
|         auto* output = context.CommandBuffer(); | ||||
|         REQUIRE(output[1] == 0x12345678); | ||||
|         REQUIRE(output[2] == 0xABCDEF00); | ||||
|         REQUIRE(context.GetIncomingHandle(output[4]) == a); | ||||
|         REQUIRE(output[6] == process->process_id); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { | ||||
|     auto session = std::get<SharedPtr<ServerSession>>(ServerSession::CreateSessionPair()); | ||||
|     HLERequestContext context(std::move(session)); | ||||
| 
 | ||||
|     auto process = Process::Create(CodeSet::Create("", 0)); | ||||
|     HandleTable handle_table; | ||||
|     auto* input = context.CommandBuffer(); | ||||
|     u32_le output[IPC::COMMAND_BUFFER_LENGTH]; | ||||
| 
 | ||||
|     SECTION("works with empty cmdbuf") { | ||||
|         input[0] = IPC::MakeHeader(0x1234, 0, 0); | ||||
| 
 | ||||
|         context.WriteToOutgoingCommandBuffer(output, *process, handle_table); | ||||
| 
 | ||||
|         REQUIRE(output[0] == 0x12340000); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("translates regular params") { | ||||
|         input[0] = IPC::MakeHeader(0, 3, 0); | ||||
|         input[1] = 0x12345678; | ||||
|         input[2] = 0x21122112; | ||||
|         input[3] = 0xAABBCCDD; | ||||
| 
 | ||||
|         context.WriteToOutgoingCommandBuffer(output, *process, handle_table); | ||||
| 
 | ||||
|         REQUIRE(output[1] == 0x12345678); | ||||
|         REQUIRE(output[2] == 0x21122112); | ||||
|         REQUIRE(output[3] == 0xAABBCCDD); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("translates move/copy handles") { | ||||
|         auto a = MakeObject(); | ||||
|         auto b = MakeObject(); | ||||
|         input[0] = IPC::MakeHeader(0, 0, 4); | ||||
|         input[1] = IPC::MoveHandleDesc(1); | ||||
|         input[2] = context.AddOutgoingHandle(a); | ||||
|         input[3] = IPC::CopyHandleDesc(1); | ||||
|         input[4] = context.AddOutgoingHandle(b); | ||||
| 
 | ||||
|         context.WriteToOutgoingCommandBuffer(output, *process, handle_table); | ||||
| 
 | ||||
|         REQUIRE(handle_table.GetGeneric(output[2]) == a); | ||||
|         REQUIRE(handle_table.GetGeneric(output[4]) == b); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("translates multi-handle descriptors") { | ||||
|         auto a = MakeObject(); | ||||
|         auto b = MakeObject(); | ||||
|         auto c = MakeObject(); | ||||
|         input[0] = IPC::MakeHeader(0, 0, 5); | ||||
|         input[1] = IPC::MoveHandleDesc(2); | ||||
|         input[2] = context.AddOutgoingHandle(a); | ||||
|         input[3] = context.AddOutgoingHandle(b); | ||||
|         input[4] = IPC::CopyHandleDesc(1); | ||||
|         input[5] = context.AddOutgoingHandle(c); | ||||
| 
 | ||||
|         context.WriteToOutgoingCommandBuffer(output, *process, handle_table); | ||||
| 
 | ||||
|         REQUIRE(handle_table.GetGeneric(output[2]) == a); | ||||
|         REQUIRE(handle_table.GetGeneric(output[3]) == b); | ||||
|         REQUIRE(handle_table.GetGeneric(output[5]) == c); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| } // namespace Kernel
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue