mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Use with same code with sceKernelStopUnloadSelfModuleWithStatus
This commit is contained in:
parent
eecd9038cd
commit
0256c7e056
2 changed files with 32 additions and 78 deletions
|
@ -1845,22 +1845,26 @@ u32 sceKernelUnloadModule(u32 moduleId)
|
||||||
return moduleId;
|
return moduleId;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 sceKernelStopUnloadSelfModule(u32 argSize, u32 argp, u32 statusAddr, u32 optionAddr) {
|
u32 hleKernelStopUnloadSelfModuleWithOrWithoutStatus(u32 exitCode, u32 argSize, u32 argp, u32 statusAddr, u32 optionAddr, bool WithStatus) {
|
||||||
// used in Tom Clancy's Splinter Cell Essentials,Ghost in the Shell Stand Alone Complex
|
|
||||||
if (loadedModules.size() > 1) {
|
if (loadedModules.size() > 1) {
|
||||||
ERROR_LOG_REPORT(SCEMODULE, "UNIMPL sceKernelStopUnloadSelfModule(%08x, %08x, %08x, %08x): game may have crashed",argSize, argp, statusAddr, optionAddr);
|
if (WithStatus)
|
||||||
|
ERROR_LOG_REPORT(SCEMODULE, "UNIMPL sceKernelStopUnloadSelfModuleWithStatus(%08x, %08x, %08x, %08x, %08x): game may have crashed", exitCode, argSize, argp, statusAddr, optionAddr);
|
||||||
|
else
|
||||||
|
ERROR_LOG_REPORT(SCEMODULE, "UNIMPL sceKernelStopUnloadSelfModule(%08x, %08x, %08x, %08x): game may have crashed", argSize, argp, statusAddr, optionAddr);
|
||||||
SceUID moduleID = __KernelGetCurThreadModuleId();
|
SceUID moduleID = __KernelGetCurThreadModuleId();
|
||||||
u32 priority = 0x20;
|
u32 priority = 0x20;
|
||||||
u32 stacksize = 0x40000;
|
u32 stacksize = 0x40000;
|
||||||
u32 attr = 0;
|
u32 attr = 0;
|
||||||
int exitCode = 0;
|
|
||||||
// TODO: In a lot of cases (even for errors), this should resched. Needs testing.
|
// TODO: In a lot of cases (even for errors), this should resched. Needs testing.
|
||||||
|
|
||||||
u32 error;
|
u32 error;
|
||||||
Module *module = kernelObjects.Get<Module>(moduleID, error);
|
Module *module = kernelObjects.Get<Module>(moduleID, error);
|
||||||
if (!module) {
|
if (!module) {
|
||||||
ERROR_LOG(SCEMODULE, "sceKernelStopUnloadSelfModule(%08x, %08x, %08x, %08x): invalid module id",argSize, argp, statusAddr, optionAddr);
|
if (WithStatus)
|
||||||
|
ERROR_LOG(SCEMODULE, "sceKernelStopUnloadSelfModuleWithStatus(%08x, %08x, %08x, %08x, %08x): invalid module id", exitCode, argSize, argp, statusAddr, optionAddr);
|
||||||
|
else
|
||||||
|
ERROR_LOG(SCEMODULE, "sceKernelStopUnloadSelfModule(%08x, %08x, %08x, %08x): invalid module id", argSize, argp, statusAddr, optionAddr);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1884,7 +1888,7 @@ u32 sceKernelStopUnloadSelfModule(u32 argSize, u32 argp, u32 statusAddr, u32 opt
|
||||||
attr = options->attribute;
|
attr = options->attribute;
|
||||||
// TODO: Maybe based on size?
|
// TODO: Maybe based on size?
|
||||||
else if (attr != 0)
|
else if (attr != 0)
|
||||||
WARN_LOG_REPORT(SCEMODULE, "Stopping module with attr=%x, but options specify 0", attr);
|
WARN_LOG_REPORT(SCEMODULE, "Stopping module with attr=%x, but options specify 0", attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Memory::IsValidAddress(stopFunc)) {
|
if (Memory::IsValidAddress(stopFunc)) {
|
||||||
|
@ -1898,92 +1902,41 @@ u32 sceKernelStopUnloadSelfModule(u32 argSize, u32 argp, u32 statusAddr, u32 opt
|
||||||
module->waitingThreads.push_back(mwt);
|
module->waitingThreads.push_back(mwt);
|
||||||
}
|
}
|
||||||
else if (stopFunc == 0) {
|
else if (stopFunc == 0) {
|
||||||
INFO_LOG(SCEMODULE, "sceKernelStopUnloadSelfModule(%08x, %08x, %08x, %08x): no stop func", argSize, argp, statusAddr, optionAddr);
|
if (WithStatus)
|
||||||
sceKernelExitDeleteThread(exitCode);
|
INFO_LOG(SCEMODULE, "sceKernelStopUnloadSelfModuleWithStatus(%08x, %08x, %08x, %08x, %08x): no stop func", exitCode, argSize, argp, statusAddr, optionAddr);
|
||||||
|
else
|
||||||
|
INFO_LOG(SCEMODULE, "sceKernelStopUnloadSelfModule(%08x, %08x, %08x, %08x): no stop func", argSize, argp, statusAddr, optionAddr);
|
||||||
|
sceKernelExitDeleteThread(exitCode);
|
||||||
module->Cleanup();
|
module->Cleanup();
|
||||||
kernelObjects.Destroy<Module>(moduleID);
|
kernelObjects.Destroy<Module>(moduleID);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ERROR_LOG_REPORT(SCEMODULE, "sceKernelStopUnloadSelfModule(%08x, %08x, %08x, %08x): bad stop func address", argSize, argp, statusAddr, optionAddr);
|
if (WithStatus)
|
||||||
|
ERROR_LOG_REPORT(SCEMODULE, "sceKernelStopUnloadSelfModuleWithStatus(%08x, %08x, %08x, %08x, %08x): bad stop func address", exitCode, argSize, argp, statusAddr, optionAddr);
|
||||||
|
else
|
||||||
|
ERROR_LOG_REPORT(SCEMODULE, "sceKernelStopUnloadSelfModule(%08x, %08x, %08x, %08x): bad stop func address", argSize, argp, statusAddr, optionAddr);
|
||||||
sceKernelExitDeleteThread(exitCode);
|
sceKernelExitDeleteThread(exitCode);
|
||||||
module->Cleanup();
|
module->Cleanup();
|
||||||
kernelObjects.Destroy<Module>(moduleID);
|
kernelObjects.Destroy<Module>(moduleID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ERROR_LOG_REPORT(SCEMODULE, "UNIMPL sceKernelStopUnloadSelfModule(%08x, %08x, %08x, %08x): game has likely crashed", argSize, argp, statusAddr, optionAddr);
|
if (WithStatus)
|
||||||
|
ERROR_LOG_REPORT(SCEMODULE, "UNIMPL sceKernelStopUnloadSelfModuleWithStatus(%08x, %08x, %08x, %08x, %08x): game has likely crashed", exitCode, argSize, argp, statusAddr, optionAddr);
|
||||||
|
else
|
||||||
|
ERROR_LOG_REPORT(SCEMODULE, "UNIMPL sceKernelStopUnloadSelfModule(%08x, %08x, %08x, %08x): game has likely crashed", argSize, argp, statusAddr, optionAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 sceKernelStopUnloadSelfModule(u32 argSize, u32 argp, u32 statusAddr, u32 optionAddr) {
|
||||||
|
// Used in Tom Clancy's Splinter Cell Essentials,Ghost in the Shell Stand Alone Complex
|
||||||
|
return hleKernelStopUnloadSelfModuleWithOrWithoutStatus(0, argSize, argp, statusAddr, optionAddr, false);
|
||||||
|
}
|
||||||
|
|
||||||
u32 sceKernelStopUnloadSelfModuleWithStatus(u32 exitCode, u32 argSize, u32 argp, u32 statusAddr, u32 optionAddr) {
|
u32 sceKernelStopUnloadSelfModuleWithStatus(u32 exitCode, u32 argSize, u32 argp, u32 statusAddr, u32 optionAddr) {
|
||||||
if (loadedModules.size() > 1) {
|
return hleKernelStopUnloadSelfModuleWithOrWithoutStatus(exitCode, argSize, argp, statusAddr, optionAddr, true);
|
||||||
ERROR_LOG_REPORT(SCEMODULE, "UNIMPL sceKernelStopUnloadSelfModuleWithStatus(%08x, %08x, %08x, %08x, %08x): game may have crashed", exitCode, argSize, argp, statusAddr, optionAddr);
|
|
||||||
|
|
||||||
SceUID moduleID = __KernelGetCurThreadModuleId();
|
|
||||||
u32 priority = 0x20;
|
|
||||||
u32 stacksize = 0x40000;
|
|
||||||
u32 attr = 0;
|
|
||||||
|
|
||||||
// TODO: In a lot of cases (even for errors), this should resched. Needs testing.
|
|
||||||
|
|
||||||
u32 error;
|
|
||||||
Module *module = kernelObjects.Get<Module>(moduleID, error);
|
|
||||||
if (!module) {
|
|
||||||
ERROR_LOG(SCEMODULE, "sceKernelStopUnloadSelfModuleWithStatus(%08x, %08x, %08x, %08x, %08x): invalid module id", exitCode, argSize, argp, statusAddr, optionAddr);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 stopFunc = module->nm.module_stop_func;
|
|
||||||
if (module->nm.module_stop_thread_priority != 0)
|
|
||||||
priority = module->nm.module_stop_thread_priority;
|
|
||||||
if (module->nm.module_stop_thread_stacksize != 0)
|
|
||||||
stacksize = module->nm.module_stop_thread_stacksize;
|
|
||||||
if (module->nm.module_stop_thread_attr != 0)
|
|
||||||
attr = module->nm.module_stop_thread_attr;
|
|
||||||
|
|
||||||
// TODO: Need to test how this really works. Let's assume it's an override.
|
|
||||||
if (Memory::IsValidAddress(optionAddr)) {
|
|
||||||
auto options = PSPPointer<SceKernelSMOption>::Create(optionAddr);
|
|
||||||
// TODO: Check how size handling actually works.
|
|
||||||
if (options->size != 0 && options->priority != 0)
|
|
||||||
priority = options->priority;
|
|
||||||
if (options->size != 0 && options->stacksize != 0)
|
|
||||||
stacksize = options->stacksize;
|
|
||||||
if (options->size != 0 && options->attribute != 0)
|
|
||||||
attr = options->attribute;
|
|
||||||
// TODO: Maybe based on size?
|
|
||||||
else if (attr != 0)
|
|
||||||
WARN_LOG_REPORT(SCEMODULE, "Stopping module with attr=%x, but options specify 0", attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Memory::IsValidAddress(stopFunc)) {
|
|
||||||
SceUID threadID = __KernelCreateThread(module->nm.name, moduleID, stopFunc, priority, stacksize, attr, 0);
|
|
||||||
sceKernelStartThread(threadID, argSize, argp);
|
|
||||||
__KernelSetThreadRA(threadID, NID_MODULERETURN);
|
|
||||||
__KernelWaitCurThread(WAITTYPE_MODULE, moduleID, 1, 0, false, "unloadstopped module");
|
|
||||||
|
|
||||||
const ModuleWaitingThread mwt = {__KernelGetCurThread(), statusAddr};
|
|
||||||
module->nm.status = MODULE_STATUS_UNLOADING;
|
|
||||||
module->waitingThreads.push_back(mwt);
|
|
||||||
} else if (stopFunc == 0) {
|
|
||||||
INFO_LOG(SCEMODULE, "sceKernelStopUnloadSelfModuleWithStatus(%08x, %08x, %08x, %08x, %08x): no stop func", exitCode, argSize, argp, statusAddr, optionAddr);
|
|
||||||
sceKernelExitDeleteThread(exitCode);
|
|
||||||
module->Cleanup();
|
|
||||||
kernelObjects.Destroy<Module>(moduleID);
|
|
||||||
} else {
|
|
||||||
ERROR_LOG_REPORT(SCEMODULE, "sceKernelStopUnloadSelfModuleWithStatus(%08x, %08x, %08x, %08x, %08x): bad stop func address", exitCode, argSize, argp, statusAddr, optionAddr);
|
|
||||||
sceKernelExitDeleteThread(exitCode);
|
|
||||||
module->Cleanup();
|
|
||||||
kernelObjects.Destroy<Module>(moduleID);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ERROR_LOG_REPORT(SCEMODULE, "UNIMPL sceKernelStopUnloadSelfModuleWithStatus(%08x, %08x, %08x, %08x, %08x): game has likely crashed", exitCode, argSize, argp, statusAddr, optionAddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Probably similar to sceKernelStopModule, but games generally call this when they die.
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __KernelReturnFromModuleFunc()
|
void __KernelReturnFromModuleFunc()
|
||||||
|
|
|
@ -29,6 +29,7 @@ void __KernelModuleShutdown();
|
||||||
u32 __KernelGetModuleGP(SceUID module);
|
u32 __KernelGetModuleGP(SceUID module);
|
||||||
bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_string);
|
bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_string);
|
||||||
void __KernelReturnFromModuleFunc();
|
void __KernelReturnFromModuleFunc();
|
||||||
|
u32 hleKernelStopUnloadSelfModuleWithOrWithoutStatus(u32 exitCode, u32 argSize, u32 argp, u32 statusAddr, u32 optionAddr, bool WithStatus);
|
||||||
|
|
||||||
void Register_ModuleMgrForUser();
|
void Register_ModuleMgrForUser();
|
||||||
void Register_ModuleMgrForKernel();
|
void Register_ModuleMgrForKernel();
|
Loading…
Add table
Reference in a new issue