From eb285c33fd2751b8f03afb5b8e207cfa6e4b17cc Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Fri, 19 Oct 2018 21:04:18 -0400 Subject: [PATCH] kernel: make handle table per-process --- src/core/hle/kernel/handle_table.cpp | 9 +- src/core/hle/kernel/handle_table.h | 6 +- src/core/hle/kernel/hle_ipc.cpp | 15 ++- src/core/hle/kernel/hle_ipc.h | 6 +- src/core/hle/kernel/ipc.cpp | 6 +- src/core/hle/kernel/kernel.cpp | 2 - src/core/hle/kernel/process.cpp | 3 +- src/core/hle/kernel/process.h | 3 + src/core/hle/kernel/svc.cpp | 167 +++++++++++++++++--------- src/core/hle/service/service.cpp | 4 +- src/tests/core/hle/kernel/hle_ipc.cpp | 67 ++++++----- 11 files changed, 169 insertions(+), 119 deletions(-) diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index 99b65fa93..87ba03f36 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp @@ -5,7 +5,6 @@ #include #include "common/assert.h" #include "common/logging/log.h" -#include "core/core.h" // TODO: for current_process. Remove this later #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/process.h" @@ -13,9 +12,7 @@ namespace Kernel { -HandleTable g_handle_table; - -HandleTable::HandleTable() { +HandleTable::HandleTable(KernelSystem& kernel) : kernel(kernel) { next_generation = 1; Clear(); } @@ -77,9 +74,7 @@ SharedPtr HandleTable::GetGeneric(Handle handle) const { if (handle == CurrentThread) { return GetCurrentThread(); } else if (handle == CurrentProcess) { - // TODO: should this return HandleTable's parent process, or kernel's current process? - // Should change this either way - return Core::System::GetInstance().Kernel().GetCurrentProcess(); + return kernel.GetCurrentProcess(); } if (!IsValid(handle)) { diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index 5497dd74a..00cb47a33 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h @@ -42,7 +42,7 @@ enum KernelHandle : Handle { */ class HandleTable final : NonCopyable { public: - HandleTable(); + explicit HandleTable(KernelSystem& kernel); /** * Allocates a handle for the given object. @@ -119,8 +119,8 @@ private: /// Head of the free slots linked list. u16 next_free_slot; + + KernelSystem& kernel; }; -extern HandleTable g_handle_table; - } // namespace Kernel diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 1da7c8a81..a72d33dd9 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -50,7 +50,7 @@ SharedPtr HLERequestContext::SleepClientThread(SharedPtr thread, std::array cmd_buff; Memory::ReadBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), cmd_buff.size() * sizeof(u32)); - context.WriteToOutgoingCommandBuffer(cmd_buff.data(), *process, Kernel::g_handle_table); + context.WriteToOutgoingCommandBuffer(cmd_buff.data(), *process); // Copy the translated command buffer back into the thread's command buffer area. Memory::WriteBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), cmd_buff.size() * sizeof(u32)); @@ -98,8 +98,7 @@ void HLERequestContext::AddStaticBuffer(u8 buffer_id, std::vector data) { } ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, - Process& src_process, - HandleTable& src_table) { + Process& src_process) { IPC::Header header{src_cmdbuf[0]}; std::size_t untranslated_size = 1u + header.normal_params_size; @@ -122,10 +121,10 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr Handle handle = src_cmdbuf[i]; SharedPtr object = nullptr; if (handle != 0) { - object = src_table.GetGeneric(handle); + object = src_process.handle_table.GetGeneric(handle); ASSERT(object != nullptr); // TODO(yuriks): Return error if (descriptor == IPC::DescriptorType::MoveHandle) { - src_table.Close(handle); + src_process.handle_table.Close(handle); } } @@ -163,8 +162,8 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr return RESULT_SUCCESS; } -ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process, - HandleTable& dst_table) const { +ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, + Process& dst_process) const { IPC::Header header{cmd_buf[0]}; std::size_t untranslated_size = 1u + header.normal_params_size; @@ -189,7 +188,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P Handle handle = 0; if (object != nullptr) { // TODO(yuriks): Figure out the proper error handling for if this fails - handle = dst_table.Create(object).Unwrap(); + handle = dst_process.handle_table.Create(object).Unwrap(); } dst_cmdbuf[i++] = handle; } diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 3a2b81b16..a41264834 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -226,11 +226,9 @@ public: MappedBuffer& GetMappedBuffer(u32 id_from_cmdbuf); /// Populates this context with data from the requesting process/thread. - ResultCode PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, Process& src_process, - HandleTable& src_table); + ResultCode PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, Process& src_process); /// Writes data from this context back to the requesting process/thread. - ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process, - HandleTable& dst_table) const; + ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process) const; private: std::array cmd_buf; diff --git a/src/core/hle/kernel/ipc.cpp b/src/core/hle/kernel/ipc.cpp index 8db9d241f..b50a2429f 100644 --- a/src/core/hle/kernel/ipc.cpp +++ b/src/core/hle/kernel/ipc.cpp @@ -60,9 +60,9 @@ ResultCode TranslateCommandBuffer(SharedPtr src_thread, SharedPtrhandle_table.GetGeneric(handle); if (descriptor == IPC::DescriptorType::MoveHandle) { - g_handle_table.Close(handle); + src_process->handle_table.Close(handle); } } @@ -73,7 +73,7 @@ ResultCode TranslateCommandBuffer(SharedPtr src_thread, SharedPtrhandle_table.Create(std::move(object)); cmd_buf[i++] = result.ValueOr(0); } break; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index bed63ff91..afe6af195 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -27,8 +27,6 @@ KernelSystem::KernelSystem(u32 system_mode) { /// Shutdown the kernel KernelSystem::~KernelSystem() { - g_handle_table.Clear(); // Free all kernel objects - Kernel::ThreadingShutdown(); Kernel::TimersShutdown(); diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index c6be6effc..21204eeb8 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -300,7 +300,8 @@ ResultCode Process::LinearFree(VAddr target, u32 size) { return RESULT_SUCCESS; } -Kernel::Process::Process(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} +Kernel::Process::Process(KernelSystem& kernel) + : Object(kernel), handle_table(kernel), kernel(kernel) {} Kernel::Process::~Process() {} SharedPtr KernelSystem::GetProcessById(u32 process_id) const { diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 762e0c0a1..fa04d8c42 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -13,6 +13,7 @@ #include #include "common/bit_field.h" #include "common/common_types.h" +#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/vm_manager.h" @@ -123,6 +124,8 @@ public: return HANDLE_TYPE; } + HandleTable handle_table; + SharedPtr codeset; /// Resource limit descriptor for this process SharedPtr resource_limit; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index b27ee5293..94a820f34 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -182,7 +182,9 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o "otherpermission={}", handle, addr, permissions, other_permissions); - SharedPtr shared_memory = g_handle_table.Get(handle); + SharedPtr shared_memory = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + handle); if (shared_memory == nullptr) return ERR_INVALID_HANDLE; @@ -211,12 +213,12 @@ static ResultCode UnmapMemoryBlock(Handle handle, u32 addr) { // TODO(Subv): Return E0A01BF5 if the address is not in the application's heap - SharedPtr shared_memory = g_handle_table.Get(handle); + SharedPtr current_process = Core::System::GetInstance().Kernel().GetCurrentProcess(); + SharedPtr shared_memory = current_process->handle_table.Get(handle); if (shared_memory == nullptr) return ERR_INVALID_HANDLE; - return shared_memory->Unmap(Core::System::GetInstance().Kernel().GetCurrentProcess().get(), - addr); + return shared_memory->Unmap(current_process.get(), addr); } /// Connect to an OS service given the port name, returns the handle to the port to out @@ -244,13 +246,17 @@ static ResultCode ConnectToPort(Handle* out_handle, VAddr port_name_address) { CASCADE_RESULT(client_session, client_port->Connect()); // Return the client session - CASCADE_RESULT(*out_handle, g_handle_table.Create(client_session)); + CASCADE_RESULT(*out_handle, + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Create( + client_session)); return RESULT_SUCCESS; } /// Makes a blocking IPC call to an OS service. static ResultCode SendSyncRequest(Handle handle) { - SharedPtr session = g_handle_table.Get(handle); + SharedPtr session = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + handle); if (session == nullptr) { return ERR_INVALID_HANDLE; } @@ -265,12 +271,14 @@ static ResultCode SendSyncRequest(Handle handle) { /// Close a handle static ResultCode CloseHandle(Handle handle) { LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); - return g_handle_table.Close(handle); + return Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Close(handle); } /// Wait for a handle to synchronize, timeout after the specified nanoseconds static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) { - auto object = g_handle_table.Get(handle); + auto object = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + handle); Thread* thread = GetCurrentThread(); if (object == nullptr) @@ -341,7 +349,9 @@ static ResultCode WaitSynchronizationN(s32* out, VAddr handles_address, s32 hand for (int i = 0; i < handle_count; ++i) { Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); - auto object = g_handle_table.Get(handle); + auto object = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + handle); if (object == nullptr) return ERR_INVALID_HANDLE; objects[i] = object; @@ -505,9 +515,11 @@ static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_ using ObjectPtr = SharedPtr; std::vector objects(handle_count); + SharedPtr current_process = Core::System::GetInstance().Kernel().GetCurrentProcess(); + for (int i = 0; i < handle_count; ++i) { Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); - auto object = g_handle_table.Get(handle); + auto object = current_process->handle_table.Get(handle); if (object == nullptr) return ERR_INVALID_HANDLE; objects[i] = object; @@ -518,7 +530,7 @@ static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_ u32* cmd_buff = GetCommandBuffer(); IPC::Header header{cmd_buff[0]}; if (reply_target != 0 && header.command_id != 0xFFFF) { - auto session = g_handle_table.Get(reply_target); + auto session = current_process->handle_table.Get(reply_target); if (session == nullptr) return ERR_INVALID_HANDLE; @@ -618,8 +630,10 @@ static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_ /// Create an address arbiter (to allocate access to shared resources) static ResultCode CreateAddressArbiter(Handle* out_handle) { - SharedPtr arbiter = Core::System::GetInstance().Kernel().CreateAddressArbiter(); - CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(arbiter))); + KernelSystem& kernel = Core::System::GetInstance().Kernel(); + SharedPtr arbiter = kernel.CreateAddressArbiter(); + CASCADE_RESULT(*out_handle, + kernel.GetCurrentProcess()->handle_table.Create(std::move(arbiter))); LOG_TRACE(Kernel_SVC, "returned handle=0x{:08X}", *out_handle); return RESULT_SUCCESS; } @@ -630,7 +644,9 @@ static ResultCode ArbitrateAddress(Handle handle, u32 address, u32 type, u32 val LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}, address=0x{:08X}, type=0x{:08X}, value=0x{:08X}", handle, address, type, value); - SharedPtr arbiter = g_handle_table.Get(handle); + SharedPtr arbiter = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + handle); if (arbiter == nullptr) return ERR_INVALID_HANDLE; @@ -678,11 +694,12 @@ static void OutputDebugString(VAddr address, int len) { static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle) { LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle); - SharedPtr process = g_handle_table.Get(process_handle); + SharedPtr current_process = Core::System::GetInstance().Kernel().GetCurrentProcess(); + SharedPtr process = current_process->handle_table.Get(process_handle); if (process == nullptr) return ERR_INVALID_HANDLE; - CASCADE_RESULT(*resource_limit, g_handle_table.Create(process->resource_limit)); + CASCADE_RESULT(*resource_limit, current_process->handle_table.Create(process->resource_limit)); return RESULT_SUCCESS; } @@ -694,7 +711,8 @@ static ResultCode GetResourceLimitCurrentValues(VAddr values, Handle resource_li resource_limit_handle, names, name_count); SharedPtr resource_limit = - g_handle_table.Get(resource_limit_handle); + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + resource_limit_handle); if (resource_limit == nullptr) return ERR_INVALID_HANDLE; @@ -714,7 +732,8 @@ static ResultCode GetResourceLimitLimitValues(VAddr values, Handle resource_limi resource_limit_handle, names, name_count); SharedPtr resource_limit = - g_handle_table.Get(resource_limit_handle); + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + resource_limit_handle); if (resource_limit == nullptr) return ERR_INVALID_HANDLE; @@ -773,7 +792,7 @@ static ResultCode CreateThread(Handle* out_handle, u32 priority, u32 entry_point thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO); // 0x03C00000 - CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(thread))); + CASCADE_RESULT(*out_handle, current_process->handle_table.Create(std::move(thread))); Core::System::GetInstance().PrepareReschedule(); @@ -795,7 +814,8 @@ static void ExitThread() { /// Gets the priority for the specified thread static ResultCode GetThreadPriority(u32* priority, Handle handle) { - const SharedPtr thread = g_handle_table.Get(handle); + const SharedPtr thread = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (thread == nullptr) return ERR_INVALID_HANDLE; @@ -809,7 +829,8 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { return ERR_OUT_OF_RANGE; } - SharedPtr thread = g_handle_table.Get(handle); + SharedPtr thread = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (thread == nullptr) return ERR_INVALID_HANDLE; @@ -834,9 +855,10 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { /// Create a mutex static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) { - SharedPtr mutex = Core::System::GetInstance().Kernel().CreateMutex(initial_locked != 0); + KernelSystem& kernel = Core::System::GetInstance().Kernel(); + SharedPtr mutex = kernel.CreateMutex(initial_locked != 0); mutex->name = fmt::format("mutex-{:08x}", Core::CPU().GetReg(14)); - CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(mutex))); + CASCADE_RESULT(*out_handle, kernel.GetCurrentProcess()->handle_table.Create(std::move(mutex))); LOG_TRACE(Kernel_SVC, "called initial_locked={} : created handle=0x{:08X}", initial_locked ? "true" : "false", *out_handle); @@ -848,7 +870,8 @@ static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) { static ResultCode ReleaseMutex(Handle handle) { LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}", handle); - SharedPtr mutex = g_handle_table.Get(handle); + SharedPtr mutex = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (mutex == nullptr) return ERR_INVALID_HANDLE; @@ -859,7 +882,9 @@ static ResultCode ReleaseMutex(Handle handle) { static ResultCode GetProcessId(u32* process_id, Handle process_handle) { LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle); - const SharedPtr process = g_handle_table.Get(process_handle); + const SharedPtr process = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + process_handle); if (process == nullptr) return ERR_INVALID_HANDLE; @@ -871,7 +896,9 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) { static ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle) { LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); - const SharedPtr thread = g_handle_table.Get(thread_handle); + const SharedPtr thread = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + thread_handle); if (thread == nullptr) return ERR_INVALID_HANDLE; @@ -887,7 +914,8 @@ static ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle) { static ResultCode GetThreadId(u32* thread_id, Handle handle) { LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", handle); - const SharedPtr thread = g_handle_table.Get(handle); + const SharedPtr thread = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (thread == nullptr) return ERR_INVALID_HANDLE; @@ -897,10 +925,12 @@ static ResultCode GetThreadId(u32* thread_id, Handle handle) { /// Creates a semaphore static ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max_count) { + KernelSystem& kernel = Core::System::GetInstance().Kernel(); CASCADE_RESULT(SharedPtr semaphore, - Core::System::GetInstance().Kernel().CreateSemaphore(initial_count, max_count)); + kernel.CreateSemaphore(initial_count, max_count)); semaphore->name = fmt::format("semaphore-{:08x}", Core::CPU().GetReg(14)); - CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(semaphore))); + CASCADE_RESULT(*out_handle, + kernel.GetCurrentProcess()->handle_table.Create(std::move(semaphore))); LOG_TRACE(Kernel_SVC, "called initial_count={}, max_count={}, created handle=0x{:08X}", initial_count, max_count, *out_handle); @@ -911,7 +941,9 @@ static ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max static ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { LOG_TRACE(Kernel_SVC, "called release_count={}, handle=0x{:08X}", release_count, handle); - SharedPtr semaphore = g_handle_table.Get(handle); + SharedPtr semaphore = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + handle); if (semaphore == nullptr) return ERR_INVALID_HANDLE; @@ -923,7 +955,9 @@ static ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) /// Query process memory static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* page_info, Handle process_handle, u32 addr) { - SharedPtr process = g_handle_table.Get(process_handle); + SharedPtr process = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + process_handle); if (process == nullptr) return ERR_INVALID_HANDLE; @@ -949,9 +983,10 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, u32 /// Create an event static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) { - SharedPtr evt = Core::System::GetInstance().Kernel().CreateEvent( - static_cast(reset_type), fmt::format("event-{:08x}", Core::CPU().GetReg(14))); - CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(evt))); + KernelSystem& kernel = Core::System::GetInstance().Kernel(); + SharedPtr evt = kernel.CreateEvent(static_cast(reset_type), + fmt::format("event-{:08x}", Core::CPU().GetReg(14))); + CASCADE_RESULT(*out_handle, kernel.GetCurrentProcess()->handle_table.Create(std::move(evt))); LOG_TRACE(Kernel_SVC, "called reset_type=0x{:08X} : created handle=0x{:08X}", reset_type, *out_handle); @@ -960,7 +995,9 @@ static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) { /// Duplicates a kernel handle static ResultCode DuplicateHandle(Handle* out, Handle handle) { - CASCADE_RESULT(*out, g_handle_table.Duplicate(handle)); + CASCADE_RESULT( + *out, + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Duplicate(handle)); LOG_TRACE(Kernel_SVC, "duplicated 0x{:08X} to 0x{:08X}", handle, *out); return RESULT_SUCCESS; } @@ -969,7 +1006,8 @@ static ResultCode DuplicateHandle(Handle* out, Handle handle) { static ResultCode SignalEvent(Handle handle) { LOG_TRACE(Kernel_SVC, "called event=0x{:08X}", handle); - SharedPtr evt = g_handle_table.Get(handle); + SharedPtr evt = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (evt == nullptr) return ERR_INVALID_HANDLE; @@ -982,7 +1020,8 @@ static ResultCode SignalEvent(Handle handle) { static ResultCode ClearEvent(Handle handle) { LOG_TRACE(Kernel_SVC, "called event=0x{:08X}", handle); - SharedPtr evt = g_handle_table.Get(handle); + SharedPtr evt = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (evt == nullptr) return ERR_INVALID_HANDLE; @@ -992,9 +1031,10 @@ static ResultCode ClearEvent(Handle handle) { /// Creates a timer static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) { - SharedPtr timer = Core::System::GetInstance().Kernel().CreateTimer( + KernelSystem& kernel = Core::System::GetInstance().Kernel(); + SharedPtr timer = kernel.CreateTimer( static_cast(reset_type), fmt ::format("timer-{:08x}", Core::CPU().GetReg(14))); - CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(timer))); + CASCADE_RESULT(*out_handle, kernel.GetCurrentProcess()->handle_table.Create(std::move(timer))); LOG_TRACE(Kernel_SVC, "called reset_type=0x{:08X} : created handle=0x{:08X}", reset_type, *out_handle); @@ -1005,7 +1045,8 @@ static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) { static ResultCode ClearTimer(Handle handle) { LOG_TRACE(Kernel_SVC, "called timer=0x{:08X}", handle); - SharedPtr timer = g_handle_table.Get(handle); + SharedPtr timer = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (timer == nullptr) return ERR_INVALID_HANDLE; @@ -1021,7 +1062,8 @@ static ResultCode SetTimer(Handle handle, s64 initial, s64 interval) { return ERR_OUT_OF_RANGE_KERNEL; } - SharedPtr timer = g_handle_table.Get(handle); + SharedPtr timer = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (timer == nullptr) return ERR_INVALID_HANDLE; @@ -1034,7 +1076,8 @@ static ResultCode SetTimer(Handle handle, s64 initial, s64 interval) { static ResultCode CancelTimer(Handle handle) { LOG_TRACE(Kernel_SVC, "called timer=0x{:08X}", handle); - SharedPtr timer = g_handle_table.Get(handle); + SharedPtr timer = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (timer == nullptr) return ERR_INVALID_HANDLE; @@ -1116,7 +1159,7 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 shared_memory = Core::System::GetInstance().Kernel().CreateSharedMemory( current_process, size, static_cast(my_permission), static_cast(other_permission), addr, region); - CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(shared_memory))); + CASCADE_RESULT(*out_handle, current_process->handle_table.Create(std::move(shared_memory))); LOG_WARNING(Kernel_SVC, "called addr=0x{:08X}", addr); return RESULT_SUCCESS; @@ -1127,48 +1170,58 @@ static ResultCode CreatePort(Handle* server_port, Handle* client_port, VAddr nam // TODO(Subv): Implement named ports. ASSERT_MSG(name_address == 0, "Named ports are currently unimplemented"); - auto ports = Core::System::GetInstance().Kernel().CreatePortPair(max_sessions); - CASCADE_RESULT(*client_port, - g_handle_table.Create(std::move(std::get>(ports)))); + KernelSystem& kernel = Core::System::GetInstance().Kernel(); + SharedPtr current_process = kernel.GetCurrentProcess(); + + auto ports = kernel.CreatePortPair(max_sessions); + CASCADE_RESULT(*client_port, current_process->handle_table.Create( + std::move(std::get>(ports)))); // Note: The 3DS kernel also leaks the client port handle if the server port handle fails to be // created. - CASCADE_RESULT(*server_port, - g_handle_table.Create(std::move(std::get>(ports)))); + CASCADE_RESULT(*server_port, current_process->handle_table.Create( + std::move(std::get>(ports)))); LOG_TRACE(Kernel_SVC, "called max_sessions={}", max_sessions); return RESULT_SUCCESS; } static ResultCode CreateSessionToPort(Handle* out_client_session, Handle client_port_handle) { - SharedPtr client_port = g_handle_table.Get(client_port_handle); + SharedPtr current_process = Core::System::GetInstance().Kernel().GetCurrentProcess(); + SharedPtr client_port = + current_process->handle_table.Get(client_port_handle); if (client_port == nullptr) return ERR_INVALID_HANDLE; CASCADE_RESULT(auto session, client_port->Connect()); - CASCADE_RESULT(*out_client_session, g_handle_table.Create(std::move(session))); + CASCADE_RESULT(*out_client_session, current_process->handle_table.Create(std::move(session))); return RESULT_SUCCESS; } static ResultCode CreateSession(Handle* server_session, Handle* client_session) { - auto sessions = Core::System::GetInstance().Kernel().CreateSessionPair(); + KernelSystem& kernel = Core::System::GetInstance().Kernel(); + auto sessions = kernel.CreateSessionPair(); + + SharedPtr current_process = kernel.GetCurrentProcess(); auto& server = std::get>(sessions); - CASCADE_RESULT(*server_session, g_handle_table.Create(std::move(server))); + CASCADE_RESULT(*server_session, current_process->handle_table.Create(std::move(server))); auto& client = std::get>(sessions); - CASCADE_RESULT(*client_session, g_handle_table.Create(std::move(client))); + CASCADE_RESULT(*client_session, current_process->handle_table.Create(std::move(client))); LOG_TRACE(Kernel_SVC, "called"); return RESULT_SUCCESS; } static ResultCode AcceptSession(Handle* out_server_session, Handle server_port_handle) { - SharedPtr server_port = g_handle_table.Get(server_port_handle); + SharedPtr current_process = Core::System::GetInstance().Kernel().GetCurrentProcess(); + SharedPtr server_port = + current_process->handle_table.Get(server_port_handle); if (server_port == nullptr) return ERR_INVALID_HANDLE; CASCADE_RESULT(auto session, server_port->Accept()); - CASCADE_RESULT(*out_server_session, g_handle_table.Create(std::move(session))); + CASCADE_RESULT(*out_server_session, current_process->handle_table.Create(std::move(session))); return RESULT_SUCCESS; } @@ -1218,7 +1271,9 @@ static ResultCode GetSystemInfo(s64* out, u32 type, s32 param) { static ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type) { LOG_TRACE(Kernel_SVC, "called process=0x{:08X} type={}", process_handle, type); - SharedPtr process = g_handle_table.Get(process_handle); + SharedPtr process = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + process_handle); if (process == nullptr) return ERR_INVALID_HANDLE; diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 117bf2b2c..1217376b1 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -194,7 +194,7 @@ void ServiceFrameworkBase::HandleSyncRequest(SharedPtr server_ses // TODO(yuriks): The kernel should be the one handling this as part of translation after // everything else is migrated Kernel::HLERequestContext context(std::move(server_session)); - context.PopulateFromIncomingCommandBuffer(cmd_buf, *current_process, Kernel::g_handle_table); + context.PopulateFromIncomingCommandBuffer(cmd_buf, *current_process); LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName().c_str(), cmd_buf)); handler_invoker(this, info->handler_callback, context); @@ -206,7 +206,7 @@ void ServiceFrameworkBase::HandleSyncRequest(SharedPtr server_ses // the thread to sleep then the writing of the command buffer will be deferred to the wakeup // callback. if (thread->status == Kernel::ThreadStatus::Running) { - context.WriteToOutgoingCommandBuffer(cmd_buf, *current_process, Kernel::g_handle_table); + context.WriteToOutgoingCommandBuffer(cmd_buf, *current_process); } } diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index 9e093f4e4..068d767b6 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -26,14 +26,13 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel HLERequestContext context(std::move(session)); auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); - HandleTable handle_table; SECTION("works with empty cmdbuf") { const u32_le input[]{ IPC::MakeHeader(0x1234, 0, 0), }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); REQUIRE(context.CommandBuffer()[0] == 0x12340000); } @@ -46,7 +45,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel 0xAABBCCDD, }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); auto* output = context.CommandBuffer(); REQUIRE(output[1] == 0x12345678); @@ -56,34 +55,34 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel SECTION("translates move handles") { auto a = MakeObject(kernel); - Handle a_handle = handle_table.Create(a).Unwrap(); + Handle a_handle = process->handle_table.Create(a).Unwrap(); const u32_le input[]{ IPC::MakeHeader(0, 0, 2), IPC::MoveHandleDesc(1), a_handle, }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); auto* output = context.CommandBuffer(); REQUIRE(context.GetIncomingHandle(output[2]) == a); - REQUIRE(handle_table.GetGeneric(a_handle) == nullptr); + REQUIRE(process->handle_table.GetGeneric(a_handle) == nullptr); } SECTION("translates copy handles") { auto a = MakeObject(kernel); - Handle a_handle = handle_table.Create(a).Unwrap(); + Handle a_handle = process->handle_table.Create(a).Unwrap(); const u32_le input[]{ IPC::MakeHeader(0, 0, 2), IPC::CopyHandleDesc(1), a_handle, }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); auto* output = context.CommandBuffer(); REQUIRE(context.GetIncomingHandle(output[2]) == a); - REQUIRE(handle_table.GetGeneric(a_handle) == a); + REQUIRE(process->handle_table.GetGeneric(a_handle) == a); } SECTION("translates multi-handle descriptors") { @@ -91,12 +90,15 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel auto b = MakeObject(kernel); auto c = MakeObject(kernel); const u32_le input[]{ - IPC::MakeHeader(0, 0, 5), IPC::MoveHandleDesc(2), - handle_table.Create(a).Unwrap(), handle_table.Create(b).Unwrap(), - IPC::MoveHandleDesc(1), handle_table.Create(c).Unwrap(), + IPC::MakeHeader(0, 0, 5), + IPC::MoveHandleDesc(2), + process->handle_table.Create(a).Unwrap(), + process->handle_table.Create(b).Unwrap(), + IPC::MoveHandleDesc(1), + process->handle_table.Create(c).Unwrap(), }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); auto* output = context.CommandBuffer(); REQUIRE(context.GetIncomingHandle(output[2]) == a); @@ -111,7 +113,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel 0, }; - auto result = context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + auto result = context.PopulateFromIncomingCommandBuffer(input, *process); REQUIRE(result == RESULT_SUCCESS); auto* output = context.CommandBuffer(); @@ -125,7 +127,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel 0x98989898, }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); REQUIRE(context.CommandBuffer()[2] == process->process_id); } @@ -145,7 +147,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel target_address, }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); CHECK(context.GetStaticBuffer(0) == *buffer); @@ -166,7 +168,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel target_address, }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); std::vector other_buffer(buffer->size()); context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer->size()); @@ -199,7 +201,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel 0x12345678, 0xABCDEF00, IPC::MoveHandleDesc(1), - handle_table.Create(a).Unwrap(), + process->handle_table.Create(a).Unwrap(), IPC::CallingPidDesc(), 0, IPC::StaticBufferDesc(buffer_static->size(), 0), @@ -208,7 +210,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel target_address_mapped, }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); auto* output = context.CommandBuffer(); CHECK(output[1] == 0x12345678); @@ -236,14 +238,13 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { HLERequestContext context(std::move(session)); auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); - HandleTable handle_table; auto* input = context.CommandBuffer(); u32_le output[IPC::COMMAND_BUFFER_LENGTH]; SECTION("works with empty cmdbuf") { input[0] = IPC::MakeHeader(0x1234, 0, 0); - context.WriteToOutgoingCommandBuffer(output, *process, handle_table); + context.WriteToOutgoingCommandBuffer(output, *process); REQUIRE(output[0] == 0x12340000); } @@ -254,7 +255,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { input[2] = 0x21122112; input[3] = 0xAABBCCDD; - context.WriteToOutgoingCommandBuffer(output, *process, handle_table); + context.WriteToOutgoingCommandBuffer(output, *process); REQUIRE(output[1] == 0x12345678); REQUIRE(output[2] == 0x21122112); @@ -270,10 +271,10 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { input[3] = IPC::CopyHandleDesc(1); input[4] = context.AddOutgoingHandle(b); - context.WriteToOutgoingCommandBuffer(output, *process, handle_table); + context.WriteToOutgoingCommandBuffer(output, *process); - REQUIRE(handle_table.GetGeneric(output[2]) == a); - REQUIRE(handle_table.GetGeneric(output[4]) == b); + REQUIRE(process->handle_table.GetGeneric(output[2]) == a); + REQUIRE(process->handle_table.GetGeneric(output[4]) == b); } SECTION("translates null handles") { @@ -281,7 +282,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { input[1] = IPC::MoveHandleDesc(1); input[2] = context.AddOutgoingHandle(nullptr); - auto result = context.WriteToOutgoingCommandBuffer(output, *process, handle_table); + auto result = context.WriteToOutgoingCommandBuffer(output, *process); REQUIRE(result == RESULT_SUCCESS); REQUIRE(output[2] == 0); @@ -298,11 +299,11 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { input[4] = IPC::CopyHandleDesc(1); input[5] = context.AddOutgoingHandle(c); - context.WriteToOutgoingCommandBuffer(output, *process, handle_table); + context.WriteToOutgoingCommandBuffer(output, *process); - REQUIRE(handle_table.GetGeneric(output[2]) == a); - REQUIRE(handle_table.GetGeneric(output[3]) == b); - REQUIRE(handle_table.GetGeneric(output[5]) == c); + REQUIRE(process->handle_table.GetGeneric(output[2]) == a); + REQUIRE(process->handle_table.GetGeneric(output[3]) == b); + REQUIRE(process->handle_table.GetGeneric(output[5]) == c); } SECTION("translates StaticBuffer descriptors") { @@ -329,7 +330,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { IPC::StaticBufferDesc(output_buffer->size(), 0); output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH + 1] = target_address; - context.WriteToOutgoingCommandBuffer(output_cmdbuff.data(), *process, handle_table); + context.WriteToOutgoingCommandBuffer(output_cmdbuff.data(), *process); CHECK(*output_buffer == input_buffer); REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer->size()) == @@ -352,7 +353,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { target_address, }; - context.PopulateFromIncomingCommandBuffer(input_cmdbuff, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input_cmdbuff, *process); context.GetMappedBuffer(0).Write(input_buffer.data(), 0, input_buffer.size()); @@ -360,7 +361,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { input[1] = IPC::MappedBufferDesc(output_buffer->size(), IPC::W); input[2] = 0; - context.WriteToOutgoingCommandBuffer(output, *process, handle_table); + context.WriteToOutgoingCommandBuffer(output, *process); CHECK(output[1] == IPC::MappedBufferDesc(output_buffer->size(), IPC::W)); CHECK(output[2] == target_address);