Project

General

Profile

Actions

Emulator Issues #12948

open

OSReport HLE behaves poorly for GameCube titles when MMU is disabled

Added by pokechu22 almost 2 years ago. Updated almost 2 years ago.

Status:
New
Priority:
Normal
Assignee:
-
% Done:

0%

Operating system:
N/A
Issue type:
Bug
Milestone:
Regression:
No
Relates to usability:
No
Relates to performance:
No
Easy:
No
Relates to maintainability:
No
Regression start:
Fixed in:

Description

What's the problem? Describe what went wrong.

OSReport HLE uses the wrong function signature in GameCube mode if MMU is disabled.

What steps will reproduce the problem?

The following Homebrew program demonstrates the issue (compiled ELF attached):

#include <stdio.h>
#include <stdlib.h>
#include <gccore.h>

static void *xfb = NULL;
static GXRModeObj *rmode = NULL;

int main(int argc, char **argv) {
    VIDEO_Init();
    PAD_Init();
    rmode = VIDEO_GetPreferredMode(NULL);
    xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
    console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
    VIDEO_Configure(rmode);
    VIDEO_SetNextFramebuffer(xfb);
    VIDEO_SetBlack(FALSE);
    VIDEO_Flush();
    VIDEO_WaitVSync();
    if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();

    printf("Load 0x%x bytes from %x to %x\n", 4, 5, 6);
    printf("Test %f %d\n", .42, 365);
    printf("Hello, world\n");
    printf("stop\n");
    printf("lowercase\n");

    return 0;
}

Disable MMU, and turn on the OSReport HLE log (and set the log level to info). Run the attached elf (note that it must be the elf and not the dol file, as the symbols are needed for OSReport HLE to work). On screen you will see the following:

Load 0x4 bytes from 5 to 6
Test 0.420000 365
Hello, world
stop
lowercase

But, the following instead shows up in the logs:

16:45:986 Core\HLE\HLE_OS.cpp:84 N[OSREPORT_HLE]: 800048f8->800048cc| 
16:45:996 Core\HLE\HLE_OS.cpp:84 N[OSREPORT_HLE]: 80004914->800048f8| Test 0.420000 365
16:45:000 Core\HLE\HLE_OS.cpp:84 N[OSREPORT_HLE]: 80004920->80004914| €ロ楳@
16:46:001 Core\HLE\HLE_OS.cpp:84 N[OSREPORT_HLE]: 8000492c->80004920| 
16:46:001 Core\HLE\HLE_OS.cpp:84 N[OSREPORT_HLE]: 80004938->8000492c| lowercase

With MMU enabled, however, the following is correctly logged:

15:02:451 Core\HLE\HLE_OS.cpp:84 N[OSREPORT_HLE]: 800048f8->800048cc| Load 0x4 bytes from 5 to 6
15:02:463 Core\HLE\HLE_OS.cpp:84 N[OSREPORT_HLE]: 80004914->800048f8| Test 0.420000 365
15:02:469 Core\HLE\HLE_OS.cpp:84 N[OSREPORT_HLE]: 80004920->80004914| Hello, world
15:02:469 Core\HLE\HLE_OS.cpp:84 N[OSREPORT_HLE]: 8000492c->80004920| stop
15:02:469 Core\HLE\HLE_OS.cpp:84 N[OSREPORT_HLE]: 80004938->8000492c| lowercase

What's specifically happening is that when MMU is disabled, fake BATs are set up for 0x40000000-0x4FFFFFFF and 0x70000000-0x7FFFFFFF that get redirected to fake virtual memory. OSReport HLE tries to determine if the first parameter (in GPR3) is a pointer to a pointer to change the signature of the function. In most cases, this is fine enough (as ASCII printable characters range from 0x20 to 0x7f). But when MMU is disabled, that means that if the first character ranges from 0x40 to 0x4f (capital A to O) or 0x70 to 0x7f (lowercase p to z and also { | } ~), the string will instead be detected as a pointer, and then it will try to use GPR4 or GPR5 as the pointer to the string, which will break horribly, printing garbage or nothing at all.

This doesn't only affect homebrew; it also affects retail titles (e.g. Super Mario Sunshine), and messages logged by Datel's apploader (where the Load 0x%x bytes from %x to %x\n came from).

I'm not sure how best to fix it. We can probably make stronger assumptions about the signature of OSReport and similar while leaving guessing to about the signature ___blank, but that wouldn't fix things in all cases.

I'm also not 100% sure why only GameCube mode is affected; maybe fake VMEM doesn't exist in Wii mode since there isn't separate ARAM on Wii?

Is the issue present in the latest development version?

Yes, 5.0-16637.

Is the issue present in the latest stable version?

Not tested. Probably.


Files

template.elf (765 KB) template.elf pokechu22, 06/12/2022 10:14 PM
Actions #1

Updated by AdmiralCurtiss almost 2 years ago

maybe fake VMEM doesn't exist in Wii mode since there isn't separate ARAM on Wii?

Correct, fake VMEM is not mapped in Wii mode. You can see this in Memmap.cpp.

Actions

Also available in: Atom PDF