1
0
Fork 0
forked from suyu/suyu

Merge pull request #1540 from lioncash/handle

kernel/process: Make the handle table per-process
This commit is contained in:
bunnei 2018-10-23 18:43:11 -04:00 committed by GitHub
commit e61a62066a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 97 additions and 100 deletions

View file

@ -77,7 +77,8 @@ HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_ses
HLERequestContext::~HLERequestContext() = default; HLERequestContext::~HLERequestContext() = default;
void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) { void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf,
bool incoming) {
IPC::RequestParser rp(src_cmdbuf); IPC::RequestParser rp(src_cmdbuf);
command_header = std::make_shared<IPC::CommandHeader>(rp.PopRaw<IPC::CommandHeader>()); command_header = std::make_shared<IPC::CommandHeader>(rp.PopRaw<IPC::CommandHeader>());
@ -94,8 +95,6 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
rp.Skip(2, false); rp.Skip(2, false);
} }
if (incoming) { if (incoming) {
auto& handle_table = Core::System::GetInstance().Kernel().HandleTable();
// Populate the object lists with the data in the IPC request. // Populate the object lists with the data in the IPC request.
for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) { for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) {
copy_objects.push_back(handle_table.GetGeneric(rp.Pop<Handle>())); copy_objects.push_back(handle_table.GetGeneric(rp.Pop<Handle>()));
@ -189,10 +188,9 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
rp.Skip(1, false); // The command is actually an u64, but we don't use the high part. rp.Skip(1, false); // The command is actually an u64, but we don't use the high part.
} }
ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(u32_le* src_cmdbuf, ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const HandleTable& handle_table,
Process& src_process, u32_le* src_cmdbuf) {
HandleTable& src_table) { ParseCommandBuffer(handle_table, src_cmdbuf, true);
ParseCommandBuffer(src_cmdbuf, true);
if (command_header->type == IPC::CommandType::Close) { if (command_header->type == IPC::CommandType::Close) {
// Close does not populate the rest of the IPC header // Close does not populate the rest of the IPC header
return RESULT_SUCCESS; return RESULT_SUCCESS;
@ -207,14 +205,17 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(u32_le* src_cmdb
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(const Thread& thread) { ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) {
auto& owner_process = *thread.GetOwnerProcess();
auto& handle_table = owner_process.GetHandleTable();
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> dst_cmdbuf; std::array<u32, IPC::COMMAND_BUFFER_LENGTH> dst_cmdbuf;
Memory::ReadBlock(*thread.GetOwnerProcess(), thread.GetTLSAddress(), dst_cmdbuf.data(), Memory::ReadBlock(owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(),
dst_cmdbuf.size() * sizeof(u32)); dst_cmdbuf.size() * sizeof(u32));
// The header was already built in the internal command buffer. Attempt to parse it to verify // The header was already built in the internal command buffer. Attempt to parse it to verify
// the integrity and then copy it over to the target command buffer. // the integrity and then copy it over to the target command buffer.
ParseCommandBuffer(cmd_buf.data(), false); ParseCommandBuffer(handle_table, cmd_buf.data(), false);
// The data_size already includes the payload header, the padding and the domain header. // The data_size already includes the payload header, the padding and the domain header.
std::size_t size = data_payload_offset + command_header->data_size - std::size_t size = data_payload_offset + command_header->data_size -
@ -236,8 +237,6 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(const Thread& thread)
ASSERT(copy_objects.size() == handle_descriptor_header->num_handles_to_copy); ASSERT(copy_objects.size() == handle_descriptor_header->num_handles_to_copy);
ASSERT(move_objects.size() == handle_descriptor_header->num_handles_to_move); ASSERT(move_objects.size() == handle_descriptor_header->num_handles_to_move);
auto& handle_table = Core::System::GetInstance().Kernel().HandleTable();
// We don't make a distinction between copy and move handles when translating since HLE // We don't make a distinction between copy and move handles when translating since HLE
// services don't deal with handles directly. However, the guest applications might check // services don't deal with handles directly. However, the guest applications might check
// for specific values in each of these descriptors. // for specific values in each of these descriptors.
@ -268,7 +267,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(const Thread& thread)
} }
// Copy the translated command buffer back into the thread's command buffer area. // Copy the translated command buffer back into the thread's command buffer area.
Memory::WriteBlock(*thread.GetOwnerProcess(), thread.GetTLSAddress(), dst_cmdbuf.data(), Memory::WriteBlock(owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(),
dst_cmdbuf.size() * sizeof(u32)); dst_cmdbuf.size() * sizeof(u32));
return RESULT_SUCCESS; return RESULT_SUCCESS;

View file

@ -24,10 +24,10 @@ class ServiceFrameworkBase;
namespace Kernel { namespace Kernel {
class Domain; class Domain;
class Event;
class HandleTable; class HandleTable;
class HLERequestContext; class HLERequestContext;
class Process; class Process;
class Event;
/** /**
* Interface implemented by HLE Session handlers. * Interface implemented by HLE Session handlers.
@ -126,13 +126,12 @@ public:
u64 timeout, WakeupCallback&& callback, u64 timeout, WakeupCallback&& callback,
Kernel::SharedPtr<Kernel::Event> event = nullptr); Kernel::SharedPtr<Kernel::Event> event = nullptr);
void ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming);
/// Populates this context with data from the requesting process/thread. /// Populates this context with data from the requesting process/thread.
ResultCode PopulateFromIncomingCommandBuffer(u32_le* src_cmdbuf, Process& src_process, ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table,
HandleTable& src_table); u32_le* src_cmdbuf);
/// Writes data from this context back to the requesting process/thread. /// Writes data from this context back to the requesting process/thread.
ResultCode WriteToOutgoingCommandBuffer(const Thread& thread); ResultCode WriteToOutgoingCommandBuffer(Thread& thread);
u32_le GetCommand() const { u32_le GetCommand() const {
return command; return command;
@ -255,6 +254,8 @@ public:
std::string Description() const; std::string Description() const;
private: private:
void ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, bool incoming);
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
SharedPtr<Kernel::ServerSession> server_session; SharedPtr<Kernel::ServerSession> server_session;
// TODO(yuriks): Check common usage of this and optimize size accordingly // TODO(yuriks): Check common usage of this and optimize size accordingly

View file

@ -118,7 +118,6 @@ struct KernelCore::Impl {
process_list.clear(); process_list.clear();
current_process = nullptr; current_process = nullptr;
handle_table.Clear();
resource_limits.fill(nullptr); resource_limits.fill(nullptr);
thread_wakeup_callback_handle_table.Clear(); thread_wakeup_callback_handle_table.Clear();
@ -209,7 +208,6 @@ struct KernelCore::Impl {
std::vector<SharedPtr<Process>> process_list; std::vector<SharedPtr<Process>> process_list;
Process* current_process = nullptr; Process* current_process = nullptr;
Kernel::HandleTable handle_table;
std::array<SharedPtr<ResourceLimit>, 4> resource_limits; std::array<SharedPtr<ResourceLimit>, 4> resource_limits;
/// The event type of the generic timer callback event /// The event type of the generic timer callback event
@ -241,14 +239,6 @@ void KernelCore::Shutdown() {
impl->Shutdown(); impl->Shutdown();
} }
Kernel::HandleTable& KernelCore::HandleTable() {
return impl->handle_table;
}
const Kernel::HandleTable& KernelCore::HandleTable() const {
return impl->handle_table;
}
SharedPtr<ResourceLimit> KernelCore::ResourceLimitForCategory( SharedPtr<ResourceLimit> KernelCore::ResourceLimitForCategory(
ResourceLimitCategory category) const { ResourceLimitCategory category) const {
return impl->resource_limits.at(static_cast<std::size_t>(category)); return impl->resource_limits.at(static_cast<std::size_t>(category));

View file

@ -47,12 +47,6 @@ public:
/// Clears all resources in use by the kernel instance. /// Clears all resources in use by the kernel instance.
void Shutdown(); void Shutdown();
/// Provides a reference to the handle table.
Kernel::HandleTable& HandleTable();
/// Provides a const reference to the handle table.
const Kernel::HandleTable& HandleTable() const;
/// Retrieves a shared pointer to a ResourceLimit identified by the given category. /// Retrieves a shared pointer to a ResourceLimit identified by the given category.
SharedPtr<ResourceLimit> ResourceLimitForCategory(ResourceLimitCategory category) const; SharedPtr<ResourceLimit> ResourceLimitForCategory(ResourceLimitCategory category) const;

View file

@ -13,6 +13,7 @@
#include <boost/container/static_vector.hpp> #include <boost/container/static_vector.hpp>
#include "common/bit_field.h" #include "common/bit_field.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/object.h" #include "core/hle/kernel/object.h"
#include "core/hle/kernel/thread.h" #include "core/hle/kernel/thread.h"
#include "core/hle/kernel/vm_manager.h" #include "core/hle/kernel/vm_manager.h"
@ -142,6 +143,16 @@ public:
return vm_manager; return vm_manager;
} }
/// Gets a reference to the process' handle table.
HandleTable& GetHandleTable() {
return handle_table;
}
/// Gets a const reference to the process' handle table.
const HandleTable& GetHandleTable() const {
return handle_table;
}
/// Gets the current status of the process /// Gets the current status of the process
ProcessStatus GetStatus() const { ProcessStatus GetStatus() const {
return status; return status;
@ -294,6 +305,9 @@ private:
/// specified by metadata provided to the process during loading. /// specified by metadata provided to the process during loading.
bool is_64bit_process = true; bool is_64bit_process = true;
/// Per-process handle table for storing created object handles in.
HandleTable handle_table;
std::string name; std::string name;
}; };

View file

@ -107,8 +107,7 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
// similar. // similar.
Kernel::HLERequestContext context(this); Kernel::HLERequestContext context(this);
u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress()); u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress());
context.PopulateFromIncomingCommandBuffer(cmd_buf, *Core::CurrentProcess(), context.PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
kernel.HandleTable());
ResultCode result = RESULT_SUCCESS; ResultCode result = RESULT_SUCCESS;
// If the session has been converted to a domain, handle the domain request // If the session has been converted to a domain, handle the domain request

View file

@ -189,14 +189,15 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address
CASCADE_RESULT(client_session, client_port->Connect()); CASCADE_RESULT(client_session, client_port->Connect());
// Return the client session // Return the client session
CASCADE_RESULT(*out_handle, kernel.HandleTable().Create(client_session)); auto& handle_table = Core::CurrentProcess()->GetHandleTable();
CASCADE_RESULT(*out_handle, handle_table.Create(client_session));
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
/// Makes a blocking IPC call to an OS service. /// Makes a blocking IPC call to an OS service.
static ResultCode SendSyncRequest(Handle handle) { static ResultCode SendSyncRequest(Handle handle) {
auto& kernel = Core::System::GetInstance().Kernel(); const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
SharedPtr<ClientSession> session = kernel.HandleTable().Get<ClientSession>(handle); SharedPtr<ClientSession> session = handle_table.Get<ClientSession>(handle);
if (!session) { if (!session) {
LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle); LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle);
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
@ -215,8 +216,8 @@ static ResultCode SendSyncRequest(Handle handle) {
static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) {
LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
auto& kernel = Core::System::GetInstance().Kernel(); const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle); const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
if (!thread) { if (!thread) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
@ -229,8 +230,8 @@ static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) {
static ResultCode GetProcessId(u32* process_id, Handle process_handle) { static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle); LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle);
auto& kernel = Core::System::GetInstance().Kernel(); const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
const SharedPtr<Process> process = kernel.HandleTable().Get<Process>(process_handle); const SharedPtr<Process> process = handle_table.Get<Process>(process_handle);
if (!process) { if (!process) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
@ -273,11 +274,11 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64
using ObjectPtr = Thread::ThreadWaitObjects::value_type; using ObjectPtr = Thread::ThreadWaitObjects::value_type;
Thread::ThreadWaitObjects objects(handle_count); Thread::ThreadWaitObjects objects(handle_count);
auto& kernel = Core::System::GetInstance().Kernel(); const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
for (u64 i = 0; i < handle_count; ++i) { for (u64 i = 0; i < handle_count; ++i) {
const Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); const Handle handle = Memory::Read32(handles_address + i * sizeof(Handle));
const auto object = kernel.HandleTable().Get<WaitObject>(handle); const auto object = handle_table.Get<WaitObject>(handle);
if (object == nullptr) { if (object == nullptr) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
@ -325,8 +326,8 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64
static ResultCode CancelSynchronization(Handle thread_handle) { static ResultCode CancelSynchronization(Handle thread_handle) {
LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle); LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle);
auto& kernel = Core::System::GetInstance().Kernel(); const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle); const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
if (!thread) { if (!thread) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
@ -354,7 +355,7 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr,
return ERR_INVALID_ADDRESS; return ERR_INVALID_ADDRESS;
} }
auto& handle_table = Core::System::GetInstance().Kernel().HandleTable(); auto& handle_table = Core::CurrentProcess()->GetHandleTable();
return Mutex::TryAcquire(handle_table, mutex_addr, holding_thread_handle, return Mutex::TryAcquire(handle_table, mutex_addr, holding_thread_handle,
requesting_thread_handle); requesting_thread_handle);
} }
@ -499,13 +500,12 @@ static ResultCode SetThreadActivity(Handle handle, u32 unknown) {
static ResultCode GetThreadContext(VAddr thread_context, Handle handle) { static ResultCode GetThreadContext(VAddr thread_context, Handle handle) {
LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle); LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle);
auto& kernel = Core::System::GetInstance().Kernel(); const auto* current_process = Core::CurrentProcess();
const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(handle); const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
if (!thread) { if (!thread) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
const auto* current_process = Core::CurrentProcess();
if (thread->GetOwnerProcess() != current_process) { if (thread->GetOwnerProcess() != current_process) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
@ -531,10 +531,11 @@ static ResultCode GetThreadContext(VAddr thread_context, Handle handle) {
/// Gets the priority for the specified thread /// Gets the priority for the specified thread
static ResultCode GetThreadPriority(u32* priority, Handle handle) { static ResultCode GetThreadPriority(u32* priority, Handle handle) {
auto& kernel = Core::System::GetInstance().Kernel(); const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(handle); const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle);
if (!thread) if (!thread) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
}
*priority = thread->GetPriority(); *priority = thread->GetPriority();
return RESULT_SUCCESS; return RESULT_SUCCESS;
@ -546,14 +547,15 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
return ERR_INVALID_THREAD_PRIORITY; return ERR_INVALID_THREAD_PRIORITY;
} }
auto& kernel = Core::System::GetInstance().Kernel(); const auto* const current_process = Core::CurrentProcess();
SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(handle); SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
if (!thread) if (!thread) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
}
// Note: The kernel uses the current process's resource limit instead of // Note: The kernel uses the current process's resource limit instead of
// the one from the thread owner's resource limit. // the one from the thread owner's resource limit.
const ResourceLimit& resource_limit = Core::CurrentProcess()->GetResourceLimit(); const ResourceLimit& resource_limit = current_process->GetResourceLimit();
if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) { if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) {
return ERR_NOT_AUTHORIZED; return ERR_NOT_AUTHORIZED;
} }
@ -595,15 +597,13 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
return ERR_INVALID_MEMORY_PERMISSIONS; return ERR_INVALID_MEMORY_PERMISSIONS;
} }
auto& kernel = Core::System::GetInstance().Kernel(); auto* const current_process = Core::CurrentProcess();
auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle); auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle);
if (!shared_memory) { if (!shared_memory) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
auto* const current_process = Core::CurrentProcess();
const auto& vm_manager = current_process->VMManager(); const auto& vm_manager = current_process->VMManager();
if (!vm_manager.IsWithinASLRRegion(addr, size)) { if (!vm_manager.IsWithinASLRRegion(addr, size)) {
return ERR_INVALID_MEMORY_RANGE; return ERR_INVALID_MEMORY_RANGE;
} }
@ -627,15 +627,13 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64
return ERR_INVALID_ADDRESS_STATE; return ERR_INVALID_ADDRESS_STATE;
} }
auto& kernel = Core::System::GetInstance().Kernel(); auto* const current_process = Core::CurrentProcess();
auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle); auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle);
if (!shared_memory) { if (!shared_memory) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
auto* const current_process = Core::CurrentProcess();
const auto& vm_manager = current_process->VMManager(); const auto& vm_manager = current_process->VMManager();
if (!vm_manager.IsWithinASLRRegion(addr, size)) { if (!vm_manager.IsWithinASLRRegion(addr, size)) {
return ERR_INVALID_MEMORY_RANGE; return ERR_INVALID_MEMORY_RANGE;
} }
@ -646,9 +644,8 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64
/// Query process memory /// Query process memory
static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/, static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/,
Handle process_handle, u64 addr) { Handle process_handle, u64 addr) {
const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
auto& kernel = Core::System::GetInstance().Kernel(); SharedPtr<Process> process = handle_table.Get<Process>(process_handle);
SharedPtr<Process> process = kernel.HandleTable().Get<Process>(process_handle);
if (!process) { if (!process) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
@ -695,20 +692,19 @@ static void ExitProcess() {
/// Creates a new thread /// Creates a new thread
static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top,
u32 priority, s32 processor_id) { u32 priority, s32 processor_id) {
std::string name = fmt::format("thread-{:X}", entry_point);
if (priority > THREADPRIO_LOWEST) { if (priority > THREADPRIO_LOWEST) {
return ERR_INVALID_THREAD_PRIORITY; return ERR_INVALID_THREAD_PRIORITY;
} }
const ResourceLimit& resource_limit = Core::CurrentProcess()->GetResourceLimit(); auto* const current_process = Core::CurrentProcess();
const ResourceLimit& resource_limit = current_process->GetResourceLimit();
if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) { if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) {
return ERR_NOT_AUTHORIZED; return ERR_NOT_AUTHORIZED;
} }
if (processor_id == THREADPROCESSORID_DEFAULT) { if (processor_id == THREADPROCESSORID_DEFAULT) {
// Set the target CPU to the one specified in the process' exheader. // Set the target CPU to the one specified in the process' exheader.
processor_id = Core::CurrentProcess()->GetDefaultProcessorID(); processor_id = current_process->GetDefaultProcessorID();
ASSERT(processor_id != THREADPROCESSORID_DEFAULT); ASSERT(processor_id != THREADPROCESSORID_DEFAULT);
} }
@ -723,11 +719,13 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
return ERR_INVALID_PROCESSOR_ID; return ERR_INVALID_PROCESSOR_ID;
} }
const std::string name = fmt::format("thread-{:X}", entry_point);
auto& kernel = Core::System::GetInstance().Kernel(); auto& kernel = Core::System::GetInstance().Kernel();
CASCADE_RESULT(SharedPtr<Thread> thread, CASCADE_RESULT(SharedPtr<Thread> thread,
Thread::Create(kernel, name, entry_point, priority, arg, processor_id, stack_top, Thread::Create(kernel, name, entry_point, priority, arg, processor_id, stack_top,
*Core::CurrentProcess())); *current_process));
const auto new_guest_handle = kernel.HandleTable().Create(thread);
const auto new_guest_handle = current_process->GetHandleTable().Create(thread);
if (new_guest_handle.Failed()) { if (new_guest_handle.Failed()) {
return new_guest_handle.Code(); return new_guest_handle.Code();
} }
@ -748,8 +746,8 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
static ResultCode StartThread(Handle thread_handle) { static ResultCode StartThread(Handle thread_handle) {
LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
auto& kernel = Core::System::GetInstance().Kernel(); const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle); const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
if (!thread) { if (!thread) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
@ -796,8 +794,8 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
"called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle=0x{:08X}, timeout={}", "called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle=0x{:08X}, timeout={}",
mutex_addr, condition_variable_addr, thread_handle, nano_seconds); mutex_addr, condition_variable_addr, thread_handle, nano_seconds);
auto& kernel = Core::System::GetInstance().Kernel(); const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle); SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
ASSERT(thread); ASSERT(thread);
CASCADE_CODE(Mutex::Release(mutex_addr)); CASCADE_CODE(Mutex::Release(mutex_addr));
@ -908,9 +906,9 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
mutex_val | Mutex::MutexHasWaitersFlag)); mutex_val | Mutex::MutexHasWaitersFlag));
// The mutex is already owned by some other thread, make this thread wait on it. // The mutex is already owned by some other thread, make this thread wait on it.
auto& kernel = Core::System::GetInstance().Kernel(); const Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask);
Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask); const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
auto owner = kernel.HandleTable().Get<Thread>(owner_handle); auto owner = handle_table.Get<Thread>(owner_handle);
ASSERT(owner); ASSERT(owner);
ASSERT(thread->GetStatus() == ThreadStatus::WaitMutex); ASSERT(thread->GetStatus() == ThreadStatus::WaitMutex);
thread->InvalidateWakeupCallback(); thread->InvalidateWakeupCallback();
@ -989,16 +987,16 @@ static u64 GetSystemTick() {
static ResultCode CloseHandle(Handle handle) { static ResultCode CloseHandle(Handle handle) {
LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle);
auto& kernel = Core::System::GetInstance().Kernel(); auto& handle_table = Core::CurrentProcess()->GetHandleTable();
return kernel.HandleTable().Close(handle); return handle_table.Close(handle);
} }
/// Reset an event /// Reset an event
static ResultCode ResetSignal(Handle handle) { static ResultCode ResetSignal(Handle handle) {
LOG_WARNING(Kernel_SVC, "(STUBBED) called handle 0x{:08X}", handle); LOG_WARNING(Kernel_SVC, "(STUBBED) called handle 0x{:08X}", handle);
auto& kernel = Core::System::GetInstance().Kernel(); const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
auto event = kernel.HandleTable().Get<Event>(handle); auto event = handle_table.Get<Event>(handle);
ASSERT(event != nullptr); ASSERT(event != nullptr);
@ -1017,8 +1015,8 @@ static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32
static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) { static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) {
LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle);
auto& kernel = Core::System::GetInstance().Kernel(); const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle); const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
if (!thread) { if (!thread) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
@ -1033,8 +1031,8 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:16X}, core=0x{:X}", thread_handle, LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:16X}, core=0x{:X}", thread_handle,
mask, core); mask, core);
auto& kernel = Core::System::GetInstance().Kernel(); const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle); const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
if (!thread) { if (!thread) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
@ -1095,7 +1093,7 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss
} }
auto& kernel = Core::System::GetInstance().Kernel(); auto& kernel = Core::System::GetInstance().Kernel();
auto& handle_table = kernel.HandleTable(); auto& handle_table = Core::CurrentProcess()->GetHandleTable();
auto shared_mem_handle = auto shared_mem_handle =
SharedMemory::Create(kernel, handle_table.Get<Process>(KernelHandle::CurrentProcess), size, SharedMemory::Create(kernel, handle_table.Get<Process>(KernelHandle::CurrentProcess), size,
local_perms, remote_perms); local_perms, remote_perms);
@ -1107,10 +1105,12 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss
static ResultCode ClearEvent(Handle handle) { static ResultCode ClearEvent(Handle handle) {
LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle);
auto& kernel = Core::System::GetInstance().Kernel(); const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
SharedPtr<Event> evt = kernel.HandleTable().Get<Event>(handle); SharedPtr<Event> evt = handle_table.Get<Event>(handle);
if (evt == nullptr) if (evt == nullptr) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
}
evt->Clear(); evt->Clear();
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
@ -1123,8 +1123,8 @@ static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) {
Status, Status,
}; };
const auto& kernel = Core::System::GetInstance().Kernel(); const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
const auto process = kernel.HandleTable().Get<Process>(process_handle); const auto process = handle_table.Get<Process>(process_handle);
if (!process) { if (!process) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }

View file

@ -266,7 +266,7 @@ SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 pri
SharedPtr<Thread> thread = std::move(thread_res).Unwrap(); SharedPtr<Thread> thread = std::move(thread_res).Unwrap();
// Register 1 must be a handle to the main thread // Register 1 must be a handle to the main thread
const Handle guest_handle = kernel.HandleTable().Create(thread).Unwrap(); const Handle guest_handle = owner_process.GetHandleTable().Create(thread).Unwrap();
thread->SetGuestHandle(guest_handle); thread->SetGuestHandle(guest_handle);
thread->GetContext().cpu_registers[1] = guest_handle; thread->GetContext().cpu_registers[1] = guest_handle;

View file

@ -9,8 +9,8 @@
#include "core/core.h" #include "core/core.h"
#include "core/hle/kernel/event.h" #include "core/hle/kernel/event.h"
#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/mutex.h" #include "core/hle/kernel/mutex.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/scheduler.h"
#include "core/hle/kernel/thread.h" #include "core/hle/kernel/thread.h"
#include "core/hle/kernel/timer.h" #include "core/hle/kernel/timer.h"
@ -83,7 +83,7 @@ QString WaitTreeText::GetText() const {
} }
WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address) : mutex_address(mutex_address) { WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address) : mutex_address(mutex_address) {
auto& handle_table = Core::System::GetInstance().Kernel().HandleTable(); const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
mutex_value = Memory::Read32(mutex_address); mutex_value = Memory::Read32(mutex_address);
owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Mutex::MutexOwnerMask); owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Mutex::MutexOwnerMask);