summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/service/cmif_serialization.h50
1 files changed, 38 insertions, 12 deletions
diff --git a/src/core/hle/service/cmif_serialization.h b/src/core/hle/service/cmif_serialization.h
index 9ee26400d..5eabf51fe 100644
--- a/src/core/hle/service/cmif_serialization.h
+++ b/src/core/hle/service/cmif_serialization.h
@@ -122,14 +122,14 @@ struct RequestLayout {
122 u32 domain_interface_count; 122 u32 domain_interface_count;
123}; 123};
124 124
125template <ArgumentType Type1, ArgumentType Type2, typename MethodArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t ArgIndex = 0> 125template <typename MethodArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t ArgIndex = 0>
126constexpr u32 GetArgumentRawDataSize() { 126constexpr u32 GetInRawDataSize() {
127 if constexpr (ArgIndex >= std::tuple_size_v<MethodArguments>) { 127 if constexpr (ArgIndex >= std::tuple_size_v<MethodArguments>) {
128 return static_cast<u32>(DataOffset); 128 return static_cast<u32>(DataOffset);
129 } else { 129 } else {
130 using ArgType = std::tuple_element_t<ArgIndex, MethodArguments>; 130 using ArgType = std::tuple_element_t<ArgIndex, MethodArguments>;
131 131
132 if constexpr (ArgumentTraits<ArgType>::Type == Type1 || ArgumentTraits<ArgType>::Type == Type2) { 132 if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InData || ArgumentTraits<ArgType>::Type == ArgumentType::InProcessId) {
133 constexpr size_t ArgAlign = alignof(ArgType); 133 constexpr size_t ArgAlign = alignof(ArgType);
134 constexpr size_t ArgSize = sizeof(ArgType); 134 constexpr size_t ArgSize = sizeof(ArgType);
135 135
@@ -138,9 +138,33 @@ constexpr u32 GetArgumentRawDataSize() {
138 constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign); 138 constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign);
139 constexpr size_t ArgEnd = ArgOffset + ArgSize; 139 constexpr size_t ArgEnd = ArgOffset + ArgSize;
140 140
141 return GetArgumentRawDataSize<Type1, Type2, MethodArguments, ArgAlign, ArgEnd, ArgIndex + 1>(); 141 return GetInRawDataSize<MethodArguments, ArgAlign, ArgEnd, ArgIndex + 1>();
142 } else {
143 return GetInRawDataSize<MethodArguments, PrevAlign, DataOffset, ArgIndex + 1>();
144 }
145 }
146}
147
148template <typename MethodArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t ArgIndex = 0>
149constexpr u32 GetOutRawDataSize() {
150 if constexpr (ArgIndex >= std::tuple_size_v<MethodArguments>) {
151 return static_cast<u32>(DataOffset);
152 } else {
153 using ArgType = std::tuple_element_t<ArgIndex, MethodArguments>;
154
155 if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutData) {
156 using RawArgType = typename ArgType::Type;
157 constexpr size_t ArgAlign = alignof(RawArgType);
158 constexpr size_t ArgSize = sizeof(RawArgType);
159
160 static_assert(PrevAlign <= ArgAlign, "Output argument is not ordered by alignment");
161
162 constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign);
163 constexpr size_t ArgEnd = ArgOffset + ArgSize;
164
165 return GetOutRawDataSize<MethodArguments, ArgAlign, ArgEnd, ArgIndex + 1>();
142 } else { 166 } else {
143 return GetArgumentRawDataSize<Type1, Type2, MethodArguments, PrevAlign, DataOffset, ArgIndex + 1>(); 167 return GetOutRawDataSize<MethodArguments, PrevAlign, DataOffset, ArgIndex + 1>();
144 } 168 }
145 } 169 }
146} 170}
@@ -165,7 +189,7 @@ constexpr RequestLayout GetNonDomainReplyInLayout() {
165 return RequestLayout{ 189 return RequestLayout{
166 .copy_handle_count = GetArgumentTypeCount<ArgumentType::InCopyHandle, MethodArguments>(), 190 .copy_handle_count = GetArgumentTypeCount<ArgumentType::InCopyHandle, MethodArguments>(),
167 .move_handle_count = 0, 191 .move_handle_count = 0,
168 .cmif_raw_data_size = GetArgumentRawDataSize<ArgumentType::InData, ArgumentType::InProcessId, MethodArguments>(), 192 .cmif_raw_data_size = GetInRawDataSize<MethodArguments>(),
169 .domain_interface_count = 0, 193 .domain_interface_count = 0,
170 }; 194 };
171} 195}
@@ -175,7 +199,7 @@ constexpr RequestLayout GetDomainReplyInLayout() {
175 return RequestLayout{ 199 return RequestLayout{
176 .copy_handle_count = GetArgumentTypeCount<ArgumentType::InCopyHandle, MethodArguments>(), 200 .copy_handle_count = GetArgumentTypeCount<ArgumentType::InCopyHandle, MethodArguments>(),
177 .move_handle_count = 0, 201 .move_handle_count = 0,
178 .cmif_raw_data_size = GetArgumentRawDataSize<ArgumentType::InData, ArgumentType::InProcessId, MethodArguments>(), 202 .cmif_raw_data_size = GetInRawDataSize<MethodArguments>(),
179 .domain_interface_count = GetArgumentTypeCount<ArgumentType::InInterface, MethodArguments>(), 203 .domain_interface_count = GetArgumentTypeCount<ArgumentType::InInterface, MethodArguments>(),
180 }; 204 };
181} 205}
@@ -185,7 +209,7 @@ constexpr RequestLayout GetNonDomainReplyOutLayout() {
185 return RequestLayout{ 209 return RequestLayout{
186 .copy_handle_count = GetArgumentTypeCount<ArgumentType::OutCopyHandle, MethodArguments>(), 210 .copy_handle_count = GetArgumentTypeCount<ArgumentType::OutCopyHandle, MethodArguments>(),
187 .move_handle_count = GetArgumentTypeCount<ArgumentType::OutMoveHandle, MethodArguments>() + GetArgumentTypeCount<ArgumentType::OutInterface, MethodArguments>(), 211 .move_handle_count = GetArgumentTypeCount<ArgumentType::OutMoveHandle, MethodArguments>() + GetArgumentTypeCount<ArgumentType::OutInterface, MethodArguments>(),
188 .cmif_raw_data_size = GetArgumentRawDataSize<ArgumentType::OutData, ArgumentType::OutData, MethodArguments>(), 212 .cmif_raw_data_size = GetOutRawDataSize<MethodArguments>(),
189 .domain_interface_count = 0, 213 .domain_interface_count = 0,
190 }; 214 };
191} 215}
@@ -195,7 +219,7 @@ constexpr RequestLayout GetDomainReplyOutLayout() {
195 return RequestLayout{ 219 return RequestLayout{
196 .copy_handle_count = GetArgumentTypeCount<ArgumentType::OutCopyHandle, MethodArguments>(), 220 .copy_handle_count = GetArgumentTypeCount<ArgumentType::OutCopyHandle, MethodArguments>(),
197 .move_handle_count = GetArgumentTypeCount<ArgumentType::OutMoveHandle, MethodArguments>(), 221 .move_handle_count = GetArgumentTypeCount<ArgumentType::OutMoveHandle, MethodArguments>(),
198 .cmif_raw_data_size = GetArgumentRawDataSize<ArgumentType::OutData, ArgumentType::OutData, MethodArguments>(), 222 .cmif_raw_data_size = GetOutRawDataSize<MethodArguments>(),
199 .domain_interface_count = GetArgumentTypeCount<ArgumentType::OutInterface, MethodArguments>(), 223 .domain_interface_count = GetArgumentTypeCount<ArgumentType::OutInterface, MethodArguments>(),
200 }; 224 };
201} 225}
@@ -337,13 +361,15 @@ void WriteOutArgument(bool is_domain, CallArguments& args, u8* raw_data, HLERequ
337 using ArgType = std::tuple_element_t<ArgIndex, MethodArguments>; 361 using ArgType = std::tuple_element_t<ArgIndex, MethodArguments>;
338 362
339 if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutData) { 363 if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutData) {
340 constexpr size_t ArgAlign = alignof(ArgType); 364 using RawArgType = decltype(std::get<ArgIndex>(args).raw);
341 constexpr size_t ArgSize = sizeof(ArgType); 365 constexpr size_t ArgAlign = alignof(RawArgType);
366 constexpr size_t ArgSize = sizeof(RawArgType);
342 367
343 static_assert(PrevAlign <= ArgAlign, "Output argument is not ordered by alignment"); 368 static_assert(PrevAlign <= ArgAlign, "Output argument is not ordered by alignment");
344 static_assert(!RawDataFinished, "All output interface arguments must appear after raw data"); 369 static_assert(!RawDataFinished, "All output interface arguments must appear after raw data");
345 static_assert(!std::is_pointer_v<ArgType>, "Output raw data must not be a pointer"); 370 static_assert(!std::is_pointer_v<ArgType>, "Output raw data must not be a pointer");
346 static_assert(std::is_trivially_copyable_v<decltype(std::get<ArgIndex>(args).raw)>, "Output raw data must be trivially copyable"); 371 static_assert(!std::is_pointer_v<RawArgType>, "Output raw data must not be a pointer");
372 static_assert(std::is_trivially_copyable_v<RawArgType>, "Output raw data must be trivially copyable");
347 373
348 constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign); 374 constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign);
349 constexpr size_t ArgEnd = ArgOffset + ArgSize; 375 constexpr size_t ArgEnd = ArgOffset + ArgSize;