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 | |
| 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.
| -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;  | 
