From 40f6b5b3ac5f9fb61440d941d5f529823a1cf5f4 Mon Sep 17 00:00:00 2001 From: Gliniak Date: Thu, 5 Jan 2023 22:51:18 +0100 Subject: [PATCH] [Kernel] Improvements to host and guest objects handling --- src/xenia/kernel/util/object_table.cc | 30 +++++++++++++++------------ src/xenia/kernel/util/object_table.h | 5 +---- src/xenia/kernel/xam/xam_net.cc | 2 +- src/xenia/kernel/xobject.h | 4 ++++ 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/xenia/kernel/util/object_table.cc b/src/xenia/kernel/util/object_table.cc index a95320710..4568c72d1 100644 --- a/src/xenia/kernel/util/object_table.cc +++ b/src/xenia/kernel/util/object_table.cc @@ -132,7 +132,13 @@ X_STATUS ObjectTable::AddHandle(XObject* object, X_HANDLE* out_handle) { entry.object = object; entry.handle_ref_count = 1; handle = slot << 2; - if (!host_object) handle += XObject::kHandleBase; + if (!host_object) { + if (object->type() != XObject::Type::Socket) { + handle += XObject::kHandleBase; + } + } else { + handle += XObject::kHandleHostBase; + } object->handles().push_back(handle); // Retain so long as the object is in the table. @@ -286,10 +292,9 @@ ObjectTable::ObjectTableEntry* ObjectTable::LookupTableInLock(X_HANDLE handle) { return nullptr; } - // Lower 2 bits are ignored. - bool host = (handle < XObject::kHandleBase); - uint32_t slot = GetHandleSlot(handle, host); - if (host) { + const bool is_host_object = XObject::is_handle_host_object(handle); + uint32_t slot = GetHandleSlot(handle, is_host_object); + if (is_host_object) { if (slot <= host_table_capacity_) { return &host_table_[slot]; } @@ -320,12 +325,11 @@ XObject* ObjectTable::LookupObject(X_HANDLE handle, bool already_locked) { global_critical_region_.mutex().lock(); } - // Lower 2 bits are ignored. - bool host = (handle < XObject::kHandleBase); - uint32_t slot = GetHandleSlot(handle, host); + const bool is_host_object = XObject::is_handle_host_object(handle); + uint32_t slot = GetHandleSlot(handle, is_host_object); // Verify slot. - if (host) { + if (is_host_object) { if (slot < host_table_capacity_) { ObjectTableEntry& entry = host_table_[slot]; if (entry.object) { @@ -461,13 +465,13 @@ bool ObjectTable::Restore(ByteStream* stream) { } X_STATUS ObjectTable::RestoreHandle(X_HANDLE handle, XObject* object) { - bool host = (handle < XObject::kHandleBase); - uint32_t slot = GetHandleSlot(handle, host); - uint32_t capacity = host ? host_table_capacity_ : table_capacity_; + const bool is_host_object = XObject::is_handle_host_object(handle); + uint32_t slot = GetHandleSlot(handle, is_host_object); + uint32_t capacity = is_host_object ? host_table_capacity_ : table_capacity_; assert_true(capacity >= slot); if (capacity >= slot) { - auto& entry = host ? host_table_[slot] : table_[slot]; + auto& entry = is_host_object ? host_table_[slot] : table_[slot]; entry.object = object; object->Retain(); } diff --git a/src/xenia/kernel/util/object_table.h b/src/xenia/kernel/util/object_table.h index 040d07d4e..ddeaa8a7b 100644 --- a/src/xenia/kernel/util/object_table.h +++ b/src/xenia/kernel/util/object_table.h @@ -49,9 +49,6 @@ class ObjectTable { X_STATUS RestoreHandle(X_HANDLE handle, XObject* object); template object_ref LookupObject(X_HANDLE handle, bool already_locked = false) { - if (T::kObjectType == XObject::Type::Socket) { - handle |= XObject::kHandleBase; - } auto object = LookupObject(handle, already_locked); if (object) { assert_true(object->type() == T::kObjectType); @@ -96,7 +93,7 @@ class ObjectTable { X_HANDLE TranslateHandle(X_HANDLE handle); static constexpr uint32_t GetHandleSlot(X_HANDLE handle, bool host) { - if (!host) handle -= XObject::kHandleBase; + handle &= host ? ~XObject::kHandleHostBase : ~XObject::kHandleBase; return handle >> 2; } X_STATUS FindFreeSlot(uint32_t* out_slot, bool host); diff --git a/src/xenia/kernel/xam/xam_net.cc b/src/xenia/kernel/xam/xam_net.cc index c126ed0aa..ae5cce6b2 100644 --- a/src/xenia/kernel/xam/xam_net.cc +++ b/src/xenia/kernel/xam/xam_net.cc @@ -639,7 +639,7 @@ dword_result_t NetDll_socket_entry(dword_t caller, dword_t af, dword_t type, return -1; } - return (socket->handle() & 0x00FFFFFF); + return socket->handle(); } DECLARE_XAM_EXPORT1(NetDll_socket, kNetworking, kImplemented); diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index 1647fa193..ad693fa79 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -117,6 +117,7 @@ class XObject { // Instead of receiving address that starts with 0x82... we're receiving // one with 0x8A... which causes crash static constexpr uint32_t kHandleBase = 0xF8000000; + static constexpr uint32_t kHandleHostBase = 0x01000000; enum class Type : uint32_t { Undefined, @@ -175,6 +176,9 @@ class XObject { static object_ref Restore(KernelState* kernel_state, Type type, ByteStream* stream); + static constexpr bool is_handle_host_object(X_HANDLE handle) { + return handle > XObject::kHandleHostBase && handle < XObject::kHandleBase; + }; // Reference() // Dereference()