diff options
| author | 2024-01-30 02:22:45 -0500 | |
|---|---|---|
| committer | 2024-01-30 02:22:45 -0500 | |
| commit | 9ba9780a96a67191cd7f12f34b343c77668b1831 (patch) | |
| tree | f1b80cc4f203199ee2c273bdd62bd2276f37ec53 /src | |
| parent | Merge pull request #12846 from german77/mii_const (diff) | |
| download | yuzu-9ba9780a96a67191cd7f12f34b343c77668b1831.tar.gz yuzu-9ba9780a96a67191cd7f12f34b343c77668b1831.tar.xz yuzu-9ba9780a96a67191cd7f12f34b343c77668b1831.zip | |
cmif_serialization: fix out layout calculation
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/cmif_serialization.h | 50 |
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 | ||
| 125 | template <ArgumentType Type1, ArgumentType Type2, typename MethodArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t ArgIndex = 0> | 125 | template <typename MethodArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t ArgIndex = 0> |
| 126 | constexpr u32 GetArgumentRawDataSize() { | 126 | constexpr 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 | |||
| 148 | template <typename MethodArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t ArgIndex = 0> | ||
| 149 | constexpr 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; |