From ccd4e921846a0174f1b2d4877ad7a3543af79343 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 3 Sep 2022 10:37:58 -0700 Subject: [PATCH] Kernel: Use PSPPointer for status objects. Code makes more sense when reading ->size rather than offset 0. --- Core/HLE/sceKernel.cpp | 38 ++++++++-------- Core/HLE/sceKernelEventFlag.cpp | 9 ++-- Core/HLE/sceKernelInterrupt.cpp | 2 +- Core/HLE/sceKernelMbx.cpp | 20 ++++----- Core/HLE/sceKernelMemory.cpp | 58 +++++++++++------------- Core/HLE/sceKernelModule.cpp | 74 +++++++++++++++--------------- Core/HLE/sceKernelMsgPipe.cpp | 30 +++++-------- Core/HLE/sceKernelMutex.cpp | 79 +++++++++++---------------------- Core/HLE/sceKernelSemaphore.cpp | 28 +++++------- Core/HLE/sceKernelThread.cpp | 15 ++++--- Core/MemMap.h | 15 ++++++- Core/MemMapHelpers.h | 27 ----------- 12 files changed, 172 insertions(+), 223 deletions(-) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 738ce25303..cb858c0e90 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -646,12 +646,12 @@ struct SystemStatus { static int sceKernelReferSystemStatus(u32 statusPtr) { DEBUG_LOG(SCEKERNEL, "sceKernelReferSystemStatus(%08x)", statusPtr); - if (Memory::IsValidAddress(statusPtr)) { - SystemStatus status; - memset(&status, 0, sizeof(SystemStatus)); - status.size = sizeof(SystemStatus); + auto status = PSPPointer::Create(statusPtr); + if (status.IsValid()) { + memset((SystemStatus *)status, 0, sizeof(SystemStatus)); + status->size = sizeof(SystemStatus); // TODO: Fill in the struct! - Memory::WriteStruct(statusPtr, &status); + status.NotifyWrite("SystemStatus"); } return 0; } @@ -684,11 +684,11 @@ static u32 sceKernelReferThreadProfiler(u32 statusPtr) { // Can we confirm that the struct above is the right struct? // If so, re-enable this code. - //DebugProfilerRegs regs; - //memset(®s, 0, sizeof(regs)); + //auto regs = PSPPointer::Create(statusPtr); // TODO: fill the struct. - //if (Memory::IsValidAddress(statusPtr)) { - // Memory::WriteStruct(statusPtr, ®s); + //if (regs.IsValid()) { + // memset((DebugProfilerRegs *)regs, 0, sizeof(DebugProfilerRegs)); + // regs.NotifyWrite("ThreadProfiler"); //} return 0; } @@ -715,14 +715,14 @@ const HLEFunction ThreadManForUser[] = {0XD6DA4BA1, &WrapI_CUIIU, "sceKernelCreateSema", 'i', "sxiix" }, {0X28B6489C, &WrapI_I, "sceKernelDeleteSema", 'i', "i" }, {0X58B1F937, &WrapI_II, "sceKernelPollSema", 'i', "ii" }, - {0XBC6FEBC5, &WrapI_IU, "sceKernelReferSemaStatus", 'i', "ix" }, + {0XBC6FEBC5, &WrapI_IU, "sceKernelReferSemaStatus", 'i', "ip" }, {0X3F53E640, &WrapI_II, "sceKernelSignalSema", 'i', "ii" }, {0X4E3A1105, &WrapI_IIU, "sceKernelWaitSema", 'i', "iix", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0X6D212BAC, &WrapI_IIU, "sceKernelWaitSemaCB", 'i', "iix", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0X60107536, &WrapI_U, "sceKernelDeleteLwMutex", 'i', "x" }, {0X19CFF145, &WrapI_UCUIU, "sceKernelCreateLwMutex", 'i', "xsxix" }, - {0X4C145944, &WrapI_IU, "sceKernelReferLwMutexStatusByID", 'i', "ix" }, + {0X4C145944, &WrapI_IU, "sceKernelReferLwMutexStatusByID", 'i', "xp" }, // NOTE: LockLwMutex, UnlockLwMutex, and ReferLwMutexStatus are in Kernel_Library, see sceKernelInterrupt.cpp. // The below should not be called directly. //{0x71040D5C, nullptr, "_sceKernelTryLockLwMutex", '?', "" }, @@ -736,7 +736,7 @@ const HLEFunction ThreadManForUser[] = {0X6B30100F, &WrapI_II, "sceKernelUnlockMutex", 'i', "ii" }, {0XB7D098C6, &WrapI_CUIU, "sceKernelCreateMutex", 'i', "sxix" }, {0X0DDCD2C9, &WrapI_II, "sceKernelTryLockMutex", 'i', "ii" }, - {0XA9C2CB9A, &WrapI_IU, "sceKernelReferMutexStatus", 'i', "ix" }, + {0XA9C2CB9A, &WrapI_IU, "sceKernelReferMutexStatus", 'i', "ip" }, {0X87D9223C, &WrapI_IIU, "sceKernelCancelMutex", 'i', "iix" }, {0XFCCFAD26, &WrapI_I, "sceKernelCancelWakeupThread", 'i', "i" }, @@ -818,7 +818,7 @@ const HLEFunction ThreadManForUser[] = {0XF3986382, &WrapI_IUU, "sceKernelReceiveMbxCB", 'i', "ixx", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0X0D81716A, &WrapI_IU, "sceKernelPollMbx", 'i', "ix" }, {0X87D4DD36, &WrapI_IU, "sceKernelCancelReceiveMbx", 'i', "ix" }, - {0XA8E8C846, &WrapI_IU, "sceKernelReferMbxStatus", 'i', "ix" }, + {0XA8E8C846, &WrapI_IU, "sceKernelReferMbxStatus", 'i', "ip" }, {0X7C0DC2A0, &WrapI_CIUUU, "sceKernelCreateMsgPipe", 'i', "sixxx" }, {0XF0B7DA1C, &WrapI_I, "sceKernelDeleteMsgPipe", 'i', "i" }, @@ -829,7 +829,7 @@ const HLEFunction ThreadManForUser[] = {0XFBFA697D, &WrapI_IUUUUU, "sceKernelReceiveMsgPipeCB", 'i', "ixxxxx" }, {0XDF52098F, &WrapI_IUUUU, "sceKernelTryReceiveMsgPipe", 'i', "ixxxx" }, {0X349B864D, &WrapI_IUU, "sceKernelCancelMsgPipe", 'i', "ixx" }, - {0X33BE4024, &WrapI_IU, "sceKernelReferMsgPipeStatus", 'i', "ix" }, + {0X33BE4024, &WrapI_IU, "sceKernelReferMsgPipeStatus", 'i', "ip" }, {0X56C039B5, &WrapI_CIUUU, "sceKernelCreateVpl", 'i', "sixxx" }, {0X89B3D48C, &WrapI_I, "sceKernelDeleteVpl", 'i', "i" }, @@ -838,7 +838,7 @@ const HLEFunction ThreadManForUser[] = {0XAF36D708, &WrapI_IUU, "sceKernelTryAllocateVpl", 'i', "ixx" }, {0XB736E9FF, &WrapI_IU, "sceKernelFreeVpl", 'i', "ix" }, {0X1D371B8A, &WrapI_IU, "sceKernelCancelVpl", 'i', "ix" }, - {0X39810265, &WrapI_IU, "sceKernelReferVplStatus", 'i', "ix" }, + {0X39810265, &WrapI_IU, "sceKernelReferVplStatus", 'i', "ip" }, {0XC07BB470, &WrapI_CUUUUU, "sceKernelCreateFpl", 'i', "sxxxxx" }, {0XED1410E0, &WrapI_I, "sceKernelDeleteFpl", 'i', "i" }, @@ -847,7 +847,7 @@ const HLEFunction ThreadManForUser[] = {0X623AE665, &WrapI_IU, "sceKernelTryAllocateFpl", 'i', "ix" }, {0XF6414A71, &WrapI_IU, "sceKernelFreeFpl", 'i', "ix" }, {0XA8AA591F, &WrapI_IU, "sceKernelCancelFpl", 'i', "ix" }, - {0XD8199E4C, &WrapI_IU, "sceKernelReferFplStatus", 'i', "ix" }, + {0XD8199E4C, &WrapI_IU, "sceKernelReferFplStatus", 'i', "ip" }, {0X20FFF560, &WrapU_CU, "sceKernelCreateVTimer", 'x', "sx", HLE_NOT_IN_INTERRUPT }, {0X328F9E52, &WrapU_I, "sceKernelDeleteVTimer", 'x', "i", HLE_NOT_IN_INTERRUPT }, @@ -866,7 +866,7 @@ const HLEFunction ThreadManForUser[] = {0X8DAFF657, &WrapI_CUUUUU, "sceKernelCreateTlspl", 'i', "sxxxxx" }, {0X32BF938E, &WrapI_I, "sceKernelDeleteTlspl", 'i', "i" }, - {0X721067F3, &WrapI_IU, "sceKernelReferTlsplStatus", 'i', "ix" }, + {0X721067F3, &WrapI_IU, "sceKernelReferTlsplStatus", 'i', "xp" }, // Not completely certain about args. {0X4A719FB2, &WrapI_I, "sceKernelFreeTlspl", 'i', "i" }, // Internal. Takes (uid, &addr) as parameters... probably. @@ -931,7 +931,7 @@ const HLEFunction ThreadManForKernel[] = {0xF3986382, &WrapI_IUU, "sceKernelReceiveMbxCB", 'i', "ixx", HLE_KERNEL_SYSCALL | HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0x0D81716A, &WrapI_IU, "sceKernelPollMbx", 'i', "ix", HLE_KERNEL_SYSCALL }, {0x87D4DD36, &WrapI_IU, "sceKernelCancelReceiveMbx", 'i', "ix", HLE_KERNEL_SYSCALL }, - {0xA8E8C846, &WrapI_IU, "sceKernelReferMbxStatus", 'i', "ix", HLE_KERNEL_SYSCALL }, + {0xA8E8C846, &WrapI_IU, "sceKernelReferMbxStatus", 'i', "ip", HLE_KERNEL_SYSCALL }, {0x56C039B5, &WrapI_CIUUU, "sceKernelCreateVpl", 'i', "sixxx", HLE_KERNEL_SYSCALL }, {0x89B3D48C, &WrapI_I, "sceKernelDeleteVpl", 'i', "i", HLE_KERNEL_SYSCALL }, {0xBED27435, &WrapI_IUUU, "sceKernelAllocateVpl", 'i', "ixxx", HLE_KERNEL_SYSCALL | HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, @@ -939,7 +939,7 @@ const HLEFunction ThreadManForKernel[] = {0xAF36D708, &WrapI_IUU, "sceKernelTryAllocateVpl", 'i', "ixx", HLE_KERNEL_SYSCALL }, {0xB736E9FF, &WrapI_IU, "sceKernelFreeVpl", 'i', "ix", HLE_KERNEL_SYSCALL }, {0x1D371B8A, &WrapI_IU, "sceKernelCancelVpl", 'i', "ix", HLE_KERNEL_SYSCALL }, - {0x39810265, &WrapI_IU, "sceKernelReferVplStatus", 'i', "ix", HLE_KERNEL_SYSCALL }, + {0x39810265, &WrapI_IU, "sceKernelReferVplStatus", 'i', "ip", HLE_KERNEL_SYSCALL }, }; void Register_ThreadManForUser() diff --git a/Core/HLE/sceKernelEventFlag.cpp b/Core/HLE/sceKernelEventFlag.cpp index 9ea935f06d..b903f950d3 100644 --- a/Core/HLE/sceKernelEventFlag.cpp +++ b/Core/HLE/sceKernelEventFlag.cpp @@ -522,14 +522,17 @@ u32 sceKernelReferEventFlagStatus(SceUID id, u32 statusPtr) { u32 error; EventFlag *e = kernelObjects.Get(id, error); if (e) { - if (!Memory::IsValidAddress(statusPtr)) + auto status = PSPPointer::Create(statusPtr); + if (!status.IsValid()) return hleLogWarning(SCEKERNEL, -1, "invalid ptr"); HLEKernel::CleanupWaitingThreads(WAITTYPE_EVENTFLAG, id, e->waitingThreads); e->nef.numWaitThreads = (int) e->waitingThreads.size(); - if (Memory::Read_U32(statusPtr) != 0) - Memory::WriteStruct(statusPtr, &e->nef); + if (status->size != 0) { + *status = e->nef; + status.NotifyWrite("EventFlagStatus"); + } return hleLogSuccessI(SCEKERNEL, 0); } else { return hleLogDebug(SCEKERNEL, error, "invalid event flag"); diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index cffedaeb46..4c91ffe529 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -677,7 +677,7 @@ const HLEFunction Kernel_Library[] = {0XBEA46419, &WrapI_UIU, "sceKernelLockLwMutex", 'i', "xix", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0X1FC64E09, &WrapI_UIU, "sceKernelLockLwMutexCB", 'i', "xix", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0X15B6446B, &WrapI_UI, "sceKernelUnlockLwMutex", 'i', "xi" }, - {0XC1734599, &WrapI_UU, "sceKernelReferLwMutexStatus", 'i', "xx" }, + {0XC1734599, &WrapI_UU, "sceKernelReferLwMutexStatus", 'i', "xp" }, {0X293B45B8, &WrapI_V, "sceKernelGetThreadId", 'i', "" }, {0XD13BDE95, &WrapI_V, "sceKernelCheckThreadStack", 'i', "" }, {0X1839852A, &WrapU_UUU, "sceKernelMemcpy", 'x', "xxx" }, diff --git a/Core/HLE/sceKernelMbx.cpp b/Core/HLE/sceKernelMbx.cpp index 412c70188d..0a5f132f01 100644 --- a/Core/HLE/sceKernelMbx.cpp +++ b/Core/HLE/sceKernelMbx.cpp @@ -552,19 +552,17 @@ int sceKernelCancelReceiveMbx(SceUID id, u32 numWaitingThreadsAddr) return 0; } -int sceKernelReferMbxStatus(SceUID id, u32 infoAddr) -{ +int sceKernelReferMbxStatus(SceUID id, u32 infoAddr) { u32 error; Mbx *m = kernelObjects.Get(id, error); - if (!m) - { - ERROR_LOG(SCEKERNEL, "sceKernelReferMbxStatus(%i, %08x): invalid mbx id", id, infoAddr); - return error; + if (!m) { + return hleLogError(SCEKERNEL, error, "invalid mbx id"); } // Should we crash the thread somehow? - if (!Memory::IsValidAddress(infoAddr)) - return -1; + auto info = PSPPointer::Create(infoAddr); + if (!info.IsValid()) + return hleLogError(SCEKERNEL, -1, "invalid pointer"); for (int i = 0, n = m->nmb.numMessages; i < n; ++i) m->nmb.packetListHead = Memory::Read_U32(m->nmb.packetListHead); @@ -572,10 +570,10 @@ int sceKernelReferMbxStatus(SceUID id, u32 infoAddr) HLEKernel::CleanupWaitingThreads(WAITTYPE_MBX, id, m->waitingThreads); // For whatever reason, it won't write if the size (first member) is 0. - if (Memory::Read_U32(infoAddr) != 0) - { + if (info->size != 0) { m->nmb.numWaitThreads = (int) m->waitingThreads.size(); - Memory::WriteStruct(infoAddr, &m->nmb); + *info = m->nmb; + info.NotifyWrite("MbxStatus"); } return 0; diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index 3c5cce3a9f..ac853d5bb3 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -881,30 +881,26 @@ int sceKernelCancelFpl(SceUID uid, u32 numWaitThreadsPtr) } } -int sceKernelReferFplStatus(SceUID uid, u32 statusPtr) -{ +int sceKernelReferFplStatus(SceUID uid, u32 statusPtr) { u32 error; FPL *fpl = kernelObjects.Get(uid, error); - if (fpl) - { - DEBUG_LOG(SCEKERNEL, "sceKernelReferFplStatus(%i, %08x)", uid, statusPtr); + if (fpl) { // Refresh waiting threads and free block count. __KernelSortFplThreads(fpl); fpl->nf.numWaitThreads = (int) fpl->waitingThreads.size(); fpl->nf.numFreeBlocks = 0; - for (int i = 0; i < (int)fpl->nf.numBlocks; ++i) - { + for (int i = 0; i < (int)fpl->nf.numBlocks; ++i) { if (!fpl->blocks[i]) ++fpl->nf.numFreeBlocks; } - if (Memory::Read_U32(statusPtr) != 0) - Memory::WriteStruct(statusPtr, &fpl->nf); - return 0; - } - else - { - DEBUG_LOG(SCEKERNEL, "sceKernelReferFplStatus(%i, %08x): invalid fpl", uid, statusPtr); - return error; + auto status = PSPPointer::Create(statusPtr); + if (status.IsValid() && status->size != 0) { + *status = fpl->nf; + status.NotifyWrite("FplStatus"); + } + return hleLogSuccessI(SCEKERNEL, 0); + } else { + return hleLogError(SCEKERNEL, error, "invalid fpl"); } } @@ -1782,8 +1778,6 @@ int sceKernelReferVplStatus(SceUID uid, u32 infoPtr) { u32 error; VPL *vpl = kernelObjects.Get(uid, error); if (vpl) { - DEBUG_LOG(SCEKERNEL, "sceKernelReferVplStatus(%i, %08x)", uid, infoPtr); - __KernelSortVplThreads(vpl); vpl->nv.numWaitThreads = (int) vpl->waitingThreads.size(); if (vpl->header.IsValid()) { @@ -1791,12 +1785,14 @@ int sceKernelReferVplStatus(SceUID uid, u32 infoPtr) { } else { vpl->nv.freeSize = vpl->alloc.GetTotalFreeBytes(); } - if (Memory::IsValidAddress(infoPtr) && Memory::Read_U32(infoPtr) != 0) { - Memory::WriteStruct(infoPtr, &vpl->nv); + auto info = PSPPointer::Create(infoPtr); + if (info.IsValid() && info->size != 0) { + *info = vpl->nv; + info.NotifyWrite("VplStatus"); } - return 0; + return hleLogSuccessI(SCEKERNEL, 0); } else { - return error; + return hleLogError(SCEKERNEL, error, "invalid vpl"); } } @@ -2270,23 +2266,23 @@ int sceKernelFreeTlspl(SceUID uid) return error; } -int sceKernelReferTlsplStatus(SceUID uid, u32 infoPtr) -{ - DEBUG_LOG(SCEKERNEL, "sceKernelReferTlsplStatus(%08x, %08x)", uid, infoPtr); +int sceKernelReferTlsplStatus(SceUID uid, u32 infoPtr) { u32 error; TLSPL *tls = kernelObjects.Get(uid, error); - if (tls) - { + if (tls) { // Update the waiting threads in case of deletions, etc. __KernelSortTlsplThreads(tls); tls->ntls.numWaitThreads = (int) tls->waitingThreads.size(); - if (Memory::Read_U32(infoPtr) != 0) - Memory::WriteStruct(infoPtr, &tls->ntls); - return 0; + auto info = PSPPointer::Create(infoPtr); + if (info.IsValid() && info->size != 0) { + *info = tls->ntls; + info.NotifyWrite("TlsplStatus"); + } + return hleLogSuccessI(SCEKERNEL, 0); + } else { + return hleLogError(SCEKERNEL, error, "invalid tlspl"); } - else - return error; } const HLEFunction SysMemUserForUser[] = { diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 502c48fc2e..a32604e928 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -247,6 +247,10 @@ enum NativeModuleStatus { class PSPModule : public KernelObject { public: + PSPModule() { + modulePtr.ptr = 0; + } + ~PSPModule() { if (memoryBlockAddr) { // If it's either below user memory, or using a high kernel bit, it's in kernel. @@ -258,9 +262,9 @@ public: g_symbolMap->UnloadModule(memoryBlockAddr, memoryBlockSize); } - if (modulePtr) { + if (modulePtr.ptr) { //Only alloc at kernel memory. - kernelMemory.Free(modulePtr); + kernelMemory.Free(modulePtr.ptr); } } const char *GetName() override { return nm.name; } @@ -320,7 +324,7 @@ public: } if (s >= 5) { - Do(p, modulePtr); + Do(p, modulePtr.ptr); } ModuleWaitingThread mwt = {0}; @@ -454,7 +458,7 @@ public: u32 memoryBlockAddr = 0; u32 memoryBlockSize = 0; - u32 modulePtr = 0; + PSPPointer modulePtr; bool isFake = false; }; @@ -1616,11 +1620,13 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load u32 moduleSize = sizeof(module->nm); char tag[32]; snprintf(tag, sizeof(tag), "SceModule-%d", module->nm.modid); - module->modulePtr = kernelMemory.Alloc(moduleSize, true, tag); + module->modulePtr.ptr = kernelMemory.Alloc(moduleSize, true, tag); // Fill the struct. - if (Memory::IsValidAddress(module->modulePtr)) - Memory::WriteStruct(module->modulePtr, &module->nm); + if (module->modulePtr.IsValid()) { + *module->modulePtr = module->nm; + module->modulePtr.NotifyWrite("KernelModule"); + } error = 0; return module; @@ -1763,17 +1769,18 @@ void __KernelLoadReset() { } bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_string) { - SceKernelLoadExecParam param; + SceKernelLoadExecParam param{}; PSP_SetLoading("Loading exec..."); - if (paramPtr) - Memory::ReadStruct(paramPtr, ¶m); - else - memset(¶m, 0, sizeof(SceKernelLoadExecParam)); + auto paramData = PSPPointer::Create(paramPtr); + if (paramData.IsValid()) { + param = *paramData; + paramData.NotifyRead("KernelLoadExec"); + } - u8 *param_argp = 0; - u8 *param_key = 0; + u8 *param_argp = nullptr; + u8 *param_key = nullptr; if (param.args > 0) { u32 argpAddr = param.argp; param_argp = new u8[param.args]; @@ -1792,10 +1799,8 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str if (!info.exists) { ERROR_LOG(LOADER, "Failed to load executable %s - file doesn't exist", filename); *error_string = StringFromFormat("Could not find executable %s", filename); - if (paramPtr) { - if (param_argp) delete[] param_argp; - if (param_key) delete[] param_key; - } + delete[] param_argp; + delete[] param_key; __KernelShutdown(); return false; } @@ -1817,10 +1822,8 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str ERROR_LOG(LOADER, "Failed to load module %s", filename); *error_string = "Failed to load executable: " + *error_string; delete [] temp; - if (paramPtr) { - if (param_argp) delete[] param_argp; - if (param_key) delete[] param_key; - } + delete[] param_argp; + delete[] param_key; return false; } @@ -1857,8 +1860,8 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str __KernelStartIdleThreads(module->GetUID()); - if (param_argp) delete[] param_argp; - if (param_key) delete[] param_key; + delete[] param_argp; + delete[] param_key; hleSkipDeadbeef(); return true; @@ -1989,11 +1992,13 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) { u32 moduleSize = sizeof(module->nm); char tag[32]; snprintf(tag, sizeof(tag), "SceModule-%d", module->nm.modid); - module->modulePtr = kernelMemory.Alloc(moduleSize, true, tag); + module->modulePtr.ptr = kernelMemory.Alloc(moduleSize, true, tag); // Fill the struct. - if(Memory::IsValidAddress(module->modulePtr)) - Memory::WriteStruct(module->modulePtr, &module->nm); + if (module->modulePtr.IsValid()) { + *module->modulePtr = module->nm; + module->modulePtr.NotifyWrite("KernelModule"); + } // TODO: It would be more ideal to allocate memory for this module. @@ -2147,10 +2152,7 @@ int KernelStartModule(SceUID moduleId, u32 argsize, u32 argAddr, u32 returnValue static void sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 returnValueAddr, u32 optionAddr) { - SceKernelSMOption smoption = {0}; - if (optionAddr) { - Memory::ReadStruct(optionAddr, &smoption); - } + auto smoption = PSPPointer::Create(optionAddr); u32 error; PSPModule *module = kernelObjects.Get(moduleId, error); if (!module) { @@ -2176,7 +2178,7 @@ static void sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 ret moduleId,argsize,argAddr,returnValueAddr,optionAddr); bool needsWait; - int ret = KernelStartModule(moduleId, argsize, argAddr, returnValueAddr, optionAddr ? &smoption : nullptr, &needsWait); + int ret = KernelStartModule(moduleId, argsize, argAddr, returnValueAddr, smoption.PtrOrNull(), &needsWait); if (needsWait) { __KernelWaitCurThread(WAITTYPE_MODULE, moduleId, 1, 0, false, "started module"); @@ -2464,8 +2466,8 @@ u32 sceKernelFindModuleByUID(u32 uid) ERROR_LOG(SCEMODULE, "0 = sceKernelFindModuleByUID(%d): Module Not Found or Fake", uid); return 0; } - INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByUID(%d)", module->modulePtr, uid); - return module->modulePtr; + INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByUID(%d)", module->modulePtr.ptr, uid); + return module->modulePtr.ptr; } u32 sceKernelFindModuleByName(const char *name) @@ -2477,8 +2479,8 @@ u32 sceKernelFindModuleByName(const char *name) continue; if (strcmp(name, module->nm.name) == 0) { if (!module->isFake) { - INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByName(%s)", module->modulePtr, name); - return module->modulePtr; + INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByName(%s)", module->modulePtr.ptr, name); + return module->modulePtr.ptr; } else { WARN_LOG(SCEMODULE, "0 = sceKernelFindModuleByName(%s): Module Fake", name); diff --git a/Core/HLE/sceKernelMsgPipe.cpp b/Core/HLE/sceKernelMsgPipe.cpp index 253bf9ae65..b16e8060e2 100644 --- a/Core/HLE/sceKernelMsgPipe.cpp +++ b/Core/HLE/sceKernelMsgPipe.cpp @@ -1006,33 +1006,27 @@ int sceKernelCancelMsgPipe(SceUID uid, u32 numSendThreadsAddr, u32 numReceiveThr return 0; } -int sceKernelReferMsgPipeStatus(SceUID uid, u32 statusPtr) -{ +int sceKernelReferMsgPipeStatus(SceUID uid, u32 statusPtr) { u32 error; MsgPipe *m = kernelObjects.Get(uid, error); - if (m) - { - if (!Memory::IsValidAddress(statusPtr)) - { - ERROR_LOG(SCEKERNEL, "sceKernelReferMsgPipeStatus(%i, %08x): invalid address", uid, statusPtr); - return -1; + if (m) { + auto status = PSPPointer::Create(statusPtr); + if (!status.IsValid()) { + return hleLogError(SCEKERNEL, -1, "invalid address"); } - DEBUG_LOG(SCEKERNEL, "sceKernelReferMsgPipeStatus(%i, %08x)", uid, statusPtr); - // Clean up any that have timed out. m->SortReceiveThreads(); m->SortSendThreads(); m->nmp.numSendWaitThreads = (int) m->sendWaitingThreads.size(); m->nmp.numReceiveWaitThreads = (int) m->receiveWaitingThreads.size(); - if (Memory::Read_U32(statusPtr) != 0) - Memory::WriteStruct(statusPtr, &m->nmp); - return 0; - } - else - { - DEBUG_LOG(SCEKERNEL, "sceKernelReferMsgPipeStatus(%i, %08x): bad message pipe", uid, statusPtr); - return error; + if (status->size != 0) { + *status = m->nmp; + status.NotifyWrite("MsgPipeStatus"); + } + return hleLogSuccessI(SCEKERNEL, 0); + } else { + return hleLogError(SCEKERNEL, error, "bad message pipe"); } } diff --git a/Core/HLE/sceKernelMutex.cpp b/Core/HLE/sceKernelMutex.cpp index 899230142b..2cba7b5ca5 100644 --- a/Core/HLE/sceKernelMutex.cpp +++ b/Core/HLE/sceKernelMutex.cpp @@ -664,31 +664,27 @@ int sceKernelUnlockMutex(SceUID id, int count) return 0; } -int sceKernelReferMutexStatus(SceUID id, u32 infoAddr) -{ +int sceKernelReferMutexStatus(SceUID id, u32 infoAddr) { u32 error; PSPMutex *m = kernelObjects.Get(id, error); - if (!m) - { - ERROR_LOG(SCEKERNEL, "sceKernelReferMutexStatus(%i, %08x): invalid mutex id", id, infoAddr); - return error; + if (!m) { + return hleLogError(SCEKERNEL, error, "invalid mutex id"); } - DEBUG_LOG(SCEKERNEL, "sceKernelReferMutexStatus(%08x, %08x)", id, infoAddr); - // Should we crash the thread somehow? - if (!Memory::IsValidAddress(infoAddr)) - return -1; + auto info = PSPPointer::Create(infoAddr); + if (!info.IsValid()) + return hleLogError(SCEKERNEL, -1, "invalid pointer"); // Don't write if the size is 0. Anything else is A-OK, though, apparently. - if (Memory::Read_U32(infoAddr) != 0) - { + if (info->size != 0) { HLEKernel::CleanupWaitingThreads(WAITTYPE_MUTEX, id, m->waitingThreads); m->nm.numWaitThreads = (int) m->waitingThreads.size(); - Memory::WriteStruct(infoAddr, &m->nm); + *info = m->nm; + info.NotifyWrite("MutexStatus"); } - return 0; + return hleLogSuccessI(SCEKERNEL, 0); } int sceKernelCreateLwMutex(u32 workareaPtr, const char *name, u32 attr, int initialCount, u32 optionsPtr) @@ -1075,18 +1071,18 @@ int sceKernelUnlockLwMutex(u32 workareaPtr, int count) return 0; } -static int __KernelReferLwMutexStatus(SceUID uid, u32 infoPtr) -{ +static int __KernelReferLwMutexStatus(SceUID uid, u32 infoPtr) { u32 error; LwMutex *m = kernelObjects.Get(uid, error); if (!m) - return error; + return hleLogError(SCEKERNEL, error, "invalid id"); // Should we crash the thread somehow? - if (!Memory::IsValidAddress(infoPtr)) - return -1; + auto info = PSPPointer::Create(infoPtr); + if (!info.IsValid()) + return hleLogError(SCEKERNEL, -1, "invalid pointer"); - if (Memory::Read_U32(infoPtr) != 0) + if (info->size != 0) { auto workarea = m->nm.workarea; @@ -1096,44 +1092,21 @@ static int __KernelReferLwMutexStatus(SceUID uid, u32 infoPtr) m->nm.currentCount = workarea->lockLevel; m->nm.lockThread = workarea->lockThread == 0 ? SceUID_le(-1) : workarea->lockThread; m->nm.numWaitThreads = (int) m->waitingThreads.size(); - Memory::WriteStruct(infoPtr, &m->nm); + *info = m->nm; + info.NotifyWrite("LwMutexStatus"); } - return 0; + return hleLogSuccessI(SCEKERNEL, 0); } -int sceKernelReferLwMutexStatusByID(SceUID uid, u32 infoPtr) -{ - int error = __KernelReferLwMutexStatus(uid, infoPtr); - if (error >= 0) - { - DEBUG_LOG(SCEKERNEL, "sceKernelReferLwMutexStatusByID(%08x, %08x)", uid, infoPtr); - return error; - } - else - { - ERROR_LOG(SCEKERNEL, "%08x=sceKernelReferLwMutexStatusByID(%08x, %08x)", error, uid, infoPtr); - return error; - } +int sceKernelReferLwMutexStatusByID(SceUID uid, u32 infoPtr) { + return __KernelReferLwMutexStatus(uid, infoPtr); } -int sceKernelReferLwMutexStatus(u32 workareaPtr, u32 infoPtr) -{ - if (!Memory::IsValidAddress(workareaPtr)) { - ERROR_LOG(SCEKERNEL, "Bad workarea pointer for LwMutex"); - return SCE_KERNEL_ERROR_ACCESS_ERROR; - } - +int sceKernelReferLwMutexStatus(u32 workareaPtr, u32 infoPtr) { auto workarea = PSPPointer::Create(workareaPtr); + if (!workarea.IsValid()) { + return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_ACCESS_ERROR, "bad workarea pointer for LwMutex"); + } - int error = __KernelReferLwMutexStatus(workarea->uid, infoPtr); - if (error >= 0) - { - DEBUG_LOG(SCEKERNEL, "sceKernelReferLwMutexStatus(%08x, %08x)", workareaPtr, infoPtr); - return error; - } - else - { - ERROR_LOG(SCEKERNEL, "%08x=sceKernelReferLwMutexStatus(%08x, %08x)", error, workareaPtr, infoPtr); - return error; - } + return __KernelReferLwMutexStatus(workarea->uid, infoPtr); } diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index d6ebbaf2c1..fffb16c20f 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -263,28 +263,24 @@ int sceKernelDeleteSema(SceUID id) } } -int sceKernelReferSemaStatus(SceUID id, u32 infoPtr) -{ +int sceKernelReferSemaStatus(SceUID id, u32 infoPtr) { u32 error; PSPSemaphore *s = kernelObjects.Get(id, error); - if (s) - { - DEBUG_LOG(SCEKERNEL, "sceKernelReferSemaStatus(%i, %08x)", id, infoPtr); - - if (!Memory::IsValidAddress(infoPtr)) - return -1; + if (s) { + auto info = PSPPointer::Create(infoPtr); + if (!info.IsValid()) + return hleLogWarning(SCEKERNEL, -1, "invalid pointer"); HLEKernel::CleanupWaitingThreads(WAITTYPE_SEMA, id, s->waitingThreads); s->ns.numWaitThreads = (int) s->waitingThreads.size(); - if (Memory::Read_U32(infoPtr) != 0) - Memory::WriteStruct(infoPtr, &s->ns); - return 0; - } - else - { - ERROR_LOG(SCEKERNEL, "sceKernelReferSemaStatus: error %08x", error); - return error; + if (info->size != 0) { + *info = s->ns; + info.NotifyWrite("SemaStatus"); + } + return hleLogSuccessI(SCEKERNEL, 0); + } else { + return hleLogError(SCEKERNEL, error); } } diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 86a234cd3b..ea9caaba1e 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2902,13 +2902,14 @@ int sceKernelGetCallbackCount(SceUID cbId) } } -int sceKernelReferCallbackStatus(SceUID cbId, u32 statusAddr) -{ +int sceKernelReferCallbackStatus(SceUID cbId, u32 statusAddr) { u32 error; PSPCallback *c = kernelObjects.Get(cbId, error); if (c) { - if (Memory::IsValidAddress(statusAddr) && Memory::Read_U32(statusAddr) != 0) { - Memory::WriteStruct(statusAddr, &c->nc); + auto status = PSPPointer::Create(statusAddr); + if (status.IsValid() && status->size != 0) { + *status = c->nc; + status.NotifyWrite("CallbackStatus"); return hleLogSuccessI(SCEKERNEL, 0); } else { return hleLogDebug(SCEKERNEL, 0, "struct size was 0"); @@ -3789,8 +3790,10 @@ int sceKernelReferThreadEventHandlerStatus(SceUID uid, u32 infoPtr) { return hleReportError(SCEKERNEL, error, "bad handler id"); } - if (Memory::IsValidAddress(infoPtr) && Memory::Read_U32(infoPtr) != 0) { - Memory::WriteStruct(infoPtr, &teh->nteh); + auto info = PSPPointer::Create(infoPtr); + if (info.IsValid() && info->size != 0) { + *info = teh->nteh; + info.NotifyWrite("ThreadEventHandlerStatus"); return hleLogSuccessI(SCEKERNEL, 0); } else { return hleLogDebug(SCEKERNEL, 0, "struct size was 0"); diff --git a/Core/MemMap.h b/Core/MemMap.h index 306190f249..0e8863b090 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -441,11 +441,22 @@ struct PSPPointer #endif } - bool IsValid() const - { + bool IsValid() const { return Memory::IsValidRange(ptr, (u32)sizeof(T)); } + T *PtrOrNull() { + if (IsValid()) + return (T *)*this; + return nullptr; + } + + const T *PtrOrNull() const { + if (IsValid()) + return (const T *)*this; + return nullptr; + } + template void NotifyWrite(const char(&tag)[tagLen]) const { PSPPointerNotifyRW(1, (uint32_t)ptr, (uint32_t)sizeof(T), tag, tagLen - 1); diff --git a/Core/MemMapHelpers.h b/Core/MemMapHelpers.h index e623d9e768..fdee215d03 100644 --- a/Core/MemMapHelpers.h +++ b/Core/MemMapHelpers.h @@ -109,31 +109,4 @@ inline void Memcpy(const u32 to_address, const u32 from_address, const u32 len) void Memset(const u32 _Address, const u8 _Data, const u32 _iLength, const char *tag = "Memset"); -template -void ReadStruct(u32 address, T *ptr) -{ - const u32 sz = (u32)sizeof(*ptr); - Memcpy(ptr, address, sz); -} - -template -void ReadStructUnchecked(u32 address, T *ptr) -{ - const u32 sz = (u32)sizeof(*ptr); - MemcpyUnchecked(ptr, address, sz); -} - -template -void WriteStruct(u32 address, T *ptr) -{ - const u32 sz = (u32)sizeof(*ptr); - Memcpy(address, ptr, sz); -} - -template -void WriteStructUnchecked(u32 address, T *ptr) -{ - const u32 sz = (u32)sizeof(*ptr); - MemcpyUnchecked(address, ptr, sz); -} }