From 9b3a38e3d331b2fb647cd7286dad51d7051bdf64 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 e441c5bc6..a221734c1 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 ea00c89f5..4f0f2331c 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 459eedfa6..725bfa01a 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 43e1189688a948e167ade54fdf2ba4007289aefd 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 348a22904..c8b60b16c 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 2f758b959..2a2c2c5ea 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 8435451093b193c1a1556a9edadc5663d3372b02 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 e6b5171ee..a1cad4fcb 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 a221734c1..2be39fb52 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 4f0f2331c..58c9d108b 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 77aec099a..d6e7981d3 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 0906302ca92332c8928c3a896e66d85d229fadb9 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 c8b60b16c..bcc9864f3 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 62d437705367421a1b919922f1ecf3c4a43d75c5 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 2be39fb52..1c2290651 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 725bfa01a..7da367251 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 b74eb88c68e85d08695667eaf4603bb565c8eb64 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 bcc9864f3..030333077 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