From c4160b4eed6430a3193a727362fbdddfa667e667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 3 Sep 2026 12:27:52 -0600 Subject: [PATCH] HLE: Small kernel cleanups Initialize the wokeThreads locals that were passed by reference uninitialized in the event flag, VPL and semaphore timeout handlers. Harmless today since the callee only ever assigns to them, but every other use in the same files starts at false. Do the semaphore overflow check in 64-bit, so a large signal value can't wrap past it into currentCount. --- Core/HLE/sceKernelEventFlag.cpp | 2 +- Core/HLE/sceKernelMemory.cpp | 2 +- Core/HLE/sceKernelSemaphore.cpp | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceKernelEventFlag.cpp b/Core/HLE/sceKernelEventFlag.cpp index b333af2a41..734aad266b 100644 --- a/Core/HLE/sceKernelEventFlag.cpp +++ b/Core/HLE/sceKernelEventFlag.cpp @@ -285,7 +285,7 @@ void __KernelEventFlagTimeout(u64 userdata, int cycleslate) { for (size_t i = 0; i < e->waitingThreads.size(); i++) { EventFlagTh *t = &e->waitingThreads[i]; if (t->threadID == threadID) { - bool wokeThreads; + bool wokeThreads = false; // This thread isn't waiting anymore, but we'll remove it from waitingThreads later. // The reason is, if it times out, but what it was waiting on is DELETED prior to it diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index 6d8edf3eab..91ce9ba1e7 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -1435,7 +1435,7 @@ void __KernelVplTimeout(u64 userdata, int cyclesLate) { // If in FIFO mode, that may have cleared another thread to wake up. VPL *vpl = kernelObjects.Get(uid, error); if (vpl && (vpl->nv.attr & PSP_VPL_ATTR_MASK_ORDER) == PSP_VPL_ATTR_FIFO) { - bool wokeThreads; + bool wokeThreads = false; std::vector::iterator iter = vpl->waitingThreads.begin(); // Unlock every waiting thread until the first that must still wait. while (iter != vpl->waitingThreads.end() && __KernelUnlockVplForThread(vpl, *iter, error, 0, wokeThreads)) { diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index b7d23f8d09..41d43aea7b 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -242,7 +242,8 @@ int sceKernelSignalSema(SceUID id, int signal) { return hleLogError(Log::sceKernel, error, "bad sema id"); } } else { - if (s->ns.currentCount + signal - (int) s->waitingThreads.size() > s->ns.maxCount) { + // Done in 64-bit so a huge signal value can't overflow its way past the check. + if ((s64)s->ns.currentCount + signal - (s64)s->waitingThreads.size() > s->ns.maxCount) { return hleLogDebug(Log::sceKernel, SCE_KERNEL_ERROR_SEMA_OVF, "overflow at %d", s->ns.currentCount); } @@ -279,7 +280,7 @@ void __KernelSemaTimeout(u64 userdata, int cycleslate) { // If in FIFO mode, that may have cleared another thread to wake up. PSPSemaphore *s = kernelObjects.Get(uid, error); if (s && (s->ns.attr & PSP_SEMA_ATTR_PRIORITY) == PSP_SEMA_ATTR_FIFO) { - bool wokeThreads; + bool wokeThreads = false; std::vector::iterator iter = s->waitingThreads.begin(); // Unlock every waiting thread until the first that must still wait. while (iter != s->waitingThreads.end() && __KernelUnlockSemaForThread(s, *iter, error, 0, wokeThreads)) {