diff options
author | Lioncash <mathew1800@gmail.com> | 2019-03-20 23:53:48 +0100 |
---|---|---|
committer | Lioncash <mathew1800@gmail.com> | 2019-04-02 06:48:40 +0200 |
commit | 28719ee3b4884d182126bddf639e1711b0744b22 (patch) | |
tree | 3c8f4310e23117c330979c2c149d24a82104f04c /src/core/hle/kernel/svc.cpp | |
parent | kernel/svc: Implement svcGetProcessList (diff) | |
download | yuzu-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.cpp | 42 |
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"}, |