summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/k_address_arbiter.cpp84
-rw-r--r--src/core/hle/kernel/svc.cpp247
-rw-r--r--src/core/hle/service/lm/lm.cpp16
-rw-r--r--src/core/hle/service/ns/pl_u.cpp9
4 files changed, 234 insertions, 122 deletions
diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp
index f2f497dc4..d0e90fd60 100644
--- a/src/core/hle/kernel/k_address_arbiter.cpp
+++ b/src/core/hle/kernel/k_address_arbiter.cpp
@@ -118,9 +118,10 @@ ResultCode KAddressArbiter::SignalAndIncrementIfEqual(VAddr addr, s32 value, s32
// Check the userspace value.
s32 user_value{};
- R_UNLESS(UpdateIfEqual(system, std::addressof(user_value), addr, value, value + 1),
- Svc::ResultInvalidCurrentMemory);
-
+ if (!UpdateIfEqual(system, &user_value, addr, value, value + 1)) {
+ LOG_ERROR(Kernel, "Invalid current memory!");
+ return Svc::ResultInvalidCurrentMemory;
+ }
if (user_value != value) {
return Svc::ResultInvalidState;
}
@@ -146,61 +147,34 @@ ResultCode KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32
// Perform signaling.
s32 num_waiters{};
{
- KScopedSchedulerLock sl(kernel);
+ [[maybe_unused]] const KScopedSchedulerLock sl(kernel);
auto it = thread_tree.nfind_light({addr, -1});
// Determine the updated value.
s32 new_value{};
- if (/*GetTargetFirmware() >= TargetFirmware_7_0_0*/ true) {
- if (count <= 0) {
- if ((it != thread_tree.end()) && (it->GetAddressArbiterKey() == addr)) {
- new_value = value - 2;
- } else {
- new_value = value + 1;
- }
+ if (count <= 0) {
+ if (it != thread_tree.end() && it->GetAddressArbiterKey() == addr) {
+ new_value = value - 2;
} else {
- if ((it != thread_tree.end()) && (it->GetAddressArbiterKey() == addr)) {
- auto tmp_it = it;
- s32 tmp_num_waiters{};
- while ((++tmp_it != thread_tree.end()) &&
- (tmp_it->GetAddressArbiterKey() == addr)) {
- if ((tmp_num_waiters++) >= count) {
- break;
- }
- }
-
- if (tmp_num_waiters < count) {
- new_value = value - 1;
- } else {
- new_value = value;
- }
- } else {
- new_value = value + 1;
- }
+ new_value = value + 1;
}
} else {
- if (count <= 0) {
- if ((it != thread_tree.end()) && (it->GetAddressArbiterKey() == addr)) {
- new_value = value - 1;
- } else {
- new_value = value + 1;
- }
- } else {
+ if (it != thread_tree.end() && it->GetAddressArbiterKey() == addr) {
auto tmp_it = it;
s32 tmp_num_waiters{};
- while ((tmp_it != thread_tree.end()) && (tmp_it->GetAddressArbiterKey() == addr) &&
- (tmp_num_waiters < count + 1)) {
- ++tmp_num_waiters;
- ++tmp_it;
+ while (++tmp_it != thread_tree.end() && tmp_it->GetAddressArbiterKey() == addr) {
+ if (tmp_num_waiters++ >= count) {
+ break;
+ }
}
- if (tmp_num_waiters == 0) {
- new_value = value + 1;
- } else if (tmp_num_waiters <= count) {
+ if (tmp_num_waiters < count) {
new_value = value - 1;
} else {
new_value = value;
}
+ } else {
+ new_value = value + 1;
}
}
@@ -208,13 +182,15 @@ ResultCode KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32
s32 user_value{};
bool succeeded{};
if (value != new_value) {
- succeeded = UpdateIfEqual(system, std::addressof(user_value), addr, value, new_value);
+ succeeded = UpdateIfEqual(system, &user_value, addr, value, new_value);
} else {
- succeeded = ReadFromUser(system, std::addressof(user_value), addr);
+ succeeded = ReadFromUser(system, &user_value, addr);
}
- R_UNLESS(succeeded, Svc::ResultInvalidCurrentMemory);
-
+ if (!succeeded) {
+ LOG_ERROR(Kernel, "Invalid current memory!");
+ return Svc::ResultInvalidCurrentMemory;
+ }
if (user_value != value) {
return Svc::ResultInvalidState;
}
@@ -255,9 +231,9 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement
s32 user_value{};
bool succeeded{};
if (decrement) {
- succeeded = DecrementIfLessThan(system, std::addressof(user_value), addr, value);
+ succeeded = DecrementIfLessThan(system, &user_value, addr, value);
} else {
- succeeded = ReadFromUser(system, std::addressof(user_value), addr);
+ succeeded = ReadFromUser(system, &user_value, addr);
}
if (!succeeded) {
@@ -278,7 +254,7 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement
}
// Set the arbiter.
- cur_thread->SetAddressArbiter(std::addressof(thread_tree), addr);
+ cur_thread->SetAddressArbiter(&thread_tree, addr);
thread_tree.insert(*cur_thread);
cur_thread->SetState(ThreadState::Waiting);
cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration);
@@ -299,7 +275,7 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement
// Get the result.
KSynchronizationObject* dummy{};
- return cur_thread->GetWaitResult(std::addressof(dummy));
+ return cur_thread->GetWaitResult(&dummy);
}
ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) {
@@ -320,7 +296,7 @@ ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) {
// Read the value from userspace.
s32 user_value{};
- if (!ReadFromUser(system, std::addressof(user_value), addr)) {
+ if (!ReadFromUser(system, &user_value, addr)) {
slp.CancelSleep();
return Svc::ResultInvalidCurrentMemory;
}
@@ -338,7 +314,7 @@ ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) {
}
// Set the arbiter.
- cur_thread->SetAddressArbiter(std::addressof(thread_tree), addr);
+ cur_thread->SetAddressArbiter(&thread_tree, addr);
thread_tree.insert(*cur_thread);
cur_thread->SetState(ThreadState::Waiting);
cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration);
@@ -359,7 +335,7 @@ ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) {
// Get the result.
KSynchronizationObject* dummy{};
- return cur_thread->GetWaitResult(std::addressof(dummy));
+ return cur_thread->GetWaitResult(&dummy);
}
} // namespace Kernel
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index edf208eff..26650a513 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -368,7 +368,10 @@ static ResultCode GetThreadId(Core::System& system, u64* out_thread_id, Handle t
// Get the thread from its handle.
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
const std::shared_ptr<KThread> thread = handle_table.Get<KThread>(thread_handle);
- R_UNLESS(thread, Svc::ResultInvalidHandle);
+ if (!thread) {
+ LOG_ERROR(Kernel_SVC, "Invalid thread handle provided (handle={:08X})", thread_handle);
+ return ResultInvalidHandle;
+ }
// Get the thread's id.
*out_thread_id = thread->GetThreadID();
@@ -478,7 +481,10 @@ static ResultCode CancelSynchronization(Core::System& system, Handle thread_hand
// Get the thread from its handle.
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
std::shared_ptr<KThread> thread = handle_table.Get<KThread>(thread_handle);
- R_UNLESS(thread, Svc::ResultInvalidHandle);
+ if (!thread) {
+ LOG_ERROR(Kernel_SVC, "Invalid thread handle provided (handle={:08X})", thread_handle);
+ return ResultInvalidHandle;
+ }
// Cancel the thread's wait.
thread->WaitCancel();
@@ -496,8 +502,15 @@ static ResultCode ArbitrateLock(Core::System& system, Handle thread_handle, VAdd
thread_handle, address, tag);
// Validate the input address.
- R_UNLESS(!Memory::IsKernelAddress(address), Svc::ResultInvalidCurrentMemory);
- R_UNLESS(Common::IsAligned(address, sizeof(u32)), Svc::ResultInvalidAddress);
+ if (Memory::IsKernelAddress(address)) {
+ LOG_ERROR(Kernel_SVC, "Attempting to arbitrate a lock on a kernel address (address={:08X})",
+ address);
+ return ResultInvalidCurrentMemory;
+ }
+ if (!Common::IsAligned(address, sizeof(u32))) {
+ LOG_ERROR(Kernel_SVC, "Input address must be 4 byte aligned (address: {:08X})", address);
+ return ResultInvalidAddress;
+ }
return system.Kernel().CurrentProcess()->WaitForAddress(thread_handle, address, tag);
}
@@ -512,8 +525,16 @@ static ResultCode ArbitrateUnlock(Core::System& system, VAddr address) {
LOG_TRACE(Kernel_SVC, "called address=0x{:X}", address);
// Validate the input address.
- R_UNLESS(!Memory::IsKernelAddress(address), Svc::ResultInvalidCurrentMemory);
- R_UNLESS(Common::IsAligned(address, sizeof(u32)), Svc::ResultInvalidAddress);
+ if (Memory::IsKernelAddress(address)) {
+ LOG_ERROR(Kernel_SVC,
+ "Attempting to arbitrate an unlock on a kernel address (address={:08X})",
+ address);
+ return ResultInvalidCurrentMemory;
+ }
+ if (!Common::IsAligned(address, sizeof(u32))) {
+ LOG_ERROR(Kernel_SVC, "Input address must be 4 byte aligned (address: {:08X})", address);
+ return ResultInvalidAddress;
+ }
return system.Kernel().CurrentProcess()->SignalToAddress(address);
}
@@ -1025,37 +1046,47 @@ static ResultCode UnmapPhysicalMemory32(Core::System& system, u32 addr, u32 size
return UnmapPhysicalMemory(system, addr, size);
}
-constexpr bool IsValidThreadActivity(Svc::ThreadActivity thread_activity) {
- switch (thread_activity) {
- case Svc::ThreadActivity::Runnable:
- case Svc::ThreadActivity::Paused:
- return true;
- default:
- return false;
- }
-}
-
/// Sets the thread activity
static ResultCode SetThreadActivity(Core::System& system, Handle thread_handle,
- Svc::ThreadActivity thread_activity) {
+ ThreadActivity thread_activity) {
LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", thread_handle,
thread_activity);
// Validate the activity.
- R_UNLESS(IsValidThreadActivity(thread_activity), Svc::ResultInvalidEnumValue);
+ constexpr auto IsValidThreadActivity = [](ThreadActivity activity) {
+ return activity == ThreadActivity::Runnable || activity == ThreadActivity::Paused;
+ };
+ if (!IsValidThreadActivity(thread_activity)) {
+ LOG_ERROR(Kernel_SVC, "Invalid thread activity value provided (activity={})",
+ thread_activity);
+ return ResultInvalidEnumValue;
+ }
// Get the thread from its handle.
auto& kernel = system.Kernel();
const auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
const std::shared_ptr<KThread> thread = handle_table.Get<KThread>(thread_handle);
- R_UNLESS(thread, Svc::ResultInvalidHandle);
+ if (!thread) {
+ LOG_ERROR(Kernel_SVC, "Invalid thread handle provided (handle={:08X})", thread_handle);
+ return ResultInvalidHandle;
+ }
// Check that the activity is being set on a non-current thread for the current process.
- R_UNLESS(thread->GetOwnerProcess() == kernel.CurrentProcess(), Svc::ResultInvalidHandle);
- R_UNLESS(thread.get() != GetCurrentThreadPointer(kernel), Svc::ResultBusy);
+ if (thread->GetOwnerProcess() != kernel.CurrentProcess()) {
+ LOG_ERROR(Kernel_SVC, "Invalid owning process for the created thread.");
+ return ResultInvalidHandle;
+ }
+ if (thread.get() == GetCurrentThreadPointer(kernel)) {
+ LOG_ERROR(Kernel_SVC, "Thread is busy");
+ return ResultBusy;
+ }
// Set the activity.
- R_TRY(thread->SetActivity(thread_activity));
+ const auto set_result = thread->SetActivity(thread_activity);
+ if (set_result.IsError()) {
+ LOG_ERROR(Kernel_SVC, "Failed to set thread activity.");
+ return set_result;
+ }
return RESULT_SUCCESS;
}
@@ -1074,16 +1105,29 @@ static ResultCode GetThreadContext(Core::System& system, VAddr out_context, Hand
const auto* current_process = system.Kernel().CurrentProcess();
const std::shared_ptr<KThread> thread =
current_process->GetHandleTable().Get<KThread>(thread_handle);
- R_UNLESS(thread, Svc::ResultInvalidHandle);
+ if (!thread) {
+ LOG_ERROR(Kernel_SVC, "Invalid thread handle provided (handle={})", thread_handle);
+ return ResultInvalidHandle;
+ }
// Require the handle be to a non-current thread in the current process.
- R_UNLESS(thread->GetOwnerProcess() == current_process, Svc::ResultInvalidHandle);
- R_UNLESS(thread.get() != system.Kernel().CurrentScheduler()->GetCurrentThread(),
- Svc::ResultBusy);
+ if (thread->GetOwnerProcess() != current_process) {
+ LOG_ERROR(Kernel_SVC, "Thread owning process is not the current process.");
+ return ResultInvalidHandle;
+ }
+ if (thread.get() == system.Kernel().CurrentScheduler()->GetCurrentThread()) {
+ LOG_ERROR(Kernel_SVC, "Current thread is busy.");
+ return ResultBusy;
+ }
// Get the thread context.
std::vector<u8> context;
- R_TRY(thread->GetThreadContext3(context));
+ const auto context_result = thread->GetThreadContext3(context);
+ if (context_result.IsError()) {
+ LOG_ERROR(Kernel_SVC, "Unable to successfully retrieve thread context (result: {})",
+ context_result.raw);
+ return context_result;
+ }
// Copy the thread context to user space.
system.Memory().WriteBlock(out_context, context.data(), context.size());
@@ -1102,7 +1146,10 @@ static ResultCode GetThreadPriority(Core::System& system, u32* out_priority, Han
// Get the thread from its handle.
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
const std::shared_ptr<KThread> thread = handle_table.Get<KThread>(handle);
- R_UNLESS(thread, Svc::ResultInvalidHandle);
+ if (!thread) {
+ LOG_ERROR(Kernel_SVC, "Invalid thread handle provided (handle={:08X})", handle);
+ return ResultInvalidHandle;
+ }
// Get the thread's priority.
*out_priority = thread->GetPriority();
@@ -1118,13 +1165,18 @@ static ResultCode SetThreadPriority(Core::System& system, Handle handle, u32 pri
LOG_TRACE(Kernel_SVC, "called");
// Validate the priority.
- R_UNLESS(Svc::HighestThreadPriority <= priority && priority <= Svc::LowestThreadPriority,
- Svc::ResultInvalidPriority);
+ if (HighestThreadPriority > priority || priority > LowestThreadPriority) {
+ LOG_ERROR(Kernel_SVC, "Invalid thread priority specified (priority={})", priority);
+ return ResultInvalidPriority;
+ }
// Get the thread from its handle.
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
const std::shared_ptr<KThread> thread = handle_table.Get<KThread>(handle);
- R_UNLESS(thread, Svc::ResultInvalidHandle);
+ if (!thread) {
+ LOG_ERROR(Kernel_SVC, "Invalid handle provided (handle={:08X})", handle);
+ return ResultInvalidHandle;
+ }
// Set the thread priority.
thread->SetBasePriority(priority);
@@ -1440,17 +1492,28 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
// Adjust core id, if it's the default magic.
auto& kernel = system.Kernel();
auto& process = *kernel.CurrentProcess();
- if (core_id == Svc::IdealCoreUseProcessValue) {
+ if (core_id == IdealCoreUseProcessValue) {
core_id = process.GetIdealCoreId();
}
// Validate arguments.
- R_UNLESS(IsValidCoreId(core_id), Svc::ResultInvalidCoreId);
- R_UNLESS(((1ULL << core_id) & process.GetCoreMask()) != 0, Svc::ResultInvalidCoreId);
+ if (!IsValidCoreId(core_id)) {
+ LOG_ERROR(Kernel_SVC, "Invalid Core ID specified (id={})", core_id);
+ return ResultInvalidCoreId;
+ }
+ if (((1ULL << core_id) & process.GetCoreMask()) == 0) {
+ LOG_ERROR(Kernel_SVC, "Core ID doesn't fall within allowable cores (id={})", core_id);
+ return ResultInvalidCoreId;
+ }
- R_UNLESS(Svc::HighestThreadPriority <= priority && priority <= Svc::LowestThreadPriority,
- Svc::ResultInvalidPriority);
- R_UNLESS(process.CheckThreadPriority(priority), Svc::ResultInvalidPriority);
+ if (HighestThreadPriority > priority || priority > LowestThreadPriority) {
+ LOG_ERROR(Kernel_SVC, "Invalid priority specified (priority={})", priority);
+ return ResultInvalidPriority;
+ }
+ if (!process.CheckThreadPriority(priority)) {
+ LOG_ERROR(Kernel_SVC, "Invalid allowable thread priority (priority={})", priority);
+ return ResultInvalidPriority;
+ }
ASSERT(process.GetResourceLimit()->Reserve(
LimitableResource::Threads, 1, system.CoreTiming().GetGlobalTimeNs().count() + 100000000));
@@ -1489,10 +1552,19 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) {
// Get the thread from its handle.
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
const std::shared_ptr<KThread> thread = handle_table.Get<KThread>(thread_handle);
- R_UNLESS(thread, Svc::ResultInvalidHandle);
+ if (!thread) {
+ LOG_ERROR(Kernel_SVC, "Invalid thread handle provided (handle={:08X})", thread_handle);
+ return ResultInvalidHandle;
+ }
// Try to start the thread.
- R_TRY(thread->Run());
+ const auto run_result = thread->Run();
+ if (run_result.IsError()) {
+ LOG_ERROR(Kernel_SVC,
+ "Unable to successfuly start thread (thread handle={:08X}, result={})",
+ thread_handle, run_result.raw);
+ return run_result;
+ }
return RESULT_SUCCESS;
}
@@ -1553,8 +1625,14 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr address,
cv_key, tag, timeout_ns);
// Validate input.
- R_UNLESS(!Memory::IsKernelAddress(address), Svc::ResultInvalidCurrentMemory);
- R_UNLESS(Common::IsAligned(address, sizeof(int32_t)), Svc::ResultInvalidAddress);
+ if (Memory::IsKernelAddress(address)) {
+ LOG_ERROR(Kernel_SVC, "Attempted to wait on kernel address (address={:08X})", address);
+ return ResultInvalidCurrentMemory;
+ }
+ if (!Common::IsAligned(address, sizeof(s32))) {
+ LOG_ERROR(Kernel_SVC, "Address must be 4 byte aligned (address={:08X})", address);
+ return ResultInvalidAddress;
+ }
// Convert timeout from nanoseconds to ticks.
s64 timeout{};
@@ -1629,9 +1707,18 @@ static ResultCode WaitForAddress(Core::System& system, VAddr address, Svc::Arbit
address, arb_type, value, timeout_ns);
// Validate input.
- R_UNLESS(!Memory::IsKernelAddress(address), Svc::ResultInvalidCurrentMemory);
- R_UNLESS(Common::IsAligned(address, sizeof(int32_t)), Svc::ResultInvalidAddress);
- R_UNLESS(IsValidArbitrationType(arb_type), Svc::ResultInvalidEnumValue);
+ if (Memory::IsKernelAddress(address)) {
+ LOG_ERROR(Kernel_SVC, "Attempting to wait on kernel address (address={:08X})", address);
+ return ResultInvalidCurrentMemory;
+ }
+ if (!Common::IsAligned(address, sizeof(s32))) {
+ LOG_ERROR(Kernel_SVC, "Wait address must be 4 byte aligned (address={:08X})", address);
+ return ResultInvalidAddress;
+ }
+ if (!IsValidArbitrationType(arb_type)) {
+ LOG_ERROR(Kernel_SVC, "Invalid arbitration type specified (type={})", arb_type);
+ return ResultInvalidEnumValue;
+ }
// Convert timeout from nanoseconds to ticks.
s64 timeout{};
@@ -1665,9 +1752,18 @@ static ResultCode SignalToAddress(Core::System& system, VAddr address, Svc::Sign
address, signal_type, value, count);
// Validate input.
- R_UNLESS(!Memory::IsKernelAddress(address), Svc::ResultInvalidCurrentMemory);
- R_UNLESS(Common::IsAligned(address, sizeof(s32)), Svc::ResultInvalidAddress);
- R_UNLESS(IsValidSignalType(signal_type), Svc::ResultInvalidEnumValue);
+ if (Memory::IsKernelAddress(address)) {
+ LOG_ERROR(Kernel_SVC, "Attempting to signal to a kernel address (address={:08X})", address);
+ return ResultInvalidCurrentMemory;
+ }
+ if (!Common::IsAligned(address, sizeof(s32))) {
+ LOG_ERROR(Kernel_SVC, "Signaled address must be 4 byte aligned (address={:08X})", address);
+ return ResultInvalidAddress;
+ }
+ if (!IsValidSignalType(signal_type)) {
+ LOG_ERROR(Kernel_SVC, "Invalid signal type specified (type={})", signal_type);
+ return ResultInvalidEnumValue;
+ }
return system.Kernel().CurrentProcess()->SignalAddressArbiter(address, signal_type, value,
count);
@@ -1815,10 +1911,17 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle,
// Get the thread from its handle.
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
const std::shared_ptr<KThread> thread = handle_table.Get<KThread>(thread_handle);
- R_UNLESS(thread, Svc::ResultInvalidHandle);
+ if (!thread) {
+ LOG_ERROR(Kernel_SVC, "Invalid thread handle specified (handle={:08X})", thread_handle);
+ return ResultInvalidHandle;
+ }
// Get the core mask.
- R_TRY(thread->GetCoreMask(out_core_id, out_affinity_mask));
+ const auto result = thread->GetCoreMask(out_core_id, out_affinity_mask);
+ if (result.IsError()) {
+ LOG_ERROR(Kernel_SVC, "Unable to successfully retrieve core mask (result={})", result.raw);
+ return result;
+ }
return RESULT_SUCCESS;
}
@@ -1846,26 +1949,46 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle,
} else {
// Validate the affinity mask.
const u64 process_core_mask = current_process.GetCoreMask();
- R_UNLESS((affinity_mask | process_core_mask) == process_core_mask,
- Svc::ResultInvalidCoreId);
- R_UNLESS(affinity_mask != 0, Svc::ResultInvalidCombination);
+ if ((affinity_mask | process_core_mask) != process_core_mask) {
+ LOG_ERROR(Kernel_SVC,
+ "Affinity mask does match the process core mask (affinity mask={:016X}, core "
+ "mask={:016X})",
+ affinity_mask, process_core_mask);
+ return ResultInvalidCoreId;
+ }
+ if (affinity_mask == 0) {
+ LOG_ERROR(Kernel_SVC, "Affinity mask is zero.");
+ return ResultInvalidCombination;
+ }
// Validate the core id.
if (IsValidCoreId(core_id)) {
- R_UNLESS(((1ULL << core_id) & affinity_mask) != 0, Svc::ResultInvalidCombination);
+ if (((1ULL << core_id) & affinity_mask) == 0) {
+ LOG_ERROR(Kernel_SVC, "Invalid core ID (ID={})", core_id);
+ return ResultInvalidCombination;
+ }
} else {
- R_UNLESS(core_id == Svc::IdealCoreNoUpdate || core_id == Svc::IdealCoreDontCare,
- Svc::ResultInvalidCoreId);
+ if (core_id != IdealCoreNoUpdate && core_id != IdealCoreDontCare) {
+ LOG_ERROR(Kernel_SVC, "Invalid core ID (ID={})", core_id);
+ return ResultInvalidCoreId;
+ }
}
}
// Get the thread from its handle.
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
const std::shared_ptr<KThread> thread = handle_table.Get<KThread>(thread_handle);
- R_UNLESS(thread, Svc::ResultInvalidHandle);
+ if (!thread) {
+ LOG_ERROR(Kernel_SVC, "Invalid thread handle (handle={:08X})", thread_handle);
+ return ResultInvalidHandle;
+ }
// Set the core mask.
- R_TRY(thread->SetCoreMask(core_id, affinity_mask));
+ const auto set_result = thread->SetCoreMask(core_id, affinity_mask);
+ if (set_result.IsError()) {
+ LOG_ERROR(Kernel_SVC, "Unable to successfully set core mask (result={})", set_result.raw);
+ return set_result;
+ }
return RESULT_SUCCESS;
}
@@ -1884,7 +2007,10 @@ static ResultCode SignalEvent(Core::System& system, Handle event_handle) {
// Get the writable event.
auto writable_event = handle_table.Get<KWritableEvent>(event_handle);
- R_UNLESS(writable_event, Svc::ResultInvalidHandle);
+ if (!writable_event) {
+ LOG_ERROR(Kernel_SVC, "Invalid event handle provided (handle={:08X})", event_handle);
+ return ResultInvalidHandle;
+ }
return writable_event->Signal();
}
@@ -1933,7 +2059,10 @@ static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* o
// Create a new event.
const auto event = KEvent::Create(kernel, "CreateEvent");
- R_UNLESS(event != nullptr, Svc::ResultOutOfResource);
+ if (!event) {
+ LOG_ERROR(Kernel_SVC, "Unable to create new events. Event creation limit reached.");
+ return ResultOutOfResource;
+ }
// Initialize the event.
event->Initialize();
diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp
index 2a6d43d2a..7d7542fc2 100644
--- a/src/core/hle/service/lm/lm.cpp
+++ b/src/core/hle/service/lm/lm.cpp
@@ -143,17 +143,19 @@ private:
rb.Push(RESULT_SUCCESS);
}
- u32 ReadLeb128(const std::vector<u8>& data, std::size_t& offset) {
- u32 result{};
+ u64 ReadLeb128(const std::vector<u8>& data, std::size_t& offset) {
+ u64 result{};
u32 shift{};
- do {
- result |= (data[offset] & 0x7f) << shift;
+
+ for (std::size_t i = 0; i < sizeof(u64); i++) {
+ const auto v = data[offset];
+ result |= (static_cast<u64>(v & 0x7f) << shift);
shift += 7;
offset++;
- if (offset >= data.size()) {
+ if (offset >= data.size() || ((v & 0x80) == 0)) {
break;
}
- } while ((data[offset] & 0x80) != 0);
+ }
return result;
}
@@ -262,7 +264,7 @@ private:
switch (entry.severity) {
case LogSeverity::Trace:
- LOG_DEBUG(Service_LM, "LogManager DEBUG ({}):\n{}", DestinationToString(destination),
+ LOG_DEBUG(Service_LM, "LogManager TRACE ({}):\n{}", DestinationToString(destination),
output_log);
break;
case LogSeverity::Info:
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp
index 71c7587db..b6ac0a81a 100644
--- a/src/core/hle/service/ns/pl_u.cpp
+++ b/src/core/hle/service/ns/pl_u.cpp
@@ -65,13 +65,18 @@ static void DecryptSharedFont(const std::vector<u32>& input, Kernel::PhysicalMem
void DecryptSharedFontToTTF(const std::vector<u32>& input, std::vector<u8>& output) {
ASSERT_MSG(input[0] == EXPECTED_MAGIC, "Failed to derive key, unexpected magic number");
+ if (input.size() < 2) {
+ LOG_ERROR(Service_NS, "Input font is empty");
+ return;
+ }
+
const u32 KEY = input[0] ^ EXPECTED_RESULT; // Derive key using an inverse xor
std::vector<u32> transformed_font(input.size());
// TODO(ogniK): Figure out a better way to do this
std::transform(input.begin(), input.end(), transformed_font.begin(),
[&KEY](u32 font_data) { return Common::swap32(font_data ^ KEY); });
- transformed_font[1] = Common::swap32(transformed_font[1]) ^ KEY; // "re-encrypt" the size
- std::memcpy(output.data(), transformed_font.data() + 2, transformed_font.size() * sizeof(u32));
+ std::memcpy(output.data(), transformed_font.data() + 2,
+ (transformed_font.size() - 2) * sizeof(u32));
}
void EncryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output,