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.
master
Lioncash 2018-10-13 14:31:46 +07:00
parent 1584fb6b38
commit 1c7a7ed79b
3 changed files with 50 additions and 4 deletions

@ -24,6 +24,7 @@ class ProgramMetadata;
namespace Kernel { namespace Kernel {
class KernelCore; class KernelCore;
class ResourceLimit;
struct AddressMapping { struct AddressMapping {
// Address and size must be page-aligned // 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). BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000).
}; };
enum class ProcessStatus { Created, Running, Exited }; /**
* Indicates the status of a Process instance.
class ResourceLimit; *
* @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 CodeSet final {
struct Segment { struct Segment {

@ -1092,6 +1092,29 @@ static ResultCode ClearEvent(Handle handle) {
return RESULT_SUCCESS; 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>(process_handle);
if (!process) {
return ERR_INVALID_HANDLE;
}
const auto info_type = static_cast<InfoType>(type);
if (info_type != InfoType::Status) {
return ERR_INVALID_ENUM_VALUE;
}
*out = static_cast<u64>(process->GetStatus());
return RESULT_SUCCESS;
}
namespace { namespace {
struct FunctionDef { struct FunctionDef {
using Func = void(); using Func = void();
@ -1227,7 +1250,7 @@ static const FunctionDef SVC_Table[] = {
{0x79, nullptr, "CreateProcess"}, {0x79, nullptr, "CreateProcess"},
{0x7A, nullptr, "StartProcess"}, {0x7A, nullptr, "StartProcess"},
{0x7B, nullptr, "TerminateProcess"}, {0x7B, nullptr, "TerminateProcess"},
{0x7C, nullptr, "GetProcessInfo"}, {0x7C, SvcWrap<GetProcessInfo>, "GetProcessInfo"},
{0x7D, nullptr, "CreateResourceLimit"}, {0x7D, nullptr, "CreateResourceLimit"},
{0x7E, nullptr, "SetResourceLimitLimitValue"}, {0x7E, nullptr, "SetResourceLimitLimitValue"},
{0x7F, nullptr, "CallSecureMonitor"}, {0x7F, nullptr, "CallSecureMonitor"},

@ -77,6 +77,14 @@ void SvcWrap() {
FuncReturn(retval); FuncReturn(retval);
} }
template <ResultCode func(u64*, u32, u32)>
void SvcWrap() {
u64 param_1 = 0;
u32 retval = func(&param_1, static_cast<u32>(Param(1)), static_cast<u32>(Param(2))).raw;
Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval);
}
template <ResultCode func(u32, u64)> template <ResultCode func(u32, u64)>
void SvcWrap() { void SvcWrap() {
FuncReturn(func(static_cast<u32>(Param(0)), Param(1)).raw); FuncReturn(func(static_cast<u32>(Param(0)), Param(1)).raw);