summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar Lioncash2018-09-29 19:58:21 -0400
committerGravatar Lioncash2018-09-30 05:29:40 -0400
commit541c5507538137b9cc5fd0579221aaecf59a89b1 (patch)
tree479a4bbd73e6ddca56eb75dd085a41f86b19994f /src/core/hle/kernel/svc.cpp
parentkernel/process: Add a data member to determine if a process is 64-bit or not. (diff)
downloadyuzu-541c5507538137b9cc5fd0579221aaecf59a89b1.tar.gz
yuzu-541c5507538137b9cc5fd0579221aaecf59a89b1.tar.xz
yuzu-541c5507538137b9cc5fd0579221aaecf59a89b1.zip
kernel/svc: Implement svcGetThreadContext()
Now that we have all of the rearranging and proper structure sizes in place, it's fairly trivial to implement svcGetThreadContext(). In the 64-bit case we can more or less just write out the context as is, minus some minor value sanitizing. In the 32-bit case we'll need to clear out the registers that wouldn't normally be accessible from a 32-bit AArch32 exectuable (or process).
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp32
1 files changed, 30 insertions, 2 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index b76280456..1cdaa740a 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -415,8 +415,36 @@ static ResultCode SetThreadActivity(Handle handle, u32 unknown) {
415} 415}
416 416
417/// Gets the thread context 417/// Gets the thread context
418static ResultCode GetThreadContext(Handle handle, VAddr addr) { 418static ResultCode GetThreadContext(VAddr thread_context, Handle handle) {
419 LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, addr=0x{:X}", handle, addr); 419 LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle);
420
421 auto& kernel = Core::System::GetInstance().Kernel();
422 const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(handle);
423 if (!thread) {
424 return ERR_INVALID_HANDLE;
425 }
426
427 const auto current_process = Core::CurrentProcess();
428 if (thread->owner_process != current_process) {
429 return ERR_INVALID_HANDLE;
430 }
431
432 if (thread == GetCurrentThread()) {
433 return ERR_ALREADY_REGISTERED;
434 }
435
436 Core::ARM_Interface::ThreadContext ctx = thread->context;
437 // Mask away mode bits, interrupt bits, IL bit, and other reserved bits.
438 ctx.pstate &= 0xFF0FFE20;
439
440 // If 64-bit, we can just write the context registers directly and we're good.
441 // However, if 32-bit, we have to ensure some registers are zeroed out.
442 if (!current_process->Is64BitProcess()) {
443 std::fill(ctx.cpu_registers.begin() + 15, ctx.cpu_registers.end(), 0);
444 std::fill(ctx.vector_registers.begin() + 16, ctx.vector_registers.end(), u128{});
445 }
446
447 Memory::WriteBlock(thread_context, &ctx, sizeof(ctx));
420 return RESULT_SUCCESS; 448 return RESULT_SUCCESS;
421} 449}
422 450