From 25ed190f4e0f8b720893e62350e5a521cc2c02b4 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 16 Oct 2019 12:50:04 -0700 Subject: [PATCH] spl: update for new-ipc (fixes two bugs in sf) --- .../sf/cmif/sf_cmif_domain_service_object.hpp | 2 +- .../cmif/sf_cmif_server_message_processor.hpp | 2 +- .../sf/impl/sf_impl_command_serialization.hpp | 27 ++++++++++--------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/include/stratosphere/sf/cmif/sf_cmif_domain_service_object.hpp b/include/stratosphere/sf/cmif/sf_cmif_domain_service_object.hpp index 2de93fb8..31b0657a 100644 --- a/include/stratosphere/sf/cmif/sf_cmif_domain_service_object.hpp +++ b/include/stratosphere/sf/cmif/sf_cmif_domain_service_object.hpp @@ -43,7 +43,7 @@ namespace sts::sf::cmif { } } - virtual Result PrepareForProcess(const ServiceDispatchContext &ctx, const size_t headers_size) const override final; + virtual Result PrepareForProcess(const ServiceDispatchContext &ctx, size_t &headers_size) const override final; virtual Result GetInObjects(ServiceObjectHolder *in_objects) const override final; virtual HipcRequest PrepareForReply(const cmif::ServiceDispatchContext &ctx, PointerAndSize &out_raw_data, const size_t headers_size, size_t &num_out_object_handles) override final; virtual void PrepareForErrorReply(const cmif::ServiceDispatchContext &ctx, PointerAndSize &out_raw_data, const size_t headers_size) override final; diff --git a/include/stratosphere/sf/cmif/sf_cmif_server_message_processor.hpp b/include/stratosphere/sf/cmif/sf_cmif_server_message_processor.hpp index 4bc1fdb0..e77b0611 100644 --- a/include/stratosphere/sf/cmif/sf_cmif_server_message_processor.hpp +++ b/include/stratosphere/sf/cmif/sf_cmif_server_message_processor.hpp @@ -30,7 +30,7 @@ namespace sts::sf::cmif { /* Used to enabled templated message processors. */ virtual void SetImplementationProcessor(ServerMessageProcessor *impl) { /* ... */ } - virtual Result PrepareForProcess(const ServiceDispatchContext &ctx, const size_t headers_size) const = 0; + virtual Result PrepareForProcess(const ServiceDispatchContext &ctx, size_t &headers_size) const = 0; virtual Result GetInObjects(ServiceObjectHolder *in_objects) const = 0; virtual HipcRequest PrepareForReply(const cmif::ServiceDispatchContext &ctx, PointerAndSize &out_raw_data, const size_t headers_size, size_t &num_out_object_handles) = 0; virtual void PrepareForErrorReply(const cmif::ServiceDispatchContext &ctx, PointerAndSize &out_raw_data, const size_t headers_size) = 0; diff --git a/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp b/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp index d6056b2c..b9d3dc20 100644 --- a/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp +++ b/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp @@ -300,7 +300,7 @@ namespace sts::sf::impl { static constexpr void StableSort(std::array &map, const std::array &values) { /* Use insertion sort, which is stable and optimal for small numbers of parameters. */ for (size_t i = 1; i < sizeof...(Ts); i++) { - for (size_t j = i; j > 0 && values[j-1] > values[j]; j--) { + for (size_t j = i; j > 0 && values[map[j-1]] > values[map[j]]; j--) { /* std::swap is not constexpr until c++20 :( */ /* TODO: std::swap(map[j], map[j-1]); */ const size_t tmp = map[j]; @@ -686,7 +686,7 @@ namespace sts::sf::impl { template struct HipcCommandProcessor : public sf::cmif::ServerMessageProcessor { public: - virtual Result PrepareForProcess(const cmif::ServiceDispatchContext &ctx, const size_t headers_size) const override final { + virtual Result PrepareForProcess(const cmif::ServiceDispatchContext &ctx, size_t &headers_size) const override final { const auto &meta = ctx.request.meta; bool is_request_valid = true; is_request_valid &= meta.send_pid == CommandMeta::HasInProcessIdHolder; @@ -789,7 +789,7 @@ namespace sts::sf::impl { }(); template> - NX_CONSTEXPR void ProcessBufferImpl(const cmif::ServiceDispatchContext &ctx, cmif::PointerAndSize &buffer, bool &is_buffer_map_alias, bool &map_alias_buffers_valid, size_t &pointer_buffer_head, size_t &pointer_buffer_tail) { + NX_CONSTEXPR void ProcessBufferImpl(const cmif::ServiceDispatchContext &ctx, cmif::PointerAndSize &buffer, bool &is_buffer_map_alias, bool &map_alias_buffers_valid, size_t &pointer_buffer_head, size_t &pointer_buffer_tail, size_t in_headers_size) { static_assert(Index != std::numeric_limits::max(), "Invalid Index From Buffer Index"); constexpr auto Info = CommandMeta::ArgumentSerializationInfos[Index]; constexpr auto Attributes = CommandMeta::BufferAttributes[BufferIndex]; @@ -824,7 +824,7 @@ namespace sts::sf::impl { pointer_buffer_head = util::AlignDown(pointer_buffer_head - size, 0x10); buffer = cmif::PointerAndSize(pointer_buffer_head, size); } else { - const u16 *recv_pointer_sizes = reinterpret_cast(reinterpret_cast(ctx.request.data.data_words) + CommandMeta::InDataRawUnfixedOutPointerSizeOffset); + const u16 *recv_pointer_sizes = reinterpret_cast(reinterpret_cast(ctx.request.data.data_words) + in_headers_size + CommandMeta::InDataRawUnfixedOutPointerSizeOffset); const size_t size = size_t(recv_pointer_sizes[Info.unfixed_recv_pointer_index]); pointer_buffer_head = util::AlignDown(pointer_buffer_head - size, 0x10); buffer = cmif::PointerAndSize(pointer_buffer_head, size); @@ -894,11 +894,11 @@ namespace sts::sf::impl { } } public: - NX_CONSTEXPR Result ProcessBuffers(const cmif::ServiceDispatchContext &ctx, BufferArrayType &buffers, std::array &is_buffer_map_alias) { + NX_CONSTEXPR Result ProcessBuffers(const cmif::ServiceDispatchContext &ctx, BufferArrayType &buffers, std::array &is_buffer_map_alias, size_t in_headers_size) { bool map_alias_buffers_valid = true; size_t pointer_buffer_tail = ctx.pointer_buffer.GetAddress(); size_t pointer_buffer_head = pointer_buffer_tail + ctx.pointer_buffer.GetSize(); - #define _SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(n) do { if constexpr (CommandMeta::NumBuffers > n) { ProcessBufferImpl(ctx, buffers[n], is_buffer_map_alias[n], map_alias_buffers_valid, pointer_buffer_head, pointer_buffer_tail); } } while (0) + #define _SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(n) do { if constexpr (CommandMeta::NumBuffers > n) { ProcessBufferImpl(ctx, buffers[n], is_buffer_map_alias[n], map_alias_buffers_valid, pointer_buffer_head, pointer_buffer_tail, in_headers_size); } } while (0) _SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(0); _SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(1); _SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(2); @@ -1010,7 +1010,7 @@ namespace sts::sf::impl { return ResultSuccess; } - template::ClassType> + template constexpr Result InvokeServiceCommandImpl(CmifOutHeader **out_header_ptr, cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data) { using CommandMeta = CommandMetaInfo; using ImplProcessorType = HipcCommandProcessor; @@ -1018,7 +1018,7 @@ namespace sts::sf::impl { using OutHandleHolderType = OutHandleHolder; using OutRawHolderType = OutRawHolder; using InOutObjectHolderType = InOutObjectHolder; - static_assert(std::is_base_of::value, "InvokeServiceCommandImpl: Invalid Override ClassType"); + using ClassType = typename CommandMeta::ClassType; static_assert(std::is_base_of::value, "InvokeServiceCommandImpl: Service Commands must be ServiceObject member functions"); /* Create a processor for us to work with. */ @@ -1032,7 +1032,8 @@ namespace sts::sf::impl { } /* Validate the metadata has the expected counts. */ - R_TRY(ctx.processor->PrepareForProcess(ctx, sizeof(CmifInHeader))); + size_t in_headers_size = sizeof(CmifInHeader); + R_TRY(ctx.processor->PrepareForProcess(ctx, in_headers_size)); /* Storage for output. */ BufferArrayType buffers; @@ -1042,7 +1043,7 @@ namespace sts::sf::impl { InOutObjectHolderType in_out_objects_holder; /* Process buffers. */ - R_TRY(ImplProcessorType::ProcessBuffers(ctx, buffers, is_buffer_map_alias)); + R_TRY(ImplProcessorType::ProcessBuffers(ctx, buffers, is_buffer_map_alias, in_headers_size)); /* Process input/output objects. */ R_TRY(in_out_objects_holder.GetInObjects(ctx.processor)); @@ -1095,16 +1096,16 @@ namespace sts::sf::impl { namespace sts::sf { - template + template inline static constexpr cmif::ServiceCommandMeta MakeServiceCommandMeta() { return { .hosver_low = Low, .hosver_high = High, .cmd_id = static_cast(CommandId), - .handler = ::sts::sf::impl::InvokeServiceCommandImpl, + .handler = ::sts::sf::impl::InvokeServiceCommandImpl, }; } } -#define MAKE_SERVICE_COMMAND_META(Name, ...) ::sts::sf::MakeServiceCommandMeta() +#define MAKE_SERVICE_COMMAND_META(Name, ...) ::sts::sf::MakeServiceCommandMeta()