mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Merge pull request #3309 from wwylele/cro-session-slot
ldr_ro: use ServiceFramework's session slot for client slot
This commit is contained in:
		
						commit
						3f37976fd3
					
				
					 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); |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
| 
 | 
 | ||||||
|     auto insert_result = slots.insert({process->process_id, {}}); |     ClientSlot* slot = GetSessionData(ctx.Session()); | ||||||
|     if (!insert_result.second) { |     if (slot->loaded_crs != 0) { | ||||||
|         LOG_ERROR(Service_LDR, "Already initialized"); |         LOG_ERROR(Service_LDR, "Already initialized"); | ||||||
|         rb.Push(ERROR_ALREADY_INITIALIZED); |         rb.Push(ERROR_ALREADY_INITIALIZED); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto& slot = insert_result.first->second; |  | ||||||
| 
 |  | ||||||
|     if (crs_size < CRO_HEADER_SIZE) { |     if (crs_size < CRO_HEADER_SIZE) { | ||||||
|         LOG_ERROR(Service_LDR, "CRS is too small"); |         LOG_ERROR(Service_LDR, "CRS is too small"); | ||||||
|         rb.Push(ERROR_BUFFER_TOO_SMALL); |         rb.Push(ERROR_BUFFER_TOO_SMALL); | ||||||
|  | @ -132,7 +130,7 @@ void RO::Initialize(Kernel::HLERequestContext& ctx) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         slot.memory_synchronizer.AddMemoryBlock(crs_address, crs_buffer_ptr, crs_size); |         slot->memory_synchronizer.AddMemoryBlock(crs_address, crs_buffer_ptr, crs_size); | ||||||
|     } else { |     } else { | ||||||
|         // Do nothing if buffer_ptr == address
 |         // Do nothing if buffer_ptr == address
 | ||||||
|         // TODO(wwylele): verify this behaviour. This is only seen in the web browser app,
 |         // 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; |         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); |     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); |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); | ||||||
| 
 | 
 | ||||||
|     auto find_result = slots.find(process->process_id); |     ClientSlot* slot = GetSessionData(ctx.Session()); | ||||||
|     if (find_result == slots.end()) { |     if (slot->loaded_crs == 0) { | ||||||
|         LOG_ERROR(Service_LDR, "Not initialized"); |         LOG_ERROR(Service_LDR, "Not initialized"); | ||||||
|         rb.Push(ERROR_NOT_INITIALIZED); |         rb.Push(ERROR_NOT_INITIALIZED); | ||||||
|         rb.Push<u32>(0); |         rb.Push<u32>(0); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     auto& slot = find_result->second; |  | ||||||
| 
 | 
 | ||||||
|     if (cro_size < CRO_HEADER_SIZE) { |     if (cro_size < CRO_HEADER_SIZE) { | ||||||
|         LOG_ERROR(Service_LDR, "CRO too small"); |         LOG_ERROR(Service_LDR, "CRO too small"); | ||||||
|  | @ -293,7 +290,7 @@ void RO::LoadCRO(Kernel::HLERequestContext& ctx, bool link_on_load_bug_fix) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         slot.memory_synchronizer.AddMemoryBlock(cro_address, cro_buffer_ptr, cro_size); |         slot->memory_synchronizer.AddMemoryBlock(cro_address, cro_buffer_ptr, cro_size); | ||||||
|     } else { |     } else { | ||||||
|         // Do nothing if buffer_ptr == address
 |         // Do nothing if buffer_ptr == address
 | ||||||
|         // TODO(wwylele): verify this behaviour.
 |         // TODO(wwylele): verify this behaviour.
 | ||||||
|  | @ -314,7 +311,7 @@ void RO::LoadCRO(Kernel::HLERequestContext& ctx, bool link_on_load_bug_fix) { | ||||||
|         return; |         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); |                         bss_segment_address, bss_segment_size, false); | ||||||
|     if (result.IsError()) { |     if (result.IsError()) { | ||||||
|         LOG_ERROR(Service_LDR, "Error rebasing CRO %08X", result.raw); |         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; |         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()) { |     if (result.IsError()) { | ||||||
|         LOG_ERROR(Service_LDR, "Error linking CRO %08X", result.raw); |         LOG_ERROR(Service_LDR, "Error linking CRO %08X", result.raw); | ||||||
|         process->vm_manager.UnmapRange(cro_address, cro_size); |         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; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     cro.Register(slot.loaded_crs, auto_link); |     cro.Register(slot->loaded_crs, auto_link); | ||||||
| 
 | 
 | ||||||
|     u32 fix_size = cro.Fix(fix_level); |     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
 |     // TODO(wwylele): verify the behaviour when buffer_ptr == address
 | ||||||
|     if (cro_buffer_ptr != cro_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
 |         // 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; |     VAddr exe_begin; | ||||||
|  | @ -393,13 +390,12 @@ void RO::UnloadCRO(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
| 
 | 
 | ||||||
|     auto find_result = slots.find(process->process_id); |     ClientSlot* slot = GetSessionData(ctx.Session()); | ||||||
|     if (find_result == slots.end()) { |     if (slot->loaded_crs == 0) { | ||||||
|         LOG_ERROR(Service_LDR, "Not initialized"); |         LOG_ERROR(Service_LDR, "Not initialized"); | ||||||
|         rb.Push(ERROR_NOT_INITIALIZED); |         rb.Push(ERROR_NOT_INITIALIZED); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     auto& slot = find_result->second; |  | ||||||
| 
 | 
 | ||||||
|     if (cro_address & Memory::PAGE_MASK) { |     if (cro_address & Memory::PAGE_MASK) { | ||||||
|         LOG_ERROR(Service_LDR, "CRO address is not aligned"); |         LOG_ERROR(Service_LDR, "CRO address is not aligned"); | ||||||
|  | @ -417,9 +413,9 @@ void RO::UnloadCRO(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     u32 fixed_size = cro.GetFixedSize(); |     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()) { |     if (result.IsError()) { | ||||||
|         LOG_ERROR(Service_LDR, "Error unlinking CRO %08X", result.raw); |         LOG_ERROR(Service_LDR, "Error unlinking CRO %08X", result.raw); | ||||||
|         rb.Push(result); |         rb.Push(result); | ||||||
|  | @ -439,7 +435,7 @@ void RO::UnloadCRO(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     cro.Unrebase(false); |     cro.Unrebase(false); | ||||||
| 
 | 
 | ||||||
|     slot.memory_synchronizer.SynchronizeOriginalMemory(*process); |     slot->memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||||
| 
 | 
 | ||||||
|     // TODO(wwylele): verify the behaviour when buffer_ptr == address
 |     // TODO(wwylele): verify the behaviour when buffer_ptr == address
 | ||||||
|     if (cro_address != cro_buffer_ptr) { |     if (cro_address != cro_buffer_ptr) { | ||||||
|  | @ -447,7 +443,7 @@ void RO::UnloadCRO(Kernel::HLERequestContext& ctx) { | ||||||
|         if (result.IsError()) { |         if (result.IsError()) { | ||||||
|             LOG_ERROR(Service_LDR, "Error unmapping CRO %08X", result.raw); |             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); |     Core::CPU().InvalidateCacheRange(cro_address, fixed_size); | ||||||
|  | @ -466,13 +462,12 @@ void RO::LinkCRO(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
| 
 | 
 | ||||||
|     auto find_result = slots.find(process->process_id); |     ClientSlot* slot = GetSessionData(ctx.Session()); | ||||||
|     if (find_result == slots.end()) { |     if (slot->loaded_crs == 0) { | ||||||
|         LOG_ERROR(Service_LDR, "Not initialized"); |         LOG_ERROR(Service_LDR, "Not initialized"); | ||||||
|         rb.Push(ERROR_NOT_INITIALIZED); |         rb.Push(ERROR_NOT_INITIALIZED); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     auto& slot = find_result->second; |  | ||||||
| 
 | 
 | ||||||
|     if (cro_address & Memory::PAGE_MASK) { |     if (cro_address & Memory::PAGE_MASK) { | ||||||
|         LOG_ERROR(Service_LDR, "CRO address is not aligned"); |         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()); |     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()) { |     if (result.IsError()) { | ||||||
|         LOG_ERROR(Service_LDR, "Error linking CRO %08X", result.raw); |         LOG_ERROR(Service_LDR, "Error linking CRO %08X", result.raw); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     slot.memory_synchronizer.SynchronizeOriginalMemory(*process); |     slot->memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||||
| 
 | 
 | ||||||
|     rb.Push(result); |     rb.Push(result); | ||||||
| } | } | ||||||
|  | @ -509,13 +504,12 @@ void RO::UnlinkCRO(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
| 
 | 
 | ||||||
|     auto find_result = slots.find(process->process_id); |     ClientSlot* slot = GetSessionData(ctx.Session()); | ||||||
|     if (find_result == slots.end()) { |     if (slot->loaded_crs == 0) { | ||||||
|         LOG_ERROR(Service_LDR, "Not initialized"); |         LOG_ERROR(Service_LDR, "Not initialized"); | ||||||
|         rb.Push(ERROR_NOT_INITIALIZED); |         rb.Push(ERROR_NOT_INITIALIZED); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     auto& slot = find_result->second; |  | ||||||
| 
 | 
 | ||||||
|     if (cro_address & Memory::PAGE_MASK) { |     if (cro_address & Memory::PAGE_MASK) { | ||||||
|         LOG_ERROR(Service_LDR, "CRO address is not aligned"); |         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()); |     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()) { |     if (result.IsError()) { | ||||||
|         LOG_ERROR(Service_LDR, "Error unlinking CRO %08X", result.raw); |         LOG_ERROR(Service_LDR, "Error unlinking CRO %08X", result.raw); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     slot.memory_synchronizer.SynchronizeOriginalMemory(*process); |     slot->memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||||
| 
 | 
 | ||||||
|     rb.Push(result); |     rb.Push(result); | ||||||
| } | } | ||||||
|  | @ -550,31 +544,30 @@ void RO::Shutdown(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
| 
 | 
 | ||||||
|     auto find_result = slots.find(process->process_id); |     ClientSlot* slot = GetSessionData(ctx.Session()); | ||||||
|     if (find_result == slots.end()) { |     if (slot->loaded_crs == 0) { | ||||||
|         LOG_ERROR(Service_LDR, "Not initialized"); |         LOG_ERROR(Service_LDR, "Not initialized"); | ||||||
|         rb.Push(ERROR_NOT_INITIALIZED); |         rb.Push(ERROR_NOT_INITIALIZED); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     auto& slot = find_result->second; |  | ||||||
| 
 | 
 | ||||||
|     CROHelper crs(slot.loaded_crs); |     CROHelper crs(slot->loaded_crs); | ||||||
|     crs.Unrebase(true); |     crs.Unrebase(true); | ||||||
| 
 | 
 | ||||||
|     slot.memory_synchronizer.SynchronizeOriginalMemory(*process); |     slot->memory_synchronizer.SynchronizeOriginalMemory(*process); | ||||||
| 
 | 
 | ||||||
|     ResultCode result = RESULT_SUCCESS; |     ResultCode result = RESULT_SUCCESS; | ||||||
| 
 | 
 | ||||||
|     // TODO(wwylele): verify the behaviour when buffer_ptr == address
 |     // TODO(wwylele): verify the behaviour when buffer_ptr == address
 | ||||||
|     if (slot.loaded_crs != crs_buffer_ptr) { |     if (slot->loaded_crs != crs_buffer_ptr) { | ||||||
|         result = process->vm_manager.UnmapRange(slot.loaded_crs, crs.GetFileSize()); |         result = process->vm_manager.UnmapRange(slot->loaded_crs, crs.GetFileSize()); | ||||||
|         if (result.IsError()) { |         if (result.IsError()) { | ||||||
|             LOG_ERROR(Service_LDR, "Error unmapping CRS %08X", result.raw); |             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); |     rb.Push(result); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,14 +4,18 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <unordered_map> |  | ||||||
| #include "core/hle/service/ldr_ro/memory_synchronizer.h" | #include "core/hle/service/ldr_ro/memory_synchronizer.h" | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/service.h" | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
| namespace LDR { | 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: | public: | ||||||
|     RO(); |     RO(); | ||||||
| 
 | 
 | ||||||
|  | @ -144,12 +148,6 @@ private: | ||||||
|      *      1 : Result of function, 0 on success, otherwise error code |      *      1 : Result of function, 0 on success, otherwise error code | ||||||
|      */ |      */ | ||||||
|     void Shutdown(Kernel::HLERequestContext& self); |     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); | void InstallInterfaces(SM::ServiceManager& service_manager); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue