diff options
| author | 2019-04-02 21:40:39 -0400 | |
|---|---|---|
| committer | 2019-04-02 21:40:39 -0400 | |
| commit | e796351a0de70d75993e326b8828229416216d91 (patch) | |
| tree | 0f5b340a115a98383202f3a848987ddd3ce361b2 /src/core/hle/kernel/svc.cpp | |
| parent | Merge pull request #2313 from lioncash/reslimit (diff) | |
| parent | kernel/svc: Implement svcGetThreadList (diff) | |
| download | yuzu-e796351a0de70d75993e326b8828229416216d91.tar.gz yuzu-e796351a0de70d75993e326b8828229416216d91.tar.xz yuzu-e796351a0de70d75993e326b8828229416216d91.zip | |
Merge pull request #2270 from lioncash/plist
kernel/svc: Implement svcGetProcessList and svcGetThreadList
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 81 |
1 files changed, 79 insertions, 2 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 76a8b0191..23c768f57 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -1983,6 +1983,83 @@ static ResultCode SetResourceLimitLimitValue(Handle resource_limit, u32 resource | |||
| 1983 | return RESULT_SUCCESS; | 1983 | return RESULT_SUCCESS; |
| 1984 | } | 1984 | } |
| 1985 | 1985 | ||
| 1986 | static ResultCode GetProcessList(u32* out_num_processes, VAddr out_process_ids, | ||
| 1987 | u32 out_process_ids_size) { | ||
| 1988 | LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}", | ||
| 1989 | out_process_ids, out_process_ids_size); | ||
| 1990 | |||
| 1991 | // If the supplied size is negative or greater than INT32_MAX / sizeof(u64), bail. | ||
| 1992 | if ((out_process_ids_size & 0xF0000000) != 0) { | ||
| 1993 | LOG_ERROR(Kernel_SVC, | ||
| 1994 | "Supplied size outside [0, 0x0FFFFFFF] range. out_process_ids_size={}", | ||
| 1995 | out_process_ids_size); | ||
| 1996 | return ERR_OUT_OF_RANGE; | ||
| 1997 | } | ||
| 1998 | |||
| 1999 | const auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 2000 | const auto& vm_manager = kernel.CurrentProcess()->VMManager(); | ||
| 2001 | const auto total_copy_size = out_process_ids_size * sizeof(u64); | ||
| 2002 | |||
| 2003 | if (out_process_ids_size > 0 && | ||
| 2004 | !vm_manager.IsWithinAddressSpace(out_process_ids, total_copy_size)) { | ||
| 2005 | LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", | ||
| 2006 | out_process_ids, out_process_ids + total_copy_size); | ||
| 2007 | return ERR_INVALID_ADDRESS_STATE; | ||
| 2008 | } | ||
| 2009 | |||
| 2010 | const auto& process_list = kernel.GetProcessList(); | ||
| 2011 | const auto num_processes = process_list.size(); | ||
| 2012 | const auto copy_amount = std::min(std::size_t{out_process_ids_size}, num_processes); | ||
| 2013 | |||
| 2014 | for (std::size_t i = 0; i < copy_amount; ++i) { | ||
| 2015 | Memory::Write64(out_process_ids, process_list[i]->GetProcessID()); | ||
| 2016 | out_process_ids += sizeof(u64); | ||
| 2017 | } | ||
| 2018 | |||
| 2019 | *out_num_processes = static_cast<u32>(num_processes); | ||
| 2020 | return RESULT_SUCCESS; | ||
| 2021 | } | ||
| 2022 | |||
| 2023 | ResultCode GetThreadList(u32* out_num_threads, VAddr out_thread_ids, u32 out_thread_ids_size, | ||
| 2024 | Handle debug_handle) { | ||
| 2025 | // TODO: Handle this case when debug events are supported. | ||
| 2026 | UNIMPLEMENTED_IF(debug_handle != InvalidHandle); | ||
| 2027 | |||
| 2028 | LOG_DEBUG(Kernel_SVC, "called. out_thread_ids=0x{:016X}, out_thread_ids_size={}", | ||
| 2029 | out_thread_ids, out_thread_ids_size); | ||
| 2030 | |||
| 2031 | // If the size is negative or larger than INT32_MAX / sizeof(u64) | ||
| 2032 | if ((out_thread_ids_size & 0xF0000000) != 0) { | ||
| 2033 | LOG_ERROR(Kernel_SVC, "Supplied size outside [0, 0x0FFFFFFF] range. size={}", | ||
| 2034 | out_thread_ids_size); | ||
| 2035 | return ERR_OUT_OF_RANGE; | ||
| 2036 | } | ||
| 2037 | |||
| 2038 | const auto* const current_process = Core::System::GetInstance().Kernel().CurrentProcess(); | ||
| 2039 | const auto& vm_manager = current_process->VMManager(); | ||
| 2040 | const auto total_copy_size = out_thread_ids_size * sizeof(u64); | ||
| 2041 | |||
| 2042 | if (out_thread_ids_size > 0 && | ||
| 2043 | !vm_manager.IsWithinAddressSpace(out_thread_ids, total_copy_size)) { | ||
| 2044 | LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", | ||
| 2045 | out_thread_ids, out_thread_ids + total_copy_size); | ||
| 2046 | return ERR_INVALID_ADDRESS_STATE; | ||
| 2047 | } | ||
| 2048 | |||
| 2049 | const auto& thread_list = current_process->GetThreadList(); | ||
| 2050 | const auto num_threads = thread_list.size(); | ||
| 2051 | const auto copy_amount = std::min(std::size_t{out_thread_ids_size}, num_threads); | ||
| 2052 | |||
| 2053 | auto list_iter = thread_list.cbegin(); | ||
| 2054 | for (std::size_t i = 0; i < copy_amount; ++i, ++list_iter) { | ||
| 2055 | Memory::Write64(out_thread_ids, (*list_iter)->GetThreadID()); | ||
| 2056 | out_thread_ids += sizeof(u64); | ||
| 2057 | } | ||
| 2058 | |||
| 2059 | *out_num_threads = static_cast<u32>(num_threads); | ||
| 2060 | return RESULT_SUCCESS; | ||
| 2061 | } | ||
| 2062 | |||
| 1986 | namespace { | 2063 | namespace { |
| 1987 | struct FunctionDef { | 2064 | struct FunctionDef { |
| 1988 | using Func = void(); | 2065 | using Func = void(); |
| @@ -2095,8 +2172,8 @@ static const FunctionDef SVC_Table[] = { | |||
| 2095 | {0x62, nullptr, "TerminateDebugProcess"}, | 2172 | {0x62, nullptr, "TerminateDebugProcess"}, |
| 2096 | {0x63, nullptr, "GetDebugEvent"}, | 2173 | {0x63, nullptr, "GetDebugEvent"}, |
| 2097 | {0x64, nullptr, "ContinueDebugEvent"}, | 2174 | {0x64, nullptr, "ContinueDebugEvent"}, |
| 2098 | {0x65, nullptr, "GetProcessList"}, | 2175 | {0x65, SvcWrap<GetProcessList>, "GetProcessList"}, |
| 2099 | {0x66, nullptr, "GetThreadList"}, | 2176 | {0x66, SvcWrap<GetThreadList>, "GetThreadList"}, |
| 2100 | {0x67, nullptr, "GetDebugThreadContext"}, | 2177 | {0x67, nullptr, "GetDebugThreadContext"}, |
| 2101 | {0x68, nullptr, "SetDebugThreadContext"}, | 2178 | {0x68, nullptr, "SetDebugThreadContext"}, |
| 2102 | {0x69, nullptr, "QueryDebugProcessMemory"}, | 2179 | {0x69, nullptr, "QueryDebugProcessMemory"}, |