(GX) make the .dol launcher code safer, this might fix occasional crashes or hangs

This commit is contained in:
ToadKing 2013-01-19 03:22:14 -05:00
parent 5d33861c8b
commit de9231f071
2 changed files with 21 additions and 5 deletions

View File

@ -337,7 +337,9 @@ static void system_exitspawn(void)
#ifdef IS_SALAMANDER #ifdef IS_SALAMANDER
rarch_console_exec(default_paths.libretro_path); rarch_console_exec(default_paths.libretro_path);
#else #else
// try to launch the core directly first, then fallback to salamander
rarch_console_exec(g_settings.libretro); rarch_console_exec(g_settings.libretro);
rarch_console_exec(g_extern.fullpath);
#endif #endif
} }

View File

@ -60,6 +60,8 @@ void dol_copy_argv_path(void)
} }
#endif #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) static void rarch_console_exec(const char *path)
{ {
RARCH_LOG("Attempt to load executable: [%s].\n", 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"); FILE * fp = fopen(path, "rb");
if (fp == NULL) if (fp == NULL)
{ {
RARCH_ERR("Could not execute DOL file.\n"); RARCH_ERR("Could not open DOL file %s.\n", path);
return; return;
} }
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
size_t size = ftell(fp); size_t size = ftell(fp);
fseek(fp, 0, SEEK_SET); fseek(fp, 0, SEEK_SET);
fread(EXECUTE_ADDR, 1, size, fp); // try to allocate a buffer for it. if we can't, fail
fclose(fp); void *dol = malloc(size);
DCFlushRange(EXECUTE_ADDR, 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("carda:");
fatUnmount("cardb:"); fatUnmount("cardb:");
@ -87,6 +94,13 @@ static void rarch_console_exec(const char *path)
__io_wiisd.shutdown(); __io_wiisd.shutdown();
__io_usbstorage.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; size_t booter_size = booter_end - booter_start;
memcpy(BOOTER_ADDR, booter_start, booter_size); memcpy(BOOTER_ADDR, booter_start, booter_size);
DCFlushRange(BOOTER_ADDR, booter_size); DCFlushRange(BOOTER_ADDR, booter_size);