summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorLioncash <mathew1800@gmail.com>2019-03-20 23:53:48 +0100
committerLioncash <mathew1800@gmail.com>2019-04-02 06:48:40 +0200
commit28719ee3b4884d182126bddf639e1711b0744b22 (patch)
tree3c8f4310e23117c330979c2c149d24a82104f04c /src/core/hle/kernel/svc.cpp
parentkernel/svc: Implement svcGetProcessList (diff)
downloadyuzu-28719ee3b4884d182126bddf639e1711b0744b22.tar
yuzu-28719ee3b4884d182126bddf639e1711b0744b22.tar.gz
yuzu-28719ee3b4884d182126bddf639e1711b0744b22.tar.bz2
yuzu-28719ee3b4884d182126bddf639e1711b0744b22.tar.lz
yuzu-28719ee3b4884d182126bddf639e1711b0744b22.tar.xz
yuzu-28719ee3b4884d182126bddf639e1711b0744b22.tar.zst
yuzu-28719ee3b4884d182126bddf639e1711b0744b22.zip
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp42
1 files changed, 41 insertions, 1 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 3cd948bb5..23c768f57 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -2020,6 +2020,46 @@ static ResultCode GetProcessList(u32* out_num_processes, VAddr out_process_ids,
return RESULT_SUCCESS;
}
+ResultCode GetThreadList(u32* out_num_threads, VAddr out_thread_ids, u32 out_thread_ids_size,
+ Handle debug_handle) {
+ // TODO: Handle this case when debug events are supported.
+ UNIMPLEMENTED_IF(debug_handle != InvalidHandle);
+
+ LOG_DEBUG(Kernel_SVC, "called. out_thread_ids=0x{:016X}, out_thread_ids_size={}",
+ out_thread_ids, out_thread_ids_size);
+
+ // If the size is negative or larger than INT32_MAX / sizeof(u64)
+ if ((out_thread_ids_size & 0xF0000000) != 0) {
+ LOG_ERROR(Kernel_SVC, "Supplied size outside [0, 0x0FFFFFFF] range. size={}",
+ out_thread_ids_size);
+ return ERR_OUT_OF_RANGE;
+ }
+
+ const auto* const current_process = Core::System::GetInstance().Kernel().CurrentProcess();
+ const auto& vm_manager = current_process->VMManager();
+ const auto total_copy_size = out_thread_ids_size * sizeof(u64);
+
+ if (out_thread_ids_size > 0 &&
+ !vm_manager.IsWithinAddressSpace(out_thread_ids, total_copy_size)) {
+ LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}",
+ out_thread_ids, out_thread_ids + total_copy_size);
+ return ERR_INVALID_ADDRESS_STATE;
+ }
+
+ const auto& thread_list = current_process->GetThreadList();
+ const auto num_threads = thread_list.size();
+ const auto copy_amount = std::min(std::size_t{out_thread_ids_size}, num_threads);
+
+ auto list_iter = thread_list.cbegin();
+ for (std::size_t i = 0; i < copy_amount; ++i, ++list_iter) {
+ Memory::Write64(out_thread_ids, (*list_iter)->GetThreadID());
+ out_thread_ids += sizeof(u64);
+ }
+
+ *out_num_threads = static_cast<u32>(num_threads);
+ return RESULT_SUCCESS;
+}
+
namespace {
struct FunctionDef {
using Func = void();
@@ -2133,7 +2173,7 @@ static const FunctionDef SVC_Table[] = {
{0x63, nullptr, "GetDebugEvent"},
{0x64, nullptr, "ContinueDebugEvent"},
{0x65, SvcWrap<GetProcessList>, "GetProcessList"},
- {0x66, nullptr, "GetThreadList"},
+ {0x66, SvcWrap<GetThreadList>, "GetThreadList"},
{0x67, nullptr, "GetDebugThreadContext"},
{0x68, nullptr, "SetDebugThreadContext"},
{0x69, nullptr, "QueryDebugProcessMemory"},