diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index 758d5abf24d2..13d5961bcd78 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -435,18 +435,24 @@ inline void updateSyscallStats(int modulenum, int funcnum, double total) inline void CallSyscallWithFlags(const HLEFunction *info) { const u32 flags = info->flags; - if ((flags & HLE_NOT_DISPATCH_SUSPENDED) && !__KernelIsDispatchEnabled()) - { + + if (flags & HLE_CLEAR_STACK_BYTES) { + u32 stackStart = __KernelGetCurThreadStackStart(); + if (currentMIPS->r[MIPS_REG_SP] - info->stackBytesToClear >= stackStart) { + Memory::Memset(currentMIPS->r[MIPS_REG_SP] - info->stackBytesToClear, 0, info->stackBytesToClear); + } + } + + if ((flags & HLE_NOT_DISPATCH_SUSPENDED) && !__KernelIsDispatchEnabled()) { DEBUG_LOG(HLE, "%s: dispatch suspended", info->name); RETURN(SCE_KERNEL_ERROR_CAN_NOT_WAIT); } - else if ((flags & HLE_NOT_IN_INTERRUPT) && __IsInInterrupt()) - { + else if ((flags & HLE_NOT_IN_INTERRUPT) && __IsInInterrupt()) { DEBUG_LOG(HLE, "%s: in interrupt", info->name); RETURN(SCE_KERNEL_ERROR_ILLEGAL_CONTEXT); - } - else + } else { info->func(); + } if (hleAfterSyscall != HLE_AFTER_NOTHING) hleFinishSyscall(*info); @@ -516,6 +522,7 @@ void CallSyscall(MIPSOpcode op) time_update(); start = time_now_d(); } + const HLEFunction *info = GetSyscallInfo(op); if (!info) { RETURN(SCE_KERNEL_ERROR_LIBRARY_NOT_YET_LINKED); diff --git a/Core/HLE/HLE.h b/Core/HLE/HLE.h index d57659e742bc..46eb3dfd832e 100644 --- a/Core/HLE/HLE.h +++ b/Core/HLE/HLE.h @@ -32,6 +32,7 @@ enum { HLE_NOT_IN_INTERRUPT = 1 << 8, // Don't allow the call if dispatch or interrupts are disabled. HLE_NOT_DISPATCH_SUSPENDED = 1 << 9, + HLE_CLEAR_STACK_BYTES = 1 << 10 }; struct HLEFunction @@ -40,6 +41,7 @@ struct HLEFunction HLEFunc func; const char *name; u32 flags; + u32 stackBytesToClear; }; struct HLEModule diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index be1a77d4a8b6..b22f741b28d1 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -1355,7 +1355,7 @@ static int sceFontGetShadowGlyphImage_Clip(u32 fontHandle, u32 charCode, u32 gly } const HLEFunction sceLibFont[] = { - {0x67f17ed7, WrapU_UU, "sceFontNewLib"}, + {0x67f17ed7, WrapU_UU, "sceFontNewLib", HLE_CLEAR_STACK_BYTES, 0x590}, {0x574b6fbc, WrapI_U, "sceFontDoneLib"}, {0x48293280, WrapI_UFF, "sceFontSetResolution"}, {0x27f6e642, WrapI_UU, "sceFontGetNumFontList"}, @@ -1366,14 +1366,14 @@ const HLEFunction sceLibFont[] = { {0x5333322d, WrapI_UUU, "sceFontGetFontInfoByIndexNumber"}, {0xa834319d, WrapU_UUUU, "sceFontOpen"}, {0x57fcb733, WrapU_UCUU, "sceFontOpenUserFile"}, - {0xbb8e7fe6, WrapU_UUUU, "sceFontOpenUserMemory"}, + {0xbb8e7fe6, WrapU_UUUU, "sceFontOpenUserMemory", HLE_CLEAR_STACK_BYTES, 0x440}, {0x3aea8cb6, WrapI_U, "sceFontClose"}, {0x0da7535e, WrapI_UU, "sceFontGetFontInfo"}, - {0xdcc80c2f, WrapI_UUU, "sceFontGetCharInfo"}, + {0xdcc80c2f, WrapI_UUU, "sceFontGetCharInfo", HLE_CLEAR_STACK_BYTES, 0x100}, {0xaa3de7b5, WrapI_UUU, "sceFontGetShadowInfo"}, {0x5c3e4a9e, WrapI_UUU, "sceFontGetCharImageRect"}, {0x48b06520, WrapI_UUU, "sceFontGetShadowImageRect"}, - {0x980f4895, WrapI_UUU, "sceFontGetCharGlyphImage"}, + {0x980f4895, WrapI_UUU, "sceFontGetCharGlyphImage", HLE_CLEAR_STACK_BYTES, 0x120}, {0xca1e6945, WrapI_UUUIIII, "sceFontGetCharGlyphImage_Clip"}, {0x74b21701, WrapF_IFU, "sceFontPixelToPointH"}, {0xf8f0752e, WrapF_IFU, "sceFontPixelToPointV"}, diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index e7675c28c091..678f4f12ab36 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2538,6 +2538,14 @@ u32 __KernelGetCurThreadStack() return 0; } +u32 __KernelGetCurThreadStackStart() +{ + Thread *t = __GetCurrentThread(); + if (t) + return t->currentStack.start; + return 0; +} + SceUID sceKernelGetThreadId() { VERBOSE_LOG(SCEKERNEL, "%i = sceKernelGetThreadId()", currentThread); diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index a9e688a1e372..8376de43a72f 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -159,6 +159,7 @@ KernelObject *__KernelCallbackObject(); void __KernelScheduleWakeup(int threadnumber, s64 usFromNow); SceUID __KernelGetCurThread(); u32 __KernelGetCurThreadStack(); +u32 __KernelGetCurThreadStackStart(); const char *__KernelGetThreadName(SceUID threadID); void __KernelSaveContext(ThreadContext *ctx, bool vfpuEnabled);