diff options
author | liamwhite <liamwhite@users.noreply.github.com> | 2023-07-02 23:38:14 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-02 23:38:14 +0200 |
commit | daaf03942fb7a3d484941f8b5a09a6349be4b0c0 (patch) | |
tree | 4a35aff5a9cfa9896762b609720bdc30a0af4785 /src/core/hle/kernel/svc/svc_ipc.cpp | |
parent | Merge pull request #10949 from t895/memory-requirements (diff) | |
parent | kernel: Synchronize (diff) | |
download | yuzu-daaf03942fb7a3d484941f8b5a09a6349be4b0c0.tar yuzu-daaf03942fb7a3d484941f8b5a09a6349be4b0c0.tar.gz yuzu-daaf03942fb7a3d484941f8b5a09a6349be4b0c0.tar.bz2 yuzu-daaf03942fb7a3d484941f8b5a09a6349be4b0c0.tar.lz yuzu-daaf03942fb7a3d484941f8b5a09a6349be4b0c0.tar.xz yuzu-daaf03942fb7a3d484941f8b5a09a6349be4b0c0.tar.zst yuzu-daaf03942fb7a3d484941f8b5a09a6349be4b0c0.zip |
Diffstat (limited to 'src/core/hle/kernel/svc/svc_ipc.cpp')
-rw-r--r-- | src/core/hle/kernel/svc/svc_ipc.cpp | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/src/core/hle/kernel/svc/svc_ipc.cpp b/src/core/hle/kernel/svc/svc_ipc.cpp index 60247df2e..bb94f6934 100644 --- a/src/core/hle/kernel/svc/svc_ipc.cpp +++ b/src/core/hle/kernel/svc/svc_ipc.cpp @@ -38,22 +38,31 @@ Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_ha Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_addr, s32 num_handles, Handle reply_target, s64 timeout_ns) { + // Ensure number of handles is valid. + R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange); + + // Get the synchronization context. auto& kernel = system.Kernel(); auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); - - R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange); - R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange( - handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)), - ResultInvalidPointer); - - std::array<Handle, Svc::ArgumentHandleCountMax> handles; - GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles); - - // Convert handle list to object table. - std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> objs; - R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles.data(), - num_handles), - ResultInvalidHandle); + auto objs = GetCurrentThread(kernel).GetSynchronizationObjectBuffer(); + auto handles = GetCurrentThread(kernel).GetHandleBuffer(); + + // Copy user handles. + if (num_handles > 0) { + // Ensure we can try to get the handles. + R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange( + handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)), + ResultInvalidPointer); + + // Get the handles. + GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), + sizeof(Handle) * num_handles); + + // Convert the handles to objects. + R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>( + objs.data(), handles.data(), num_handles), + ResultInvalidHandle); + } // Ensure handles are closed when we're done. SCOPE_EXIT({ |