From eb5596044dfb3ee862ca239f9cb08eb4b9b3903f Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 26 Nov 2018 19:14:29 -0500 Subject: svc: Implement svcGetResourceLimitCurrentValue() This kernel service function is essentially the exact same as svcGetResourceLimitLimitValue(), with the only difference being that it retrieves the current value for a given resource category using the provided resource limit handle, rather than retrieving the limiting value of that resource limit instance. Given these are exactly the same and only differ on returned values, we can extract the existing code for svcGetResourceLimitLimitValue() to handle both values. --- src/core/hle/kernel/svc.cpp | 65 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 16 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 5e604411b..9d1b000b5 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -105,6 +105,38 @@ ResultCode MapUnmapMemorySanityChecks(const VMManager& vm_manager, VAddr dst_add return RESULT_SUCCESS; } + +enum class ResourceLimitValueType { + CurrentValue, + LimitValue, +}; + +ResultVal RetrieveResourceLimitValue(Handle resource_limit, u32 resource_type, + ResourceLimitValueType value_type) { + const auto type = static_cast(resource_type); + if (!IsValidResourceType(type)) { + LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); + return ERR_INVALID_ENUM_VALUE; + } + + const auto& kernel = Core::System::GetInstance().Kernel(); + const auto* const current_process = kernel.CurrentProcess(); + ASSERT(current_process != nullptr); + + const auto resource_limit_object = + current_process->GetHandleTable().Get(resource_limit); + if (!resource_limit_object) { + LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", + resource_limit); + return ERR_INVALID_HANDLE; + } + + if (value_type == ResourceLimitValueType::CurrentValue) { + return MakeResult(resource_limit_object->GetCurrentResourceValue(type)); + } + + return MakeResult(resource_limit_object->GetMaxResourceValue(type)); +} } // Anonymous namespace /// Set the process heap to a given Size. It can both extend and shrink the heap. @@ -1368,26 +1400,27 @@ static ResultCode GetResourceLimitLimitValue(u64* out_value, Handle resource_lim u32 resource_type) { LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type); - const auto type = static_cast(resource_type); - if (!IsValidResourceType(type)) { - LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'.", resource_type); - return ERR_INVALID_ENUM_VALUE; + const auto limit_value = RetrieveResourceLimitValue(resource_limit, resource_type, + ResourceLimitValueType::LimitValue); + if (limit_value.Failed()) { + return limit_value.Code(); } - const auto& kernel = Core::System::GetInstance().Kernel(); - const auto* const current_process = kernel.CurrentProcess(); - ASSERT(current_process != nullptr); + *out_value = static_cast(*limit_value); + return RESULT_SUCCESS; +} - const auto resource_limit_object = - current_process->GetHandleTable().Get(resource_limit); - if (!resource_limit_object) { - LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", - resource_limit); - return ERR_INVALID_HANDLE; +static ResultCode GetResourceLimitCurrentValue(u64* out_value, Handle resource_limit, + u32 resource_type) { + LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type); + + const auto current_value = RetrieveResourceLimitValue(resource_limit, resource_type, + ResourceLimitValueType::CurrentValue); + if (current_value.Failed()) { + return current_value.Code(); } - const s64 limit_value = resource_limit_object->GetMaxResourceValue(type); - *out_value = static_cast(limit_value); + *out_value = static_cast(*current_value); return RESULT_SUCCESS; } @@ -1451,7 +1484,7 @@ static const FunctionDef SVC_Table[] = { {0x2E, nullptr, "GetFutureThreadInfo"}, {0x2F, nullptr, "GetLastThreadInfo"}, {0x30, SvcWrap, "GetResourceLimitLimitValue"}, - {0x31, nullptr, "GetResourceLimitCurrentValue"}, + {0x31, SvcWrap, "GetResourceLimitCurrentValue"}, {0x32, SvcWrap, "SetThreadActivity"}, {0x33, SvcWrap, "GetThreadContext"}, {0x34, SvcWrap, "WaitForAddress"}, -- cgit v1.2.3