From 226786f0b05405b4c0287786f106ae2e08feefec Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 6 Jan 2018 21:14:14 -0500 Subject: IPC: Use the correct size when pushing raw data to the command buffer and fixed pushing domain objects. Domain object ids are always stored immediately after the raw data. --- src/core/hle/ipc.h | 10 ++++++++-- src/core/hle/ipc_helpers.h | 19 ++++++++++++++----- src/core/hle/kernel/hle_ipc.cpp | 2 +- src/core/hle/kernel/hle_ipc.h | 8 ++++++-- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h index 4dc8937c3..4c21f5024 100644 --- a/src/core/hle/ipc.h +++ b/src/core/hle/ipc.h @@ -143,7 +143,7 @@ struct DataPayloadHeader { }; static_assert(sizeof(DataPayloadHeader) == 8, "DataPayloadRequest size is incorrect"); -struct DomainMessageHeader { +struct DomainRequestMessageHeader { union { BitField<0, 8, u32_le> command; BitField<16, 16, u32_le> size; @@ -151,7 +151,13 @@ struct DomainMessageHeader { u32_le object_id; INSERT_PADDING_WORDS(2); }; -static_assert(sizeof(DomainMessageHeader) == 16, "DomainMessageHeader size is incorrect"); +static_assert(sizeof(DomainRequestMessageHeader) == 16, "DomainRequestMessageHeader size is incorrect"); + +struct DomainResponseMessageHeader { + u32_le num_objects; + INSERT_PADDING_WORDS(3); +}; +static_assert(sizeof(DomainResponseMessageHeader) == 16, "DomainResponseMessageHeader size is incorrect"); enum DescriptorType : u32 { // Buffer related desciptors types (mask : 0x0F) diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 28a2b8545..705943e6b 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h @@ -58,14 +58,20 @@ public: RequestBuilder(u32* command_buffer) : RequestHelperBase(command_buffer) {} RequestBuilder(Kernel::HLERequestContext& context, unsigned normal_params_size, - u32 num_handles_to_copy = 0, u32 num_handles_to_move = 0) + u32 num_handles_to_copy = 0, u32 num_handles_to_move = 0, u32 num_domain_objects = 0) : RequestHelperBase(context) { memset(cmdbuf, 0, 64); context.ClearIncomingObjects(); IPC::CommandHeader header{}; - header.data_size.Assign(normal_params_size * sizeof(u32)); + + // The entire size of the raw data section in u32 units, including the 16 bytes of mandatory padding. + u32 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size; + if (context.IsDomain()) + raw_data_size += sizeof(DomainResponseMessageHeader) / 4 + num_domain_objects; + + header.data_size.Assign(raw_data_size); if (num_handles_to_copy || num_handles_to_move) { header.enable_handle_descriptor.Assign(1); } @@ -82,7 +88,9 @@ public: AlignWithPadding(); if (context.IsDomain()) { - PushRaw(IPC::DomainMessageHeader{}); + IPC::DomainResponseMessageHeader domain_header{}; + domain_header.num_objects = num_domain_objects; + PushRaw(domain_header); } IPC::DataPayloadHeader data_payload_header{}; @@ -93,9 +101,10 @@ public: template void PushIpcInterface() { auto& request_handlers = context->Domain()->request_handlers; - request_handlers.push_back(std::move(std::make_shared()->shared_from_this())); + request_handlers.emplace_back(std::make_shared()); Push(RESULT_SUCCESS); - AlignWithPadding(); + Push(0); // The error code is the lower word of an u64, so we fill the rest with 0. + // Now push the id of the newly-added object. Push(static_cast(request_handlers.size())); } diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 85dd80159..e784d59cc 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -95,7 +95,7 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) { // If this is an incoming message, only CommandType "Request" has a domain header // All outgoing domain messages have the domain header domain_message_header = - std::make_unique(rp.PopRaw()); + std::make_unique(rp.PopRaw()); } data_payload_header = diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 7de13b36b..b5649931d 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -154,7 +154,11 @@ public: return buffer_x_desciptors; } - const std::unique_ptr& GetDomainMessageHeader() const { + const std::vector& BufferDescriptorA() const { + return buffer_a_desciptors; + } + + const std::unique_ptr& GetDomainMessageHeader() const { return domain_message_header; } @@ -172,7 +176,7 @@ private: std::unique_ptr command_header; std::unique_ptr handle_descriptor_header; std::unique_ptr data_payload_header; - std::unique_ptr domain_message_header; + std::unique_ptr domain_message_header; std::vector buffer_x_desciptors; std::vector buffer_a_desciptors; std::vector buffer_b_desciptors; -- cgit v1.2.3