hrydgard / ppsspp

A PSP emulator for Android, Windows, Mac and Linux, written in C++. Want to contribute? Join us on Discord at https://discord.gg/5NJB6dD or just send pull requests / issues. For discussion use the forums at forums.ppsspp.org.
https://www.ppsspp.org
Other
11.33k stars 2.18k forks source link

Little Big Planet doesn't work #324

Closed artart78 closed 11 years ago

artart78 commented 11 years ago

I opened this issue so we can discuss a bit what I found, if someone finds what's the problem, or at least it will help me re-explain the problem so maybe it'll help myself.

The game prints itself an error: "libc:_getmodreent: no reent structure found." I'm not sure that's fatal, but it probably is. Anyway, the game fails trying to load a file with a completely invalid name, so I'll just consider the error it prints as fatal (maybe someone could try running this game on his PSP to be sure it doesn't show this message?).

This game stores a pointer, that we'll call PTR, into $k0 + 4. PTR has a value which seems to be kept, so the $k0/$sp overwriting problem seems to be fixed.

However, near the start of the game, sub_08B9BD8C writes to some value to an address, calculated to PTR and the main module UID. It stores the module UID there (address is a bit after 0x08C0EC38). But then, when sub_08B9BC9C is ran and at this same often, it isn't the module UID, the game shows that error. Which means that value has been overwritten.

After running some ugly tests, I've seen that the value is overwritten, probably involuntarily, by the user_main thread itself (which also shows that error), after the "08C0EAE4 fios mediathread" thread has been started. It means there is some awful overwriting somewhere. The game uses a partition memory (in which that "reent" data is). Modules are loaded, but after the value has been overwritten.

I'm open to all ideas. [Unknown], did you investigate around this?

unknownbrackets commented 11 years ago

Interesting. In fact, Final Fantasy 3 and LittleBigPlanet are the two games I've seen k0 stuff going on in.

Final Fantasy 3 is a lot happier with 0xFFFFFFFF at $k0 + 4 (as in the current state), as I'd found last night. It still doesn't load but no invalid memory access.

After reading your notes, I tried this simple test:

    int thid = 0;
    sceKernelStartThread(
        thid = sceKernelCreateThread("Test Thread", (void *)&threadFunction, 0x12, 0x10000, 0x00200000, NULL),
        0, NULL
    );

    sceKernelWaitThreadEnd(thid, NULL);

    sceKernelStartThread(
        thid = sceKernelCreateThread("Test Thread", (void *)&threadFunction, 0x12, 0x1000, 0x00200000, NULL),
        0, NULL
    );

    sceKernelWaitThreadEnd(thid, NULL);

In fact, the second time it doesn't pass ($k0 + 4 == 0x00000000...) And it's not the Memset, even if I change that value it's still 0x00000000. Seems I'll need to add some memory write breakpoints.

-[Unknown]

unknownbrackets commented 11 years ago

No wait, I screwed up my test, that's not it. Hmm.

-[Unknown]

artart78 commented 11 years ago

I found the issue, finally. Not enough space was allocated for the ELF, so the memory block ended up overwriting the ELF data sections/segments. Now that my quick hack works, I'll try to find the real size needed by the module.

unknownbrackets commented 11 years ago

Wow, that sounds dangerous. I wonder how many other games that could be affecting.

-[Unknown]

hrydgard commented 11 years ago

nice debugging :)