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).
This commit is contained in:
		
							parent
							
								
									dccfe193a9
								
							
						
					
					
						commit
						541c550753
					
				@ -31,6 +31,7 @@ enum {
 | 
			
		||||
    TooLarge = 119,
 | 
			
		||||
    InvalidEnumValue = 120,
 | 
			
		||||
    NoSuchEntry = 121,
 | 
			
		||||
    AlreadyRegistered = 122,
 | 
			
		||||
    InvalidState = 125,
 | 
			
		||||
    ResourceLimitExceeded = 132,
 | 
			
		||||
};
 | 
			
		||||
@ -58,6 +59,7 @@ constexpr ResultCode ERR_INVALID_MEMORY_PERMISSIONS(ErrorModule::Kernel,
 | 
			
		||||
constexpr ResultCode ERR_INVALID_HANDLE(ErrorModule::Kernel, ErrCodes::InvalidHandle);
 | 
			
		||||
constexpr ResultCode ERR_INVALID_PROCESSOR_ID(ErrorModule::Kernel, ErrCodes::InvalidProcessorId);
 | 
			
		||||
constexpr ResultCode ERR_INVALID_SIZE(ErrorModule::Kernel, ErrCodes::InvalidSize);
 | 
			
		||||
constexpr ResultCode ERR_ALREADY_REGISTERED(ErrorModule::Kernel, ErrCodes::AlreadyRegistered);
 | 
			
		||||
constexpr ResultCode ERR_INVALID_STATE(ErrorModule::Kernel, ErrCodes::InvalidState);
 | 
			
		||||
constexpr ResultCode ERR_INVALID_THREAD_PRIORITY(ErrorModule::Kernel,
 | 
			
		||||
                                                 ErrCodes::InvalidThreadPriority);
 | 
			
		||||
 | 
			
		||||
@ -415,8 +415,36 @@ static ResultCode SetThreadActivity(Handle handle, u32 unknown) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Gets the thread context
 | 
			
		||||
static ResultCode GetThreadContext(Handle handle, VAddr addr) {
 | 
			
		||||
    LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, addr=0x{:X}", handle, addr);
 | 
			
		||||
static ResultCode GetThreadContext(VAddr thread_context, Handle handle) {
 | 
			
		||||
    LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle);
 | 
			
		||||
 | 
			
		||||
    auto& kernel = Core::System::GetInstance().Kernel();
 | 
			
		||||
    const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(handle);
 | 
			
		||||
    if (!thread) {
 | 
			
		||||
        return ERR_INVALID_HANDLE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const auto current_process = Core::CurrentProcess();
 | 
			
		||||
    if (thread->owner_process != current_process) {
 | 
			
		||||
        return ERR_INVALID_HANDLE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (thread == GetCurrentThread()) {
 | 
			
		||||
        return ERR_ALREADY_REGISTERED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Core::ARM_Interface::ThreadContext ctx = thread->context;
 | 
			
		||||
    // Mask away mode bits, interrupt bits, IL bit, and other reserved bits.
 | 
			
		||||
    ctx.pstate &= 0xFF0FFE20;
 | 
			
		||||
 | 
			
		||||
    // If 64-bit, we can just write the context registers directly and we're good.
 | 
			
		||||
    // However, if 32-bit, we have to ensure some registers are zeroed out.
 | 
			
		||||
    if (!current_process->Is64BitProcess()) {
 | 
			
		||||
        std::fill(ctx.cpu_registers.begin() + 15, ctx.cpu_registers.end(), 0);
 | 
			
		||||
        std::fill(ctx.vector_registers.begin() + 16, ctx.vector_registers.end(), u128{});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Memory::WriteBlock(thread_context, &ctx, sizeof(ctx));
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -64,6 +64,11 @@ void SvcWrap() {
 | 
			
		||||
    FuncReturn(func(Param(0), (s32)Param(1)).raw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <ResultCode func(u64, u32)>
 | 
			
		||||
void SvcWrap() {
 | 
			
		||||
    FuncReturn(func(Param(0), static_cast<u32>(Param(1))).raw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <ResultCode func(u64*, u64)>
 | 
			
		||||
void SvcWrap() {
 | 
			
		||||
    u64 param_1 = 0;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user