Merge pull request #22818 from hrydgard/adhoc-arg-checks

Adhoc: Check function arguments more like the real thing.
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2026-10-28 10:29:26 +01:00
commit 2816d6a409
10 files changed
+366 -99

No files matched your search

+33 -10
View File
@@ -1049,7 +1049,7 @@ static int sceNetInit(MIPSState *mips, u32 poolSize, u32 calloutPri, u32 callout
INFO_LOG(Log::sceNet, "sceNetInit(poolsize=%d, calloutpri=%i, calloutstack=%d, netintrpri=%i, netintrstack=%d) at %08x", poolSize, calloutPri, calloutStack, netinitPri, netinitStack, mips->pc);
netMallocStat.pool = poolSize - 0x20; // On Vantage Master Portable this is slightly (32 bytes) smaller than the poolSize arg when tested with JPCSP + prx files
netMallocStat.pool = poolSize - 0x20; // 0x1FFE0 for a 0x20000 pool, as on the PSP (pspautotests net/inet/offline)
netMallocStat.maximum = 0x4050; // Dummy maximum foot print
netMallocStat.free = netMallocStat.pool; // Dummy free size, we should set this high enough to prevent any issue (ie. Vantage Master Portable), this is probably the only field being checked by games?
@@ -1065,12 +1065,24 @@ static int sceNetInit(MIPSState *mips, u32 poolSize, u32 calloutPri, u32 callout
// Free(delete) thread info / data.
// Normal usage: sceKernelDeleteThread followed by sceNetFreeThreadInfo with the same threadID as argument
// Both take any thread, also the current one or one that has ended (pspautotests net/inet/offline).
static bool IsThreadID(SceUID thid) {
int type = 0;
return thid != 0 && kernelObjects.GetIDType(thid, &type) && type == SCE_KERNEL_TMID_Thread;
}
static int sceNetFreeThreadinfo(SceUID thid) {
if (!IsThreadID(thid)) {
return hleLogError(Log::sceNet, 0x80410104, "not a thread");
}
return hleLogError(Log::sceNet, 0, "UNIMPL");
}
// Abort a thread.
static int sceNetThreadAbort(SceUID thid) {
if (!IsThreadID(thid)) {
return hleLogError(Log::sceNet, 0x80410104, "not a thread");
}
return hleLogError(Log::sceNet, 0, "UNIMPL");
}
@@ -1184,7 +1196,7 @@ static void sceNetEtherStrton(u32 bufferPtr, u32 macPtr) {
static int sceNetGetMallocStat(u32 statPtr) {
auto stat = PSPPointer<SceNetMallocStat>::Create(statPtr);
if (!stat.IsValid())
return hleLogError(Log::sceNet, 0, "invalid address");
return hleLogError(Log::sceNet, 0x80410103, "invalid address");
*stat = netMallocStat;
stat.NotifyWrite("sceNetGetMallocStat");
@@ -1497,6 +1509,10 @@ static int NetApctl_AddHandler(u32 handlerPtr, u32 handlerArg) {
// TODO: Should we allow the same handler to be added more than once?
static u32 sceNetApctlAddHandler(u32 handlerPtr, u32 handlerArg) {
INFO_LOG(Log::sceNet, "%s(%08x, %08x)", __FUNCTION__, handlerPtr, handlerArg);
// A game gets two (pspautotests net/inet/offline).
if (apctlHandlers.size() >= MAX_APCTL_GAME_HANDLERS) {
return hleLogError(Log::sceNet, 0x80410A0F, "too many handlers");
}
return NetApctl_AddHandler(handlerPtr, handlerArg);
}
@@ -1513,6 +1529,14 @@ static int NetApctl_DelHandler(u32 handlerID) {
static int sceNetApctlDelHandler(u32 handlerID) {
INFO_LOG(Log::sceNet, "%s(%d)", __FUNCTION__, handlerID);
// An ID that can't be a handler's (100, -1) and a free one give different errors
// (pspautotests net/inet/offline). Where the range ends is inferred from the handler limit.
if (handlerID >= MAX_APCTL_GAME_HANDLERS) {
return hleLogError(Log::sceNet, 0x80410A82, "bad handler id");
}
if (apctlHandlers.find(handlerID) == apctlHandlers.end()) {
return hleLogError(Log::sceNet, SCE_NET_APCTL_ERROR_INVALID_ID, "no such handler");
}
return NetApctl_DelHandler(handlerID);
}
@@ -1575,7 +1599,7 @@ static int sceNetApctlGetState(u32 pStateAddr) {
return hleLogDebug(Log::sceNet, 0);
}
return hleLogError(Log::sceNet, -1, "apctl invalid arg"); // 0x8002013A or ERROR_NET_WLAN_INVALID_ARG ?
return hleLogError(Log::sceNet, 0x80410A03, "apctl invalid arg"); // pspautotests net/inet/offline
}
// This one logs like a syscall because it's called at the end of some.
@@ -1601,8 +1625,9 @@ int NetApctl_GetBSSDescIDListUser(u32 sizeAddr, u32 bufAddr) {
const int userInfoSize = 8; // 8 bytes per entry (next address + entry id)
// Faking 4 entries, games like MGS:PW Recruit will need to have a different AP for each entry
int entries = 4;
if (!Memory::IsValid4AlignedAddress(sizeAddr) || !Memory::IsValidAddress(bufAddr))
return hleLogError(Log::sceNet, -1, "apctl invalid arg"); // 0x8002013A or ERROR_NET_WLAN_INVALID_ARG ?
// A NULL buffer asks for the size (pspautotests net/inet/offline).
if (!Memory::IsValid4AlignedAddress(sizeAddr) || (bufAddr != 0 && !Memory::IsValidAddress(bufAddr)))
return hleLogError(Log::sceNet, 0x80410A03, "apctl invalid arg");
int size = Memory::ReadUnchecked_U32(sizeAddr);
// Return size required
@@ -1748,16 +1773,14 @@ static int sceNetApctlDelInternalHandler(u32 handlerID) {
static int sceNetApctlAddInternal03Handler(u32 handlerPtr, u32 handlerArg) {
ERROR_LOG(Log::sceNet, "UNIMPL %s(%08x, %08x)", __FUNCTION__, handlerPtr, handlerArg);
// This seems to be a 3rd kind of handler
// Simple forward, don't need to use hleCall
return sceNetApctlAddHandler(handlerPtr, handlerArg);
// This seems to be a 3rd kind of handler. The game handler limit doesn't apply.
return NetApctl_AddHandler(handlerPtr, handlerArg);
}
static int sceNetApctlDelInternal03Handler(u32 handlerID) {
ERROR_LOG(Log::sceNet, "UNIMPL %s(%i)", __FUNCTION__, handlerID);
// This seems to be a 3rd kind of handler
// Simple forward, don't need to use hleCall
return sceNetApctlDelHandler(handlerID);
return NetApctl_DelHandler(handlerID);
}
static int sceNetApctl_lib2_69745F0A(int handlerId) {