From 1c7a7ed79ba55c5fdefd729b12d6b8aa86a0779b Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 13 Oct 2018 14:31:46 -0400 Subject: [PATCH] svc: Implement svcGetProcessInfo A fairly basic service function, which only appears to currently support retrieving the process state. This also alters the ProcessStatus enum to contain all of the values that a kernel process seems to be able of reporting with regards to state. --- src/core/hle/kernel/process.h | 21 ++++++++++++++++++--- src/core/hle/kernel/svc.cpp | 25 ++++++++++++++++++++++++- src/core/hle/kernel/svc_wrap.h | 8 ++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 73ec01e119..f2816943a2 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -24,6 +24,7 @@ class ProgramMetadata; namespace Kernel { class KernelCore; +class ResourceLimit; struct AddressMapping { // Address and size must be page-aligned @@ -57,9 +58,23 @@ union ProcessFlags { BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000). }; -enum class ProcessStatus { Created, Running, Exited }; - -class ResourceLimit; +/** + * Indicates the status of a Process instance. + * + * @note These match the values as used by kernel, + * so new entries should only be added if RE + * shows that a new value has been introduced. + */ +enum class ProcessStatus { + Created, + CreatedWithDebuggerAttached, + Running, + WaitingForDebuggerToAttach, + DebuggerAttached, + Exiting, + Exited, + DebugBreak, +}; struct CodeSet final { struct Segment { diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index e406df829b..d9d919e181 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1092,6 +1092,29 @@ static ResultCode ClearEvent(Handle handle) { return RESULT_SUCCESS; } +static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) { + LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type); + + // This function currently only allows retrieving a process' status. + enum class InfoType { + Status, + }; + + const auto& kernel = Core::System::GetInstance().Kernel(); + const auto process = kernel.HandleTable().Get(process_handle); + if (!process) { + return ERR_INVALID_HANDLE; + } + + const auto info_type = static_cast(type); + if (info_type != InfoType::Status) { + return ERR_INVALID_ENUM_VALUE; + } + + *out = static_cast(process->GetStatus()); + return RESULT_SUCCESS; +} + namespace { struct FunctionDef { using Func = void(); @@ -1227,7 +1250,7 @@ static const FunctionDef SVC_Table[] = { {0x79, nullptr, "CreateProcess"}, {0x7A, nullptr, "StartProcess"}, {0x7B, nullptr, "TerminateProcess"}, - {0x7C, nullptr, "GetProcessInfo"}, + {0x7C, SvcWrap, "GetProcessInfo"}, {0x7D, nullptr, "CreateResourceLimit"}, {0x7E, nullptr, "SetResourceLimitLimitValue"}, {0x7F, nullptr, "CallSecureMonitor"}, diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index cbb80c3c49..b09753c80d 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h @@ -77,6 +77,14 @@ void SvcWrap() { FuncReturn(retval); } +template +void SvcWrap() { + u64 param_1 = 0; + u32 retval = func(¶m_1, static_cast(Param(1)), static_cast(Param(2))).raw; + Core::CurrentArmInterface().SetReg(1, param_1); + FuncReturn(retval); +} + template void SvcWrap() { FuncReturn(func(static_cast(Param(0)), Param(1)).raw);