mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	ldr_ro: use ServiceFramework's session slot for client slot
This commit is contained in:
		
							parent
							
								
									6e2a4ba665
								
							
						
					
					
						commit
						eeec04fcaa
					
				
					 2 changed files with 41 additions and 50 deletions
				
			
		|  | @ -63,15 +63,13 @@ void RO::Initialize(Kernel::HLERequestContext& ctx) { | |||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
| 
 | ||||
|     auto insert_result = slots.insert({process->process_id, {}}); | ||||
|     if (!insert_result.second) { | ||||
|     ClientSlot* slot = GetSessionData(ctx.Session()); | ||||
|     if (slot->loaded_crs != 0) { | ||||
|         LOG_ERROR(Service_LDR, "Already initialized"); | ||||
|         rb.Push(ERROR_ALREADY_INITIALIZED); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     auto& slot = insert_result.first->second; | ||||
| 
 | ||||
|     if (crs_size < CRO_HEADER_SIZE) { | ||||
|         LOG_ERROR(Service_LDR, "CRS is too small"); | ||||
|         rb.Push(ERROR_BUFFER_TOO_SMALL); | ||||
|  | @ -132,7 +130,7 @@ void RO::Initialize(Kernel::HLERequestContext& ctx) { | |||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         slot.memory_synchronizer.AddMemoryBlock(crs_address, crs_buffer_ptr, crs_size); | ||||
|         slot->memory_synchronizer.AddMemoryBlock(crs_address, crs_buffer_ptr, crs_size); | ||||
|     } else { | ||||
|         // Do nothing if buffer_ptr == address
 | ||||
|         // TODO(wwylele): verify this behaviour. This is only seen in the web browser app,
 | ||||
|  | @ -151,9 +149,9 @@ void RO::Initialize(Kernel::HLERequestContext& ctx) { | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     slot.memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||
|     slot->memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||
| 
 | ||||
|     slot.loaded_crs = crs_address; | ||||
|     slot->loaded_crs = crs_address; | ||||
| 
 | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
| } | ||||
|  | @ -207,14 +205,13 @@ void RO::LoadCRO(Kernel::HLERequestContext& ctx, bool link_on_load_bug_fix) { | |||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); | ||||
| 
 | ||||
|     auto find_result = slots.find(process->process_id); | ||||
|     if (find_result == slots.end()) { | ||||
|     ClientSlot* slot = GetSessionData(ctx.Session()); | ||||
|     if (slot->loaded_crs == 0) { | ||||
|         LOG_ERROR(Service_LDR, "Not initialized"); | ||||
|         rb.Push(ERROR_NOT_INITIALIZED); | ||||
|         rb.Push<u32>(0); | ||||
|         return; | ||||
|     } | ||||
|     auto& slot = find_result->second; | ||||
| 
 | ||||
|     if (cro_size < CRO_HEADER_SIZE) { | ||||
|         LOG_ERROR(Service_LDR, "CRO too small"); | ||||
|  | @ -293,7 +290,7 @@ void RO::LoadCRO(Kernel::HLERequestContext& ctx, bool link_on_load_bug_fix) { | |||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         slot.memory_synchronizer.AddMemoryBlock(cro_address, cro_buffer_ptr, cro_size); | ||||
|         slot->memory_synchronizer.AddMemoryBlock(cro_address, cro_buffer_ptr, cro_size); | ||||
|     } else { | ||||
|         // Do nothing if buffer_ptr == address
 | ||||
|         // TODO(wwylele): verify this behaviour.
 | ||||
|  | @ -314,7 +311,7 @@ void RO::LoadCRO(Kernel::HLERequestContext& ctx, bool link_on_load_bug_fix) { | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     result = cro.Rebase(slot.loaded_crs, cro_size, data_segment_address, data_segment_size, | ||||
|     result = cro.Rebase(slot->loaded_crs, cro_size, data_segment_address, data_segment_size, | ||||
|                         bss_segment_address, bss_segment_size, false); | ||||
|     if (result.IsError()) { | ||||
|         LOG_ERROR(Service_LDR, "Error rebasing CRO %08X", result.raw); | ||||
|  | @ -324,7 +321,7 @@ void RO::LoadCRO(Kernel::HLERequestContext& ctx, bool link_on_load_bug_fix) { | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     result = cro.Link(slot.loaded_crs, link_on_load_bug_fix); | ||||
|     result = cro.Link(slot->loaded_crs, link_on_load_bug_fix); | ||||
|     if (result.IsError()) { | ||||
|         LOG_ERROR(Service_LDR, "Error linking CRO %08X", result.raw); | ||||
|         process->vm_manager.UnmapRange(cro_address, cro_size); | ||||
|  | @ -333,11 +330,11 @@ void RO::LoadCRO(Kernel::HLERequestContext& ctx, bool link_on_load_bug_fix) { | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     cro.Register(slot.loaded_crs, auto_link); | ||||
|     cro.Register(slot->loaded_crs, auto_link); | ||||
| 
 | ||||
|     u32 fix_size = cro.Fix(fix_level); | ||||
| 
 | ||||
|     slot.memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||
|     slot->memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||
| 
 | ||||
|     // TODO(wwylele): verify the behaviour when buffer_ptr == address
 | ||||
|     if (cro_buffer_ptr != cro_address) { | ||||
|  | @ -353,7 +350,7 @@ void RO::LoadCRO(Kernel::HLERequestContext& ctx, bool link_on_load_bug_fix) { | |||
|         } | ||||
| 
 | ||||
|         // Changes the block size
 | ||||
|         slot.memory_synchronizer.ResizeMemoryBlock(cro_address, cro_buffer_ptr, fix_size); | ||||
|         slot->memory_synchronizer.ResizeMemoryBlock(cro_address, cro_buffer_ptr, fix_size); | ||||
|     } | ||||
| 
 | ||||
|     VAddr exe_begin; | ||||
|  | @ -393,13 +390,12 @@ void RO::UnloadCRO(Kernel::HLERequestContext& ctx) { | |||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
| 
 | ||||
|     auto find_result = slots.find(process->process_id); | ||||
|     if (find_result == slots.end()) { | ||||
|     ClientSlot* slot = GetSessionData(ctx.Session()); | ||||
|     if (slot->loaded_crs == 0) { | ||||
|         LOG_ERROR(Service_LDR, "Not initialized"); | ||||
|         rb.Push(ERROR_NOT_INITIALIZED); | ||||
|         return; | ||||
|     } | ||||
|     auto& slot = find_result->second; | ||||
| 
 | ||||
|     if (cro_address & Memory::PAGE_MASK) { | ||||
|         LOG_ERROR(Service_LDR, "CRO address is not aligned"); | ||||
|  | @ -417,9 +413,9 @@ void RO::UnloadCRO(Kernel::HLERequestContext& ctx) { | |||
| 
 | ||||
|     u32 fixed_size = cro.GetFixedSize(); | ||||
| 
 | ||||
|     cro.Unregister(slot.loaded_crs); | ||||
|     cro.Unregister(slot->loaded_crs); | ||||
| 
 | ||||
|     ResultCode result = cro.Unlink(slot.loaded_crs); | ||||
|     ResultCode result = cro.Unlink(slot->loaded_crs); | ||||
|     if (result.IsError()) { | ||||
|         LOG_ERROR(Service_LDR, "Error unlinking CRO %08X", result.raw); | ||||
|         rb.Push(result); | ||||
|  | @ -439,7 +435,7 @@ void RO::UnloadCRO(Kernel::HLERequestContext& ctx) { | |||
| 
 | ||||
|     cro.Unrebase(false); | ||||
| 
 | ||||
|     slot.memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||
|     slot->memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||
| 
 | ||||
|     // TODO(wwylele): verify the behaviour when buffer_ptr == address
 | ||||
|     if (cro_address != cro_buffer_ptr) { | ||||
|  | @ -447,7 +443,7 @@ void RO::UnloadCRO(Kernel::HLERequestContext& ctx) { | |||
|         if (result.IsError()) { | ||||
|             LOG_ERROR(Service_LDR, "Error unmapping CRO %08X", result.raw); | ||||
|         } | ||||
|         slot.memory_synchronizer.RemoveMemoryBlock(cro_address, cro_buffer_ptr); | ||||
|         slot->memory_synchronizer.RemoveMemoryBlock(cro_address, cro_buffer_ptr); | ||||
|     } | ||||
| 
 | ||||
|     Core::CPU().InvalidateCacheRange(cro_address, fixed_size); | ||||
|  | @ -466,13 +462,12 @@ void RO::LinkCRO(Kernel::HLERequestContext& ctx) { | |||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
| 
 | ||||
|     auto find_result = slots.find(process->process_id); | ||||
|     if (find_result == slots.end()) { | ||||
|     ClientSlot* slot = GetSessionData(ctx.Session()); | ||||
|     if (slot->loaded_crs == 0) { | ||||
|         LOG_ERROR(Service_LDR, "Not initialized"); | ||||
|         rb.Push(ERROR_NOT_INITIALIZED); | ||||
|         return; | ||||
|     } | ||||
|     auto& slot = find_result->second; | ||||
| 
 | ||||
|     if (cro_address & Memory::PAGE_MASK) { | ||||
|         LOG_ERROR(Service_LDR, "CRO address is not aligned"); | ||||
|  | @ -488,12 +483,12 @@ void RO::LinkCRO(Kernel::HLERequestContext& ctx) { | |||
| 
 | ||||
|     LOG_INFO(Service_LDR, "Linking CRO \"%s\"", cro.ModuleName().data()); | ||||
| 
 | ||||
|     ResultCode result = cro.Link(slot.loaded_crs, false); | ||||
|     ResultCode result = cro.Link(slot->loaded_crs, false); | ||||
|     if (result.IsError()) { | ||||
|         LOG_ERROR(Service_LDR, "Error linking CRO %08X", result.raw); | ||||
|     } | ||||
| 
 | ||||
|     slot.memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||
|     slot->memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||
| 
 | ||||
|     rb.Push(result); | ||||
| } | ||||
|  | @ -509,13 +504,12 @@ void RO::UnlinkCRO(Kernel::HLERequestContext& ctx) { | |||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
| 
 | ||||
|     auto find_result = slots.find(process->process_id); | ||||
|     if (find_result == slots.end()) { | ||||
|     ClientSlot* slot = GetSessionData(ctx.Session()); | ||||
|     if (slot->loaded_crs == 0) { | ||||
|         LOG_ERROR(Service_LDR, "Not initialized"); | ||||
|         rb.Push(ERROR_NOT_INITIALIZED); | ||||
|         return; | ||||
|     } | ||||
|     auto& slot = find_result->second; | ||||
| 
 | ||||
|     if (cro_address & Memory::PAGE_MASK) { | ||||
|         LOG_ERROR(Service_LDR, "CRO address is not aligned"); | ||||
|  | @ -531,12 +525,12 @@ void RO::UnlinkCRO(Kernel::HLERequestContext& ctx) { | |||
| 
 | ||||
|     LOG_INFO(Service_LDR, "Unlinking CRO \"%s\"", cro.ModuleName().data()); | ||||
| 
 | ||||
|     ResultCode result = cro.Unlink(slot.loaded_crs); | ||||
|     ResultCode result = cro.Unlink(slot->loaded_crs); | ||||
|     if (result.IsError()) { | ||||
|         LOG_ERROR(Service_LDR, "Error unlinking CRO %08X", result.raw); | ||||
|     } | ||||
| 
 | ||||
|     slot.memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||
|     slot->memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||
| 
 | ||||
|     rb.Push(result); | ||||
| } | ||||
|  | @ -550,31 +544,30 @@ void RO::Shutdown(Kernel::HLERequestContext& ctx) { | |||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
| 
 | ||||
|     auto find_result = slots.find(process->process_id); | ||||
|     if (find_result == slots.end()) { | ||||
|     ClientSlot* slot = GetSessionData(ctx.Session()); | ||||
|     if (slot->loaded_crs == 0) { | ||||
|         LOG_ERROR(Service_LDR, "Not initialized"); | ||||
|         rb.Push(ERROR_NOT_INITIALIZED); | ||||
|         return; | ||||
|     } | ||||
|     auto& slot = find_result->second; | ||||
| 
 | ||||
|     CROHelper crs(slot.loaded_crs); | ||||
|     CROHelper crs(slot->loaded_crs); | ||||
|     crs.Unrebase(true); | ||||
| 
 | ||||
|     slot.memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||
|     slot->memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||
| 
 | ||||
|     ResultCode result = RESULT_SUCCESS; | ||||
| 
 | ||||
|     // TODO(wwylele): verify the behaviour when buffer_ptr == address
 | ||||
|     if (slot.loaded_crs != crs_buffer_ptr) { | ||||
|         result = process->vm_manager.UnmapRange(slot.loaded_crs, crs.GetFileSize()); | ||||
|     if (slot->loaded_crs != crs_buffer_ptr) { | ||||
|         result = process->vm_manager.UnmapRange(slot->loaded_crs, crs.GetFileSize()); | ||||
|         if (result.IsError()) { | ||||
|             LOG_ERROR(Service_LDR, "Error unmapping CRS %08X", result.raw); | ||||
|         } | ||||
|         slot.memory_synchronizer.RemoveMemoryBlock(slot.loaded_crs, crs_buffer_ptr); | ||||
|         slot->memory_synchronizer.RemoveMemoryBlock(slot->loaded_crs, crs_buffer_ptr); | ||||
|     } | ||||
| 
 | ||||
|     slots.erase(find_result); | ||||
|     slot->loaded_crs = 0; | ||||
|     rb.Push(result); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,14 +4,18 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <unordered_map> | ||||
| #include "core/hle/service/ldr_ro/memory_synchronizer.h" | ||||
| #include "core/hle/service/service.h" | ||||
| 
 | ||||
| namespace Service { | ||||
| namespace LDR { | ||||
| 
 | ||||
| class RO final : public ServiceFramework<RO> { | ||||
| struct ClientSlot : public Kernel::SessionRequestHandler::SessionDataBase { | ||||
|     MemorySynchronizer memory_synchronizer; | ||||
|     VAddr loaded_crs = 0; ///< the virtual address of the static module
 | ||||
| }; | ||||
| 
 | ||||
| class RO final : public ServiceFramework<RO, ClientSlot> { | ||||
| public: | ||||
|     RO(); | ||||
| 
 | ||||
|  | @ -144,12 +148,6 @@ private: | |||
|      *      1 : Result of function, 0 on success, otherwise error code | ||||
|      */ | ||||
|     void Shutdown(Kernel::HLERequestContext& self); | ||||
| 
 | ||||
|     struct ClientSlot { | ||||
|         MemorySynchronizer memory_synchronizer; | ||||
|         VAddr loaded_crs = 0; ///< the virtual address of the static module
 | ||||
|     }; | ||||
|     std::unordered_map<u32, ClientSlot> slots; | ||||
| }; | ||||
| 
 | ||||
| void InstallInterfaces(SM::ServiceManager& service_manager); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue