From b6947f8d6de2dc8d50913bfa6dd0a7a30b99d8cd Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 18 Dec 2018 22:16:53 -0500 Subject: [PATCH 1/6] kernel/process: Make process_id a 64-bit value In the actual kernel, this is a 64-bit value, so we shouldn't be using a 32-bit type to handle it. --- src/core/hle/kernel/kernel.cpp | 4 ++-- src/core/hle/kernel/kernel.h | 2 +- src/core/hle/kernel/process.h | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index e441c5bc6a..a221734c10 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -155,7 +155,7 @@ struct KernelCore::Impl { std::atomic next_object_id{0}; // TODO(Subv): Start the process ids from 10 for now, as lower PIDs are // reserved for low-level services - std::atomic next_process_id{10}; + std::atomic next_process_id{10}; std::atomic next_thread_id{1}; // Lists all processes that exist in the current session. @@ -246,7 +246,7 @@ u32 KernelCore::CreateNewThreadID() { return impl->next_thread_id++; } -u32 KernelCore::CreateNewProcessID() { +u64 KernelCore::CreateNewProcessID() { return impl->next_process_id++; } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index ea00c89f59..4f0f2331c8 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -88,7 +88,7 @@ private: u32 CreateNewObjectID(); /// Creates a new process ID, incrementing the internal process ID counter; - u32 CreateNewProcessID(); + u64 CreateNewProcessID(); /// Creates a new thread ID, incrementing the internal thread ID counter. u32 CreateNewThreadID(); diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 459eedfa6d..725bfa01a4 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -162,7 +162,7 @@ public: } /// Gets the unique ID that identifies this particular process. - u32 GetProcessID() const { + u64 GetProcessID() const { return process_id; } @@ -288,10 +288,10 @@ private: ProcessStatus status; /// The ID of this process - u32 process_id = 0; + u64 process_id = 0; /// Title ID corresponding to the process - u64 program_id; + u64 program_id = 0; /// Resource limit descriptor for this process SharedPtr resource_limit; From 7755331f46b28bd60a9b284d9105ff9b1725f49a Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 18 Dec 2018 22:30:53 -0500 Subject: [PATCH 2/6] kernel/svc: Correct output parameter for svcGetProcessId svcGetProcessId's out parameter is a pointer to a 64-bit value, not a 32-bit one. --- src/core/hle/kernel/svc.cpp | 2 +- src/core/hle/kernel/svc_wrap.h | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 348a229047..c8b60b16c1 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -365,7 +365,7 @@ static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { } /// Get the ID of the specified process -static ResultCode GetProcessId(u32* process_id, Handle process_handle) { +static ResultCode GetProcessId(u64* process_id, Handle process_handle) { LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle); const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index 2f758b959b..2a2c2c5ead 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h @@ -73,7 +73,15 @@ void SvcWrap() { template void SvcWrap() { u32 param_1 = 0; - u32 retval = func(¶m_1, Param(1)).raw; + const u32 retval = func(¶m_1, Param(1)).raw; + Core::CurrentArmInterface().SetReg(1, param_1); + FuncReturn(retval); +} + +template +void SvcWrap() { + u64 param_1 = 0; + const u32 retval = func(¶m_1, static_cast(Param(1))).raw; Core::CurrentArmInterface().SetReg(1, param_1); FuncReturn(retval); } From bf75c5f45cc8e8abfaf26c8ceb484e60270b2a24 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 18 Dec 2018 22:37:01 -0500 Subject: [PATCH 3/6] kernel/thread: Make thread_id a 64-bit value The kernel uses a 64-bit value for the thread ID, so we shouldn't be using a 32-bit value. --- src/core/gdbstub/gdbstub.cpp | 4 ++-- src/core/hle/kernel/kernel.cpp | 4 ++-- src/core/hle/kernel/kernel.h | 2 +- src/core/hle/kernel/thread.h | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index e6b5171eed..a1cad4fcb4 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -201,11 +201,11 @@ void RegisterModule(std::string name, VAddr beg, VAddr end, bool add_elf_ext) { modules.push_back(std::move(module)); } -static Kernel::Thread* FindThreadById(int id) { +static Kernel::Thread* FindThreadById(s64 id) { for (u32 core = 0; core < Core::NUM_CPU_CORES; core++) { const auto& threads = Core::System::GetInstance().Scheduler(core).GetThreadList(); for (auto& thread : threads) { - if (thread->GetThreadID() == static_cast(id)) { + if (thread->GetThreadID() == static_cast(id)) { current_core = core; return thread.get(); } diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index a221734c10..2be39fb52b 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -156,7 +156,7 @@ struct KernelCore::Impl { // TODO(Subv): Start the process ids from 10 for now, as lower PIDs are // reserved for low-level services std::atomic next_process_id{10}; - std::atomic next_thread_id{1}; + std::atomic next_thread_id{1}; // Lists all processes that exist in the current session. std::vector> process_list; @@ -242,7 +242,7 @@ u32 KernelCore::CreateNewObjectID() { return impl->next_object_id++; } -u32 KernelCore::CreateNewThreadID() { +u64 KernelCore::CreateNewThreadID() { return impl->next_thread_id++; } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 4f0f2331c8..58c9d108b9 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -91,7 +91,7 @@ private: u64 CreateNewProcessID(); /// Creates a new thread ID, incrementing the internal thread ID counter. - u32 CreateNewThreadID(); + u64 CreateNewThreadID(); /// Creates a timer callback handle for the given timer. ResultVal CreateTimerCallbackHandle(const SharedPtr& timer); diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 77aec099ae..d6e7981d3c 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -151,7 +151,7 @@ public: * Gets the thread's thread ID * @return The thread's ID */ - u32 GetThreadID() const { + u64 GetThreadID() const { return thread_id; } @@ -379,7 +379,7 @@ private: Core::ARM_Interface::ThreadContext context{}; - u32 thread_id = 0; + u64 thread_id = 0; ThreadStatus status = ThreadStatus::Dormant; From 60661a4fd97a6542a7aeb04285cee10445da68a4 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 18 Dec 2018 22:38:22 -0500 Subject: [PATCH 4/6] kernel/svc: Correct output parameter for svcGetThreadId The service call uses a 64-bit value, just like svcGetProcessId. This amends the function signature accordingly. --- src/core/hle/kernel/svc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index c8b60b16c1..bcc9864f3f 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -350,7 +350,7 @@ static ResultCode SendSyncRequest(Handle handle) { } /// Get the ID for the specified thread. -static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { +static ResultCode GetThreadId(u64* thread_id, Handle thread_handle) { LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); From d15a67cd163d8567be388a57407d144eb5a0fb4e Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 18 Dec 2018 22:53:58 -0500 Subject: [PATCH 5/6] kernel/kernel: Use correct initial PID for userland Process instances Starts the process ID counter off at 81, which is what the kernel itself checks against internally when creating processes. It's actually supposed to panic if the PID is less than 81 for a userland process. --- src/core/hle/kernel/kernel.cpp | 6 ++---- src/core/hle/kernel/process.h | 12 ++++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 2be39fb52b..1c2290651e 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -112,7 +112,7 @@ struct KernelCore::Impl { void Shutdown() { next_object_id = 0; - next_process_id = 10; + next_process_id = Process::ProcessIDMin; next_thread_id = 1; process_list.clear(); @@ -153,9 +153,7 @@ struct KernelCore::Impl { } std::atomic next_object_id{0}; - // TODO(Subv): Start the process ids from 10 for now, as lower PIDs are - // reserved for low-level services - std::atomic next_process_id{10}; + std::atomic next_process_id{Process::ProcessIDMin}; std::atomic next_thread_id{1}; // Lists all processes that exist in the current session. diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 725bfa01a4..7da367251f 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -120,6 +120,18 @@ struct CodeSet final { class Process final : public WaitObject { public: + enum : u64 { + /// Lowest allowed process ID for a kernel initial process. + InitialKIPIDMin = 1, + /// Highest allowed process ID for a kernel initial process. + InitialKIPIDMax = 80, + + /// Lowest allowed process ID for a userland process. + ProcessIDMin = 81, + /// Highest allowed process ID for a userland process. + ProcessIDMax = 0xFFFFFFFFFFFFFFFF, + }; + static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4; static SharedPtr Create(KernelCore& kernel, std::string&& name); From 9a15fbc6732283d39b9f38bb1298eb72b56a44c3 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 18 Dec 2018 23:09:08 -0500 Subject: [PATCH 6/6] kernel/svc: Handle thread handles within GetProcessId If a thread handle is passed to svcGetProcessId, the kernel attempts to access the process ID via the thread's instance's owning process. Technically, this function should also be handling the kernel debug objects as well, however we currently don't handle those kernel objects yet, so I've left a note via a comment about it to remind myself when implementing it in the future. --- src/core/hle/kernel/svc.cpp | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index bcc9864f3f..0303330776 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -364,20 +364,33 @@ static ResultCode GetThreadId(u64* thread_id, Handle thread_handle) { return RESULT_SUCCESS; } -/// Get the ID of the specified process -static ResultCode GetProcessId(u64* process_id, Handle process_handle) { - LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle); +/// Gets the ID of the specified process or a specified thread's owning process. +static ResultCode GetProcessId(u64* process_id, Handle handle) { + LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle); const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); - const SharedPtr process = handle_table.Get(process_handle); - if (!process) { - LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", - process_handle); - return ERR_INVALID_HANDLE; + const SharedPtr process = handle_table.Get(handle); + if (process) { + *process_id = process->GetProcessID(); + return RESULT_SUCCESS; } - *process_id = process->GetProcessID(); - return RESULT_SUCCESS; + const SharedPtr thread = handle_table.Get(handle); + if (thread) { + const Process* const owner_process = thread->GetOwnerProcess(); + if (!owner_process) { + LOG_ERROR(Kernel_SVC, "Non-existent owning process encountered."); + return ERR_INVALID_HANDLE; + } + + *process_id = owner_process->GetProcessID(); + return RESULT_SUCCESS; + } + + // NOTE: This should also handle debug objects before returning. + + LOG_ERROR(Kernel_SVC, "Handle does not exist, handle=0x{:08X}", handle); + return ERR_INVALID_HANDLE; } /// Default thread wakeup callback for WaitSynchronization