diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/kernel/process.h | 21 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 31 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc_wrap.h | 8 | 
3 files changed, 56 insertions, 4 deletions
| diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 73ec01e11..f2816943a 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 e406df829..7a053da1e 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -389,6 +389,12 @@ static void Break(u32 reason, u64 info1, u64 info2) {              "Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}",              reason, info1, info2);          ASSERT(false); + +        Core::CurrentProcess()->PrepareForTermination(); + +        // Kill the current thread +        GetCurrentThread()->Stop(); +        Core::System::GetInstance().PrepareReschedule();      }  } @@ -1092,6 +1098,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>(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 {  struct FunctionDef {      using Func = void(); @@ -1227,7 +1256,7 @@ static const FunctionDef SVC_Table[] = {      {0x79, nullptr, "CreateProcess"},      {0x7A, nullptr, "StartProcess"},      {0x7B, nullptr, "TerminateProcess"}, -    {0x7C, nullptr, "GetProcessInfo"}, +    {0x7C, SvcWrap<GetProcessInfo>, "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 cbb80c3c4..b09753c80 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 <ResultCode func(u64*, u32, u32)> +void SvcWrap() { +    u64 param_1 = 0; +    u32 retval = func(¶m_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)>  void SvcWrap() {      FuncReturn(func(static_cast<u32>(Param(0)), Param(1)).raw); | 
