Beispiel #1
0
void testCheckStackLayout(const char *title, int argSize, u32 attr) {
	char argLengthTemp[0x1000];
	memset(argLengthTemp, 0xAB, sizeof(argLengthTemp));

	// First create the thread to wipe the stack area, that way we can see what it'd look like clean.
	SceUID stackCheckThread = sceKernelCreateThread("stackCheck", &stackCheckFunc, 0x10, 0x1000, attr, NULL);
	stackCheckInfo.size = sizeof(stackCheckInfo);
	sceKernelReferThreadStatus(stackCheckThread, &stackCheckInfo);
	sceKernelTerminateDeleteThread(stackCheckThread);
	memset(stackCheckInfo.stack, 0xCC, stackCheckInfo.stackSize);

	stackCheckName = title;
	stackCheckThread = sceKernelCreateThread("stackCheck", &stackCheckFunc, 0x10, 0x1000, attr, NULL);
	sceKernelStartThread(stackCheckThread, argSize, argLengthTemp);
	sceKernelWaitThreadEnd(stackCheckThread, NULL);

	u32 *stack = (u32 *) stackCheckInfo.stack;
	stack[1] = 0xFF1337FF;

	sceKernelTerminateDeleteThread(stackCheckThread);

	if (stack[1] != 0xFF1337FF) {
		schedf("    %s: WARNING: stack cleared to something after delete: %08x.\n", stackCheckName, stack[1]);
	}

	checkpoint("%s", title);
}
Beispiel #2
0
int clear_thread(SceSize args, void *argp)
{
    int result;
    u32 outBits;
    SceKernelThreadInfo info;
    info.size = sizeof(SceKernelThreadInfo);

    sceKernelReferThreadStatus (0, &info);
    printf("thread '%-12s' sp %p pattern %08x START\n", info.name, info.stack, CLEAR_PATTERN);

    while(!done)
    {
        // 0x00FF00FF initPattern
        // 0x000000FF should work - ok
        // 0x00000FF0 should fail - ok
        // 0x0000FF00 should fail - ok

        outBits = 0xbaadc0de;
        result = sceKernelWaitEventFlag(evid, CLEAR_PATTERN, PSP_EVENT_WAITCLEAR, &outBits, 0);
        printf("thread '%-12s' result %08x outBits %08x\n", info.name, result, (int)outBits);

        sceKernelSleepThreadCB();
    }

    return 0;
}
Beispiel #3
0
int or_thread(SceSize args, void *argp)
{
    int result;
    u32 outBits;
    SceKernelThreadInfo info;
    info.size = sizeof(SceKernelThreadInfo);

    sceKernelReferThreadStatus (0, &info);
    printf("thread '%-12s' sp %p pattern %08x START\n", info.name, info.stack, OR_PATTERN);

    while(!done)
    {
        // 0x00FF00FF initPattern
        // 0x000000FF should work - ok
        // 0x00000FF0 should work - ok
        // 0x0000FF00 should fail - ok

        outBits = 0xbaadc0de;
        volatile SceUInt timeout = 1000*1000*5;
        //result = sceKernelWaitEventFlag(evid, OR_PATTERN, PSP_EVENT_WAITOR, &outBits, &timeout);
        result = sceKernelWaitEventFlag(evid, OR_PATTERN, PSP_EVENT_WAITOR, &outBits, 0);
        printf("thread '%-12s' result %08x outBits %08x\n", info.name, result, (int)outBits);

        //if (timeout) timeout = *(int*)timeout;
        printf("timeout %d/%08x\n", (int)timeout, (int)timeout);


        sceKernelSleepThreadCB();
    }

    return 0;
}
Beispiel #4
0
int control_module_threads(SceUID module_id, int pause) {
    // get an array of all threads
    int thread_count;
    if (sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Thread, NULL, 0, &thread_count) < 0)
        return 0;
    if (thread_count < 1)
        return 0;
    SceUID thread_id[thread_count];
    if (sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Thread, thread_id, thread_count, NULL) < 0)
        return 0;
    int i;
    SceModule* module;
    SceKernelThreadInfo thread_info;
    thread_info.size = sizeof(SceKernelThreadInfo);
    for (i = 0; i < thread_count; i++) {
        // determine if a thread is from the game
        if (sceKernelReferThreadStatus(thread_id[i], &thread_info))
            continue;
        module = sceKernelFindModuleByAddress((unsigned int) thread_info.entry);
        if (module && module->modid == module_id) {
            // pause or resume the thread
            if (pause)
                sceKernelSuspendThread(thread_id[i]);
            else
                sceKernelResumeThread(thread_id[i]);
        }
    }
    return 1;
}
Beispiel #5
0
int threadCtrlSuspend()
{
	if (threadCtrlState() == THREAD_CTRL_STATE_SUSPEND) {
		return 1;
	}
	
	int i, n;
	SceUID this_thid;
	SceKernelThreadInfo thinfo;
	
	this_thid = sceKernelGetThreadId();
	
	sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Thread, current_thid, MAX_THREAD, &current_count);
	
	for (i = 0;i < current_count;i++) {
		memset(&thinfo, 0, sizeof(SceKernelThreadInfo));
		thinfo.size = sizeof(SceKernelThreadInfo);
		sceKernelReferThreadStatus(current_thid[i], &thinfo);
		
		if (thinfo.status & PSP_THREAD_SUSPEND || current_thid[i] == this_thid) {
			current_thid[i] = -1;
			continue;
		}
		for (n = 0;n < first_count;n++) {
			if (current_thid[i] == first_thid[n]) {
				current_thid[i] = -1;
				break;
			}
		}
	}
	
	/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
	/*      I got a hint from taba's JPCheat, thanks!        */
	/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
	if (use_safely_suspend) {
		int count;
		for (count = 0;count < 1000;count++) {
			if ((IO_MEM_STICK_STATUS & 0x2000) == 0) {
				count = 0;
			}
			sceKernelDelayThread(1);
		}
	}
	/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
	
	for (i = 0;i < current_count;i++) {
		if (current_thid[i] >= 0) {
			sceKernelSuspendThread(current_thid[i]);
		}
	}
	
	return 0;
}
Beispiel #6
0
static void PSPAUDIO_ThreadInit(_THIS)
{
    /* Increase the priority of this audio thread by 1 to put it
       ahead of other SDL threads. */
    SceUID thid;
    SceKernelThreadInfo status;
    thid = sceKernelGetThreadId();
    status.size = sizeof(SceKernelThreadInfo);
    if (sceKernelReferThreadStatus(thid, &status) == 0) {
        sceKernelChangeThreadPriority(thid, status.currentPriority - 1);
    }
}
Beispiel #7
0
// returns the result of sceKernelReferThreadStatus
int referThread(int thid)
{
    int result;
    SceKernelThreadInfo info;
    memset(&info, 0, sizeof(info));
    info.size = sizeof(SceKernelThreadInfo);
    result = sceKernelReferThreadStatus(thid, &info);
    printf("[%s] pri:%02x status:%02x waitType:%02x\n", info.name, info.currentPriority, info.status, info.waitType);

    if (info.status & PSP_THREAD_RUNNING) printf("  RUNNING\n");
    if (info.status & PSP_THREAD_READY) printf("  READY\n");
    if (info.status & PSP_THREAD_WAITING) printf("  WAITING\n");
    if (info.status & PSP_THREAD_SUSPEND) printf("  SUSPEND\n");
    if (info.status & PSP_THREAD_STOPPED) printf("  STOPPED\n");
    if (info.status & PSP_THREAD_KILLED) printf("  KILLED\n");

    return result;
}
Beispiel #8
0
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{
    SceKernelThreadInfo status;
    int priority = 32;

    /* Set priority of new thread to the same as the current thread */
    status.size = sizeof(SceKernelThreadInfo);
    if (sceKernelReferThreadStatus(sceKernelGetThreadId(), &status) == 0) {
        priority = status.currentPriority;
    }

    thread->handle = sceKernelCreateThread(thread->name, ThreadEntry,
                           priority, thread->stacksize ? ((int) thread->stacksize) : 0x8000,
                           PSP_THREAD_ATTR_VFPU, NULL);
    if (thread->handle < 0) {
        return SDL_SetError("sceKernelCreateThread() failed");
    }

    sceKernelStartThread(thread->handle, 4, &args);
    return 0;
}
Beispiel #9
0
/* Dump the current thread's status */
void dump_threadstatus(void)
{
	int thid;
	SceKernelThreadInfo status;
	int ret;

	thid = sceKernelGetThreadId();
	memset(&status, 0, sizeof(SceKernelThreadInfo));
	printf("Thread ID: %08X\n", thid);
	status.size = sizeof(SceKernelThreadInfo);
	ret = sceKernelReferThreadStatus(thid, &status); 
	printf("Get Thread Status: %08X\n", ret);
	if(ret == 0)
	{
		printf("Name: %s\n", status.name);
		printf("Thread Addr: %p\n", status.entry);
		printf("Stack Addr: %p\n", status.stack);
		printf("Stack Size: %08X\n", status.stackSize);
		printf("gp: %p\n", status.gpReg);
		printf("Initial Pri: %x\n", status.initPriority);
		printf("Current Pri: %x\n", status.currentPriority);
	}
}
Beispiel #10
0
void syscallLog(const SyscallInfo *syscallInfo, const u32 *parameters, u64 result, u32 ra, const char *prefix) {
	char buffer[300];
	char *s = buffer;
	int i, j, k;
	int length;
	int lineStart;

	// Don't log out own sceIoWrites.
	if (syscallInfo->nid == 0x42EC03AC && parameters[0] == commonInfo->logFd) {
		return;
	}

	if (logTimestamp) {
		pspTime time;
		if (sceRtcGetCurrentClockLocalTime(&time) == 0) {
			s = appendInt(s, time.hour, 2);
			*s++ = ':';
			s = appendInt(s, time.minutes, 2);
			*s++ = ':';
			s = appendInt(s, time.seconds, 2);
			*s++ = '.';
			s = appendInt(s, time.microseconds, 6);
			*s++ = ' ';
		}
	}

	if (logThreadName) {
		SceKernelThreadInfo currentThreadInfo;
		currentThreadInfo.size = sizeof(currentThreadInfo);
		currentThreadInfo.name[0] = '\0';
		sceKernelReferThreadStatus(0, &currentThreadInfo);

		s = append(s, currentThreadInfo.name);
		*s++ = ' ';
		*s++ = '-';
		*s++ = ' ';
	}

	if (logRa) {
		s = appendHex(s, ra, 0);
		*s++ = ' ';
	}

	s = append(s, prefix);
	s = append(s, syscallInfo->name);
	int types = syscallInfo->paramTypes;
	for (i = 0; i < syscallInfo->numParams; i++, types >>= 4) {
		if (i > 0) {
			*s++ = ',';
		}
		*s++ = ' ';
		int parameter = parameters[i];
		switch (types & 0xF) {
			case TYPE_HEX32:
				s = appendHex(s, parameter, 0);
				break;
			case TYPE_INT32:
				s = appendInt(s, parameter, 0);
				break;
			case TYPE_STRING:
				s = appendHex(s, parameter, 8);
				if (parameter != 0) {
					*s++ = '(';
					*s++ = '\'';
					s = append(s, (char *) parameter);
					*s++ = '\'';
					*s++ = ')';
				}
				break;
			case TYPE_POINTER32:
				s = appendHex(s, parameter, 8);
				if (parameter != 0) {
					*s++ = '(';
					s = appendHex(s, _lw(parameter), 0);
					*s++ = ')';
				}
				break;
			case TYPE_POINTER64:
				s = appendHex(s, parameter, 8);
				if (parameter != 0) {
					*s++ = '(';
					s = appendHex(s, _lw(parameter), 8);
					*s++ = ' ';
					s = appendHex(s, _lw(parameter + 4), 8);
					*s++ = ')';
				}
				break;
			case TYPE_VARSTRUCT:
				s = appendHex(s, parameter, 8);
				if (parameter != 0) {
					*s++ = ':';
					*s++ = '\n';
					writeLog(buffer, s - buffer);
					s = buffer;
					length = _lw(parameter);
					lineStart = 0;
					for (j = 0; j < length; j += 4) {
						if (j > 0) {
							if ((j % 16) == 0) {
								s = append(s, "  >");
								for (k = lineStart; k < j; k++) {
									char c = _lb(parameter + k);
									if (c < ' ' || c > '~') {
										c = '.';
									}
									*s++ = c;
								}
								s = append(s, "<\n");
								writeLog(buffer, s - buffer);
								s = buffer;
								lineStart = j;
							} else {
								*s++ = ',';
								*s++ = ' ';
							}
						}
						s = appendHex(s, _lw(parameter + j), 8);
					}
				}
				break;
			case TYPE_FIXSTRUCT:
				s = appendHex(s, parameter, 8);
				if (parameter != 0) {
					*s++ = ':';
					*s++ = '\n';
					writeLog(buffer, s - buffer);
					s = buffer;
					length = FIXSTRUCT_SIZE;
					lineStart = 0;
					for (j = 0; j < length; j += 4) {
						if (j > 0) {
							if ((j % 16) == 0) {
								s = append(s, "  >");
								for (k = lineStart; k < j; k++) {
									char c = _lb(parameter + k);
									if (c < ' ' || c > '~') {
										c = '.';
									}
									*s++ = c;
								}
								s = append(s, "<\n");
								writeLog(buffer, s - buffer);
								s = buffer;
								lineStart = j;
							} else {
								*s++ = ',';
								*s++ = ' ';
							}
						}
						s = appendHex(s, _lw(parameter + j), 8);
					}
				}
				break;
		}
	}
	*s++ = ' ';
	*s++ = '=';
	*s++ = ' ';
	s = appendHex(s, (int) result, 0);

	#if DEBUG_MUTEX
	s = mutexLog(s, syscallInfo, parameters, result);
	#endif

	*s++ = '\n';
	writeLog(buffer, s - buffer);

	#if DEBUG_UTILITY_SAVEDATA
	utilitySavedataLog(buffer, syscallInfo, parameters[0]);
	#endif
}
void runReferTests() {
	SceKernelThreadInfo2 info;
	int i;
	SceUID delayThread = sceKernelCreateThread("delay", &delayFunc, sceKernelGetThreadCurrentPriority(), 0x1000, PSP_THREAD_ATTR_VFPU, NULL);
	SceUID deletedThread = sceKernelCreateThread("deleted", &delayFunc, sceKernelGetThreadCurrentPriority(), 0x1000, 0, NULL);
	sceKernelDeleteThread(deletedThread);

	info.size = sizeof(info);

	checkpointNext("Thread IDs:");
	checkpoint("  NULL: %08x", sceKernelReferThreadStatus(0, &info));
	checkpoint("  Current: %08x", sceKernelReferThreadStatus(sceKernelGetThreadId(), &info));
	checkpoint("  Deleted: %08x", sceKernelReferThreadStatus(deletedThread, &info));
	checkpoint("  Invalid: %08x", sceKernelReferThreadStatus(0xDEADBEEF, &info));

	// Crashes.
	//checkpointNext("sceKernelReferThreadStatus info ptr:");
	//checkpoint("  NULL info: %08x", sceKernelReferThreadStatus(0, NULL));

	checkpointNext("Sizes:");
	int sizes[] = {-1, 0, 1, 2, 3, 4, 5, 8, 16, 32, 64, 80, 82, 108, 128, 1024};
	for (i = 0; i < ARRAY_SIZE(sizes); ++i) {
		memset(&info, 0xff, sizeof(info));
		info.size = sizes[i];
		int result = sceKernelReferThreadStatus(0, &info);
		checkpoint("  %d: %08x => %d (exit: %x)", sizes[i], result, info.size, info.exitStatus);
	}

	info.size = sizeof(info);
	sceKernelStartThread(delayThread, 0, NULL);
	sceKernelReferThreadStatus(delayThread, &info);
	checkpointNext("Values:");
	schedfThreadInfo(&info, &delayFunc);

	SceUID slumberThread = sceKernelCreateThread("slumber", &slumberFunc, sceKernelGetThreadCurrentPriority() - 1, 0x1000, 0, NULL);

	checkpoint("  slumber before start:");
	sceKernelReferThreadStatus(slumberThread, &info);
	schedfThreadInfo(&info, &slumberFunc);

	sceKernelStartThread(slumberThread, 0, NULL);
	checkpoint("  started slumber");

	checkpoint("  slumber after start:");
	sceKernelReferThreadStatus(slumberThread, &info);
	schedfThreadInfo(&info, &slumberFunc);

	sceKernelTerminateThread(slumberThread);
	checkpoint("  terminated slumber");

	checkpoint("  slumber after terminate:");
	sceKernelReferThreadStatus(slumberThread, &info);
	schedfThreadInfo(&info, &slumberFunc);

	sceKernelStartThread(slumberThread, 0, NULL);
	checkpoint("  started slumber");

	checkpoint("  slumber after start:");
	sceKernelReferThreadStatus(slumberThread, &info);
	schedfThreadInfo(&info, &slumberFunc);

	checkpoint("  woke slumber: %08x", sceKernelWakeupThread(slumberThread));

	checkpoint("  slumber after wake:");
	sceKernelReferThreadStatus(slumberThread, &info);
	schedfThreadInfo(&info, &slumberFunc);

	sceKernelTerminateDeleteThread(slumberThread);
	checkpoint("  terminated and deleted slumber");

	// TODO: Test more cases.

	flushschedf();
}
Beispiel #12
0
int main(int argc, char *argv[]) {
	int i, result;
	SceKernelThreadInfo info;
	SceUID testThread = sceKernelCreateThread("test", &testFunc, sceKernelGetThreadCurrentPriority(), 0x1000, 0, NULL);
	SceUID deletedThread = sceKernelCreateThread("deleted", &testFunc, sceKernelGetThreadCurrentPriority(), 0x1000, 0, NULL);
	sceKernelDeleteThread(deletedThread);

	checkpointNext("Thread IDs:");
	checkpoint("  Normal: %08x", sceKernelStartThread(testThread, 0, NULL));
	checkpoint("  Twice: %08x", sceKernelStartThread(testThread, 0, NULL));
	checkpoint("  NULL: %08x", sceKernelStartThread(0, 0, NULL));
	checkpoint("  Current: %08x", sceKernelStartThread(sceKernelGetThreadId(), 0, NULL));
	checkpoint("  Deleted: %08x", sceKernelStartThread(deletedThread, 0, NULL));
	checkpoint("  Invalid: %08x", sceKernelStartThread(0xDEADBEEF, 0, NULL));

	checkpointNext("Argument length:");
	SceUID argLengthThread = sceKernelCreateThread("argLength", &argLengthFunc, sceKernelGetThreadCurrentPriority() - 1, 0x800, 0, NULL);
	char argLengthTemp[0x1000];
	void *argLengthStack;

	info.size = sizeof(info);
	sceKernelReferThreadStatus(argLengthThread, &info);
	argLengthStack = info.stack;

	result = sceKernelStartThread(argLengthThread, 8, NULL);
	sceKernelWaitThreadEnd(argLengthThread, NULL);
	char temp[256];
	if (argLengthArgv == 0)
		sprintf(temp, "NULL");
	else if (argLengthArgv == argLengthTemp)
		sprintf(temp, "original");
	else
		sprintf(temp, "stack+0x%x", (char *)argLengthArgv - (char *)argLengthStack);
	checkpoint("  With NULL ptr: %08x (%d, %s)", result, argLengthArgc, temp);

	// Note: larger than stack seems to crash the PSP...
	static int lengths[] = {-1, 0x80000000, 0, 1, 2, 3, 4, 5, 6, 7, 8, 80, 90, 0x600};
	for (i = 0; i < ARRAY_SIZE(lengths); ++i) {
		argLengthArgc = -1;
		argLengthArgv = NULL;
		result = sceKernelStartThread(argLengthThread, lengths[i], argLengthTemp);
		sceKernelWaitThreadEnd(argLengthThread, NULL);

		if (argLengthArgv == 0)
			sprintf(temp, "NULL");
		else if (argLengthArgv == argLengthTemp)
			sprintf(temp, "original");
		else
			sprintf(temp, "stack+0x%x", (char *)argLengthArgv - (char *)argLengthStack);
		checkpoint("  %d arg length: %08x (%d, %s)", lengths[i], result, argLengthArgc, temp);
	}

	// NULL crashes it, though...
	checkpointNext("Argument pointers:");
	void *argptrs[] = {argLengthTemp, (void *)0xDEADBEEF, (void *)0x80000000};
	for (i = 0; i < ARRAY_SIZE(argptrs); ++i) {
		argLengthArgc = -1;
		argLengthArgv = NULL;
		result = sceKernelStartThread(argLengthThread, 4, argptrs[i]);
		sceKernelWaitThreadEnd(argLengthThread, NULL);

		if (argLengthArgv == 0)
			sprintf(temp, "NULL");
		else if (argLengthArgv == argLengthTemp)
			sprintf(temp, "original");
		else
			sprintf(temp, "stack+0x%x", (char *)argLengthArgv - (char *)argLengthStack);
		checkpoint("  arg ptr #%d: %08x (%d, %s)", i, result, argLengthArgc, temp);
	}

	checkpointNext("Priorities:");
	static int priorities[] = {0x8, 0x1F, 0x20, 0x21, 0x40};
	for (i = 0; i < ARRAY_SIZE(priorities); ++i) {
		argLengthArgc = -1;
		sceKernelDeleteThread(argLengthThread);
		argLengthThread = sceKernelCreateThread("argLength", &argLengthFunc, priorities[i], 0x800, 0, NULL);
		result = sceKernelStartThread(argLengthThread, priorities[i], argLengthTemp);
		int afterStart = argLengthArgc;
		sceKernelWaitThreadEnd(argLengthThread, NULL);

		int priorityDiff = priorities[i] - sceKernelGetThreadCurrentPriority();
		checkpoint("  priority 0x%02x: %08x (current%s0x%02x, %s)", priorities[i], result, priorityDiff < 0 ? "-" : "+", priorityDiff < 0 ? -priorityDiff : priorityDiff, afterStart == priorities[i] ? "resched" : (argLengthArgc == priorities[i] ? "deferred" : "never"));
	}

	checkpointNext("Stack:");
	testCheckStackLayout("  No arg", 0, 0);
	testCheckStackLayout("  Odd arg", 1, 0);
	testCheckStackLayout("  Large arg", 0x600, 0);
	testCheckStackLayout("  Low stack", 0, 0x00400000);
	testCheckStackLayout("  Without fill", 0, 0x00100000);
	testCheckStackLayout("  Clear stack", 0, 0x00200000);

	return 0;
}