diff options
author | Subv <subv2112@gmail.com> | 2018-01-06 21:14:14 -0500 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2018-01-07 17:11:43 -0500 |
commit | 226786f0b05405b4c0287786f106ae2e08feefec (patch) | |
tree | f4cb770adc575fa749b98e60f8f5fa0012cdc4c6 /src | |
parent | bc8ef64804841c996aeebfe7ce23f34347a0be60 (diff) |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/core/hle/ipc.h | 10 | ||||
-rw-r--r-- | src/core/hle/ipc_helpers.h | 19 | ||||
-rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 2 | ||||
-rw-r--r-- | 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 <class T> void PushIpcInterface() { auto& request_handlers = context->Domain()->request_handlers; - request_handlers.push_back(std::move(std::make_shared<T>()->shared_from_this())); + request_handlers.emplace_back(std::make_shared<T>()); Push(RESULT_SUCCESS); - AlignWithPadding(); + Push<u32>(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<u32>(static_cast<u32>(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<IPC::DomainMessageHeader>(rp.PopRaw<IPC::DomainMessageHeader>()); + std::make_unique<IPC::DomainRequestMessageHeader>(rp.PopRaw<IPC::DomainRequestMessageHeader>()); } 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<IPC::DomainMessageHeader>& GetDomainMessageHeader() const { + const std::vector<IPC::BufferDescriptorABW>& BufferDescriptorA() const { + return buffer_a_desciptors; + } + + const std::unique_ptr<IPC::DomainRequestMessageHeader>& GetDomainMessageHeader() const { return domain_message_header; } @@ -172,7 +176,7 @@ private: std::unique_ptr<IPC::CommandHeader> command_header; std::unique_ptr<IPC::HandleDescriptorHeader> handle_descriptor_header; std::unique_ptr<IPC::DataPayloadHeader> data_payload_header; - std::unique_ptr<IPC::DomainMessageHeader> domain_message_header; + std::unique_ptr<IPC::DomainRequestMessageHeader> domain_message_header; std::vector<IPC::BufferDescriptorX> buffer_x_desciptors; std::vector<IPC::BufferDescriptorABW> buffer_a_desciptors; std::vector<IPC::BufferDescriptorABW> buffer_b_desciptors; |