VSH: Drop the 6.6x alarm-category patch

6.60 and 6.61 crashed in vsh_module's alarm-task scan on a count nothing
initialized, and a data patch zeroed it. With the shell's modules started
in order, both reach the XMB, show icons and launch homebrew without it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-10 22:32:46 +02:00
1 parent 09974f9e82
commit 2cf8b69bab
2 files changed
+8 -48

No files matched your search

-38
View File
@@ -1791,44 +1791,6 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load
module->nm.name[ARRAY_SIZE(module->nm.name) - 1] = '\0';
if (equals(module->nm.name, "vsh_module")) {
// This is likely firmware-version-specific.
//
// vsh_module's SCE_VSH_GRAPHICS thread runs a scan over a small fixed table of
// "alarm task" categories (2 categories, each with a count followed by that many
// 4-byte item IDs). Category 0's data is legitimate, compiled-in content (count=8,
// items 1..8). Category 1's "count" slot, at this fixed offset, holds leftover
// unrelated float-array data instead of a real (small) count - extensive live tracing
// (see docs/VSHBootInvestigation.md, Attempts 17-19) found nothing that ever writes a
// real value here: no HLE syscall, no other loaded module's own init code (including
// the real kd/rtc.prx and kd/syscon.prx drivers), and real hardware/JPCSP running the
// identical bytes never even reaches this code path in the first place (confirmed via
// instrumenting both emulators - JPCSP's equivalent thread never executes the
// PPSSPP-equivalent 0x08818d14 entry point at all, let alone this scan). Whatever
// precondition real firmware relies on to skip or safely handle this scan isn't
// present here, and hasn't been identified despite substantial investigation - so
// zero this specific "count" out directly, matching what an empty/absent category
// would look like (the scan's own code already handles count<=0 as "nothing to do"
// for category 0 the same way). This is a narrow, targeted patch of one 4-byte value
// vsh_module itself never properly initializes, not a general vsh_module patch.
//
// This offset is into rodata rather than at a fixed
// distance from gp, and it moves with the build - so check that what's there is the
// value we identified before overwriting it, rather than writing blind into a firmware
// we haven't looked at. 6.60 and 6.61 ship byte-identical builds of vshmain.prx and
// both have the same float here; anything else is a version this patch wasn't derived
// from, and those don't reach an XMB for other reasons anyway.
const u32 vshAlarmCategory1CountOffset = 0x455C4; // Offset from module base.
const u32 vshAlarmCategory1CountExpected = 0x3F666666; // Leftover 0.9f from a float array.
u32 patchAddr = module->memoryBlockAddr + vshAlarmCategory1CountOffset;
if (!Memory::IsValid4AlignedAddress(patchAddr)) {
WARN_LOG(Log::sceModule, "Failed to patch vsh_module alarm category 1 count");
} else if (Memory::ReadUnchecked_U32(patchAddr) != vshAlarmCategory1CountExpected) {
WARN_LOG(Log::sceModule, "vsh_module isn't the build the alarm-category patch was derived from (%08x at +%x), leaving it alone",
Memory::ReadUnchecked_U32(patchAddr), vshAlarmCategory1CountOffset);
} else {
Memory::WriteUnchecked_U32(0, patchAddr);
}
ApplyVshHomebrewPatches(module->memoryBlockAddr, module->memoryBlockAddr + module->memoryBlockSize);
}