diff options
| author | 2021-05-18 19:52:52 -0700 | |
|---|---|---|
| committer | 2021-05-20 21:41:52 -0700 | |
| commit | f4fe71c1c9e5f0c2eaa159f676efea3ae1953a22 (patch) | |
| tree | c4c9818c0e443e514c774f35e8e3dff3ebb23e4c /src | |
| parent | common: tree: Avoid a crash on nullptr dereference. (diff) | |
| download | yuzu-f4fe71c1c9e5f0c2eaa159f676efea3ae1953a22.tar.gz yuzu-f4fe71c1c9e5f0c2eaa159f676efea3ae1953a22.tar.xz yuzu-f4fe71c1c9e5f0c2eaa159f676efea3ae1953a22.zip | |
hle: kernel: hle_ipc: Simplify incoming/outgoing move/copy/domain objects.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/ipc_helpers.h | 20 | ||||
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 16 | ||||
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.h | 43 |
3 files changed, 17 insertions, 62 deletions
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 963f3db30..61bda3786 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h | |||
| @@ -80,8 +80,6 @@ public: | |||
| 80 | 80 | ||
| 81 | memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH); | 81 | memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH); |
| 82 | 82 | ||
| 83 | ctx.ClearIncomingObjects(); | ||
| 84 | |||
| 85 | IPC::CommandHeader header{}; | 83 | IPC::CommandHeader header{}; |
| 86 | 84 | ||
| 87 | // The entire size of the raw data section in u32 units, including the 16 bytes of mandatory | 85 | // The entire size of the raw data section in u32 units, including the 16 bytes of mandatory |
| @@ -170,24 +168,6 @@ public: | |||
| 170 | PushIpcInterface<T>(std::make_shared<T>(std::forward<Args>(args)...)); | 168 | PushIpcInterface<T>(std::make_shared<T>(std::forward<Args>(args)...)); |
| 171 | } | 169 | } |
| 172 | 170 | ||
| 173 | void ValidateHeader() { | ||
| 174 | const std::size_t num_domain_objects = context->NumDomainObjects(); | ||
| 175 | const std::size_t num_move_objects = context->NumMoveObjects(); | ||
| 176 | ASSERT_MSG(!num_domain_objects || !num_move_objects, | ||
| 177 | "cannot move normal handles and domain objects"); | ||
| 178 | ASSERT_MSG((index - data_payload_index) == normal_params_size, | ||
| 179 | "normal_params_size value is incorrect"); | ||
| 180 | ASSERT_MSG((num_domain_objects + num_move_objects) == num_objects_to_move, | ||
| 181 | "num_objects_to_move value is incorrect"); | ||
| 182 | ASSERT_MSG(context->NumCopyObjects() == num_handles_to_copy, | ||
| 183 | "num_handles_to_copy value is incorrect"); | ||
| 184 | } | ||
| 185 | |||
| 186 | // Validate on destruction, as there shouldn't be any case where we don't want it | ||
| 187 | ~ResponseBuilder() { | ||
| 188 | ValidateHeader(); | ||
| 189 | } | ||
| 190 | |||
| 191 | void PushImpl(s8 value); | 171 | void PushImpl(s8 value); |
| 192 | void PushImpl(s16 value); | 172 | void PushImpl(s16 value); |
| 193 | void PushImpl(s32 value); | 173 | void PushImpl(s32 value); |
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 689f58cf6..9d069a78f 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -69,14 +69,10 @@ void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32 | |||
| 69 | if (incoming) { | 69 | if (incoming) { |
| 70 | // Populate the object lists with the data in the IPC request. | 70 | // Populate the object lists with the data in the IPC request. |
| 71 | for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) { | 71 | for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) { |
| 72 | const u32 copy_handle{rp.Pop<Handle>()}; | 72 | incoming_copy_handles.push_back(rp.Pop<Handle>()); |
| 73 | copy_handles.push_back(copy_handle); | ||
| 74 | copy_objects.push_back(handle_table.GetObject(copy_handle).GetPointerUnsafe()); | ||
| 75 | } | 73 | } |
| 76 | for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) { | 74 | for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) { |
| 77 | const u32 move_handle{rp.Pop<Handle>()}; | 75 | incoming_move_handles.push_back(rp.Pop<Handle>()); |
| 78 | move_handles.push_back(move_handle); | ||
| 79 | move_objects.push_back(handle_table.GetObject(move_handle).GetPointerUnsafe()); | ||
| 80 | } | 76 | } |
| 81 | } else { | 77 | } else { |
| 82 | // For responses we just ignore the handles, they're empty and will be populated when | 78 | // For responses we just ignore the handles, they're empty and will be populated when |
| @@ -186,14 +182,14 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(KThread& requesting_t | |||
| 186 | auto& owner_process = *requesting_thread.GetOwnerProcess(); | 182 | auto& owner_process = *requesting_thread.GetOwnerProcess(); |
| 187 | auto& handle_table = owner_process.GetHandleTable(); | 183 | auto& handle_table = owner_process.GetHandleTable(); |
| 188 | 184 | ||
| 189 | for (auto& object : copy_objects) { | 185 | for (auto& object : outgoing_copy_objects) { |
| 190 | Handle handle{}; | 186 | Handle handle{}; |
| 191 | if (object) { | 187 | if (object) { |
| 192 | R_TRY(handle_table.Add(&handle, object)); | 188 | R_TRY(handle_table.Add(&handle, object)); |
| 193 | } | 189 | } |
| 194 | cmd_buf[current_offset++] = handle; | 190 | cmd_buf[current_offset++] = handle; |
| 195 | } | 191 | } |
| 196 | for (auto& object : move_objects) { | 192 | for (auto& object : outgoing_move_objects) { |
| 197 | Handle handle{}; | 193 | Handle handle{}; |
| 198 | if (object) { | 194 | if (object) { |
| 199 | R_TRY(handle_table.Add(&handle, object)); | 195 | R_TRY(handle_table.Add(&handle, object)); |
| @@ -208,8 +204,8 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(KThread& requesting_t | |||
| 208 | // TODO(Subv): This completely ignores C buffers. | 204 | // TODO(Subv): This completely ignores C buffers. |
| 209 | 205 | ||
| 210 | if (Session()->IsDomain()) { | 206 | if (Session()->IsDomain()) { |
| 211 | current_offset = domain_offset - static_cast<u32>(domain_objects.size()); | 207 | current_offset = domain_offset - static_cast<u32>(outgoing_domain_objects.size()); |
| 212 | for (const auto& object : domain_objects) { | 208 | for (const auto& object : outgoing_domain_objects) { |
| 213 | server_session->AppendDomainHandler(object); | 209 | server_session->AppendDomainHandler(object); |
| 214 | cmd_buf[current_offset++] = | 210 | cmd_buf[current_offset++] = |
| 215 | static_cast<u32_le>(server_session->NumDomainRequestHandlers()); | 211 | static_cast<u32_le>(server_session->NumDomainRequestHandlers()); |
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 51cd1a898..b47e363cc 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h | |||
| @@ -11,7 +11,6 @@ | |||
| 11 | #include <string> | 11 | #include <string> |
| 12 | #include <type_traits> | 12 | #include <type_traits> |
| 13 | #include <vector> | 13 | #include <vector> |
| 14 | #include <boost/container/small_vector.hpp> | ||
| 15 | 14 | ||
| 16 | #include "common/assert.h" | 15 | #include "common/assert.h" |
| 17 | #include "common/common_types.h" | 16 | #include "common/common_types.h" |
| @@ -289,23 +288,23 @@ public: | |||
| 289 | bool CanWriteBuffer(std::size_t buffer_index = 0) const; | 288 | bool CanWriteBuffer(std::size_t buffer_index = 0) const; |
| 290 | 289 | ||
| 291 | Handle GetCopyHandle(std::size_t index) const { | 290 | Handle GetCopyHandle(std::size_t index) const { |
| 292 | return copy_handles.at(index); | 291 | return incoming_copy_handles.at(index); |
| 293 | } | 292 | } |
| 294 | 293 | ||
| 295 | Handle GetMoveHandle(std::size_t index) const { | 294 | Handle GetMoveHandle(std::size_t index) const { |
| 296 | return move_handles.at(index); | 295 | return incoming_move_handles.at(index); |
| 297 | } | 296 | } |
| 298 | 297 | ||
| 299 | void AddMoveObject(KAutoObject* object) { | 298 | void AddMoveObject(KAutoObject* object) { |
| 300 | move_objects.emplace_back(object); | 299 | outgoing_move_objects.emplace_back(object); |
| 301 | } | 300 | } |
| 302 | 301 | ||
| 303 | void AddCopyObject(KAutoObject* object) { | 302 | void AddCopyObject(KAutoObject* object) { |
| 304 | copy_objects.emplace_back(object); | 303 | outgoing_copy_objects.emplace_back(object); |
| 305 | } | 304 | } |
| 306 | 305 | ||
| 307 | void AddDomainObject(SessionRequestHandlerPtr object) { | 306 | void AddDomainObject(SessionRequestHandlerPtr object) { |
| 308 | domain_objects.emplace_back(std::move(object)); | 307 | outgoing_domain_objects.emplace_back(std::move(object)); |
| 309 | } | 308 | } |
| 310 | 309 | ||
| 311 | template <typename T> | 310 | template <typename T> |
| @@ -317,26 +316,6 @@ public: | |||
| 317 | manager = std::move(manager_); | 316 | manager = std::move(manager_); |
| 318 | } | 317 | } |
| 319 | 318 | ||
| 320 | /// Clears the list of objects so that no lingering objects are written accidentally to the | ||
| 321 | /// response buffer. | ||
| 322 | void ClearIncomingObjects() { | ||
| 323 | move_objects.clear(); | ||
| 324 | copy_objects.clear(); | ||
| 325 | domain_objects.clear(); | ||
| 326 | } | ||
| 327 | |||
| 328 | std::size_t NumMoveObjects() const { | ||
| 329 | return move_objects.size(); | ||
| 330 | } | ||
| 331 | |||
| 332 | std::size_t NumCopyObjects() const { | ||
| 333 | return copy_objects.size(); | ||
| 334 | } | ||
| 335 | |||
| 336 | std::size_t NumDomainObjects() const { | ||
| 337 | return domain_objects.size(); | ||
| 338 | } | ||
| 339 | |||
| 340 | std::string Description() const; | 319 | std::string Description() const; |
| 341 | 320 | ||
| 342 | KThread& GetThread() { | 321 | KThread& GetThread() { |
| @@ -356,12 +335,12 @@ private: | |||
| 356 | Kernel::KServerSession* server_session{}; | 335 | Kernel::KServerSession* server_session{}; |
| 357 | KThread* thread; | 336 | KThread* thread; |
| 358 | 337 | ||
| 359 | // TODO(yuriks): Check common usage of this and optimize size accordingly | 338 | std::vector<Handle> incoming_move_handles; |
| 360 | boost::container::small_vector<Handle, 8> move_handles; | 339 | std::vector<Handle> incoming_copy_handles; |
| 361 | boost::container::small_vector<Handle, 8> copy_handles; | 340 | |
| 362 | boost::container::small_vector<KAutoObject*, 8> move_objects; | 341 | std::vector<KAutoObject*> outgoing_move_objects; |
| 363 | boost::container::small_vector<KAutoObject*, 8> copy_objects; | 342 | std::vector<KAutoObject*> outgoing_copy_objects; |
| 364 | boost::container::small_vector<SessionRequestHandlerPtr, 8> domain_objects; | 343 | std::vector<SessionRequestHandlerPtr> outgoing_domain_objects; |
| 365 | 344 | ||
| 366 | std::optional<IPC::CommandHeader> command_header; | 345 | std::optional<IPC::CommandHeader> command_header; |
| 367 | std::optional<IPC::HandleDescriptorHeader> handle_descriptor_header; | 346 | std::optional<IPC::HandleDescriptorHeader> handle_descriptor_header; |