Add ability to flag function to clear a bit of stack. See #6374, idea by JPCSP, pointed out by sum2012.

This commit is contained in:
Henrik Rydgard 2015-03-02 01:03:12 +01:00
parent acdd0807f5
commit fd1dcb881f
5 changed files with 28 additions and 10 deletions

View File

@ -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);

View File

@ -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

View File

@ -1355,7 +1355,7 @@ static int sceFontGetShadowGlyphImage_Clip(u32 fontHandle, u32 charCode, u32 gly
}
const HLEFunction sceLibFont[] = {
{0x67f17ed7, WrapU_UU<sceFontNewLib>, "sceFontNewLib"},
{0x67f17ed7, WrapU_UU<sceFontNewLib>, "sceFontNewLib", HLE_CLEAR_STACK_BYTES, 0x590},
{0x574b6fbc, WrapI_U<sceFontDoneLib>, "sceFontDoneLib"},
{0x48293280, WrapI_UFF<sceFontSetResolution>, "sceFontSetResolution"},
{0x27f6e642, WrapI_UU<sceFontGetNumFontList>, "sceFontGetNumFontList"},
@ -1366,14 +1366,14 @@ const HLEFunction sceLibFont[] = {
{0x5333322d, WrapI_UUU<sceFontGetFontInfoByIndexNumber>, "sceFontGetFontInfoByIndexNumber"},
{0xa834319d, WrapU_UUUU<sceFontOpen>, "sceFontOpen"},
{0x57fcb733, WrapU_UCUU<sceFontOpenUserFile>, "sceFontOpenUserFile"},
{0xbb8e7fe6, WrapU_UUUU<sceFontOpenUserMemory>, "sceFontOpenUserMemory"},
{0xbb8e7fe6, WrapU_UUUU<sceFontOpenUserMemory>, "sceFontOpenUserMemory", HLE_CLEAR_STACK_BYTES, 0x440},
{0x3aea8cb6, WrapI_U<sceFontClose>, "sceFontClose"},
{0x0da7535e, WrapI_UU<sceFontGetFontInfo>, "sceFontGetFontInfo"},
{0xdcc80c2f, WrapI_UUU<sceFontGetCharInfo>, "sceFontGetCharInfo"},
{0xdcc80c2f, WrapI_UUU<sceFontGetCharInfo>, "sceFontGetCharInfo", HLE_CLEAR_STACK_BYTES, 0x100},
{0xaa3de7b5, WrapI_UUU<sceFontGetShadowInfo>, "sceFontGetShadowInfo"},
{0x5c3e4a9e, WrapI_UUU<sceFontGetCharImageRect>, "sceFontGetCharImageRect"},
{0x48b06520, WrapI_UUU<sceFontGetShadowImageRect>, "sceFontGetShadowImageRect"},
{0x980f4895, WrapI_UUU<sceFontGetCharGlyphImage>, "sceFontGetCharGlyphImage"},
{0x980f4895, WrapI_UUU<sceFontGetCharGlyphImage>, "sceFontGetCharGlyphImage", HLE_CLEAR_STACK_BYTES, 0x120},
{0xca1e6945, WrapI_UUUIIII<sceFontGetCharGlyphImage_Clip>, "sceFontGetCharGlyphImage_Clip"},
{0x74b21701, WrapF_IFU<sceFontPixelToPointH>, "sceFontPixelToPointH"},
{0xf8f0752e, WrapF_IFU<sceFontPixelToPointV>, "sceFontPixelToPointV"},

View File

@ -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);

View File

@ -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);