From cf9d6c6f526fffb2bf414ff774c5d0281a73ecf4 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 29 Sep 2018 18:47:00 -0400 Subject: kernel/process: Make data member variables private Makes the public interface consistent in terms of how accesses are done on a process object. It also makes it slightly nicer to reason about the logic of the process class, as we don't want to expose everything to external code. --- src/core/hle/kernel/svc.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'src/core/hle/kernel/svc.cpp') diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 44bbaf0c8..b76280456 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -51,7 +51,7 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { } auto& process = *Core::CurrentProcess(); - const VAddr heap_base = process.vm_manager.GetHeapRegionBaseAddress(); + const VAddr heap_base = process.VMManager().GetHeapRegionBaseAddress(); CASCADE_RESULT(*heap_addr, process.HeapAllocate(heap_base, heap_size, VMAPermission::ReadWrite)); return RESULT_SUCCESS; @@ -327,14 +327,14 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) info_sub_id, handle); const auto& current_process = Core::CurrentProcess(); - const auto& vm_manager = current_process->vm_manager; + const auto& vm_manager = current_process->VMManager(); switch (static_cast(info_id)) { case GetInfoType::AllowedCpuIdBitmask: - *result = current_process->allowed_processor_mask; + *result = current_process->GetAllowedProcessorMask(); break; case GetInfoType::AllowedThreadPrioBitmask: - *result = current_process->allowed_thread_priority_mask; + *result = current_process->GetAllowedThreadPriorityMask(); break; case GetInfoType::MapRegionBaseAddr: *result = vm_manager.GetMapRegionBaseAddress(); @@ -386,10 +386,10 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) *result = vm_manager.GetNewMapRegionSize(); break; case GetInfoType::IsVirtualAddressMemoryEnabled: - *result = current_process->is_virtual_address_memory_enabled; + *result = current_process->IsVirtualMemoryEnabled(); break; case GetInfoType::TitleId: - *result = current_process->program_id; + *result = current_process->GetTitleID(); break; case GetInfoType::PrivilegedProcessId: LOG_WARNING(Kernel_SVC, @@ -444,8 +444,8 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { // Note: The kernel uses the current process's resource limit instead of // the one from the thread owner's resource limit. - SharedPtr& resource_limit = Core::CurrentProcess()->resource_limit; - if (resource_limit->GetMaxResourceValue(ResourceType::Priority) > priority) { + const ResourceLimit& resource_limit = Core::CurrentProcess()->GetResourceLimit(); + if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) { return ERR_NOT_AUTHORIZED; } @@ -519,9 +519,9 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i if (!process) { return ERR_INVALID_HANDLE; } - auto vma = process->vm_manager.FindVMA(addr); + auto vma = process->VMManager().FindVMA(addr); memory_info->attributes = 0; - if (vma == Core::CurrentProcess()->vm_manager.vma_map.end()) { + if (vma == Core::CurrentProcess()->VMManager().vma_map.end()) { memory_info->base_address = 0; memory_info->permission = static_cast(VMAPermission::None); memory_info->size = 0; @@ -568,14 +568,14 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V return ERR_INVALID_THREAD_PRIORITY; } - SharedPtr& resource_limit = Core::CurrentProcess()->resource_limit; - if (resource_limit->GetMaxResourceValue(ResourceType::Priority) > priority) { + const ResourceLimit& resource_limit = Core::CurrentProcess()->GetResourceLimit(); + if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) { return ERR_NOT_AUTHORIZED; } if (processor_id == THREADPROCESSORID_DEFAULT) { // Set the target CPU to the one specified in the process' exheader. - processor_id = Core::CurrentProcess()->ideal_processor; + processor_id = Core::CurrentProcess()->GetDefaultProcessorID(); ASSERT(processor_id != THREADPROCESSORID_DEFAULT); } @@ -902,10 +902,10 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { } if (core == static_cast(THREADPROCESSORID_DEFAULT)) { - ASSERT(thread->owner_process->ideal_processor != + ASSERT(thread->owner_process->GetDefaultProcessorID() != static_cast(THREADPROCESSORID_DEFAULT)); // Set the target CPU to the one specified in the process' exheader. - core = thread->owner_process->ideal_processor; + core = thread->owner_process->GetDefaultProcessorID(); mask = 1ull << core; } -- cgit v1.2.3 From 541c5507538137b9cc5fd0579221aaecf59a89b1 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 29 Sep 2018 19:58:21 -0400 Subject: 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). --- src/core/hle/kernel/svc.cpp | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel/svc.cpp') 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) { } /// 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 = kernel.HandleTable().Get(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; } -- cgit v1.2.3