diff --git a/frontend/platform/platform_gx.c b/frontend/platform/platform_gx.c index ede803f9df..bc929e2a4b 100644 --- a/frontend/platform/platform_gx.c +++ b/frontend/platform/platform_gx.c @@ -337,7 +337,9 @@ static void system_exitspawn(void) #ifdef IS_SALAMANDER rarch_console_exec(default_paths.libretro_path); #else + // try to launch the core directly first, then fallback to salamander rarch_console_exec(g_settings.libretro); + rarch_console_exec(g_extern.fullpath); #endif } diff --git a/frontend/platform/platform_gx_exec.c b/frontend/platform/platform_gx_exec.c index fca8ddd181..fa88e35375 100644 --- a/frontend/platform/platform_gx_exec.c +++ b/frontend/platform/platform_gx_exec.c @@ -60,6 +60,8 @@ void dol_copy_argv_path(void) } #endif +// WARNING: after we move any data into EXECUTE_ADDR, we can no longer use any +// heap memory and are restricted to the stack only static void rarch_console_exec(const char *path) { RARCH_LOG("Attempt to load executable: [%s].\n", path); @@ -67,18 +69,23 @@ static void rarch_console_exec(const char *path) FILE * fp = fopen(path, "rb"); if (fp == NULL) { - RARCH_ERR("Could not execute DOL file.\n"); + RARCH_ERR("Could not open DOL file %s.\n", path); return; } fseek(fp, 0, SEEK_END); size_t size = ftell(fp); fseek(fp, 0, SEEK_SET); - fread(EXECUTE_ADDR, 1, size, fp); - fclose(fp); - DCFlushRange(EXECUTE_ADDR, size); + // try to allocate a buffer for it. if we can't, fail + void *dol = malloc(size); + if (!dol) + { + RARCH_ERR("Could not execute DOL file %s.\n", path); + return; + } - dol_copy_argv_path(); + fread(dol, 1, size, fp); + fclose(fp); fatUnmount("carda:"); fatUnmount("cardb:"); @@ -87,6 +94,13 @@ static void rarch_console_exec(const char *path) __io_wiisd.shutdown(); __io_usbstorage.shutdown(); + // luckily for us, newlib's memmove doesn't allocate a seperate buffer for + // copying in situations of overlap, so it's safe to do this + memmove(EXECUTE_ADDR, dol, size); + DCFlushRange(EXECUTE_ADDR, size); + + dol_copy_argv_path(); + size_t booter_size = booter_end - booter_start; memcpy(BOOTER_ADDR, booter_start, booter_size); DCFlushRange(BOOTER_ADDR, booter_size);