From: chaoskagami Date: Mon, 26 Dec 2016 23:38:51 +0000 (-0500) Subject: Allow merged codebins as option. X-Git-Tag: v0.3.1~51 X-Git-Url: https://chaos.moe/g/?a=commitdiff_plain;h=1b3cfe0229c1e6497265e523ebcfe045b82436d0;p=corbenik%2Fcorbenik.git Allow merged codebins as option. This is utterly stupid and a lossy removal of information. Unfortunately, it's what you call a "scene standard" which is to say an idiotic decision that somehow stuck. Anyways, add a toggle for usage of merged codebins. These should go one level above where text/ro/data are and are named by titleid sans extension. --- diff --git a/external/loader/source/patcher.c b/external/loader/source/patcher.c index 7ce4930..eb16186 100644 --- a/external/loader/source/patcher.c +++ b/external/loader/source/patcher.c @@ -16,10 +16,11 @@ #endif #include -#define TEXT_PATH PATH_EXEFS_TEXT "/0000000000000000" -#define DATA_PATH PATH_EXEFS_DATA "/0000000000000000" -#define RO_PATH PATH_EXEFS_RO "/0000000000000000" -#define LANG_PATH PATH_LOCEMU "/0000000000000000" +#define MERGE_PATH PATH_EXEFS "/0000000000000000" +#define TEXT_PATH PATH_EXEFS_TEXT "/0000000000000000" +#define DATA_PATH PATH_EXEFS_DATA "/0000000000000000" +#define RO_PATH PATH_EXEFS_RO "/0000000000000000" +#define LANG_PATH PATH_LOCEMU "/0000000000000000" const char hexDigits[] = "0123456789ABCDEF"; @@ -348,60 +349,8 @@ overlay_patch(_UNUSED u64 progId, _UNUSED u8 *code, _UNUSED u32 size) { // TODO - Implement. Needs some thought. This should allow usage of files off SD rather than RomFS. - /* Okay, so in a nutshell, here's how the alternatives work: - * ----------------------------------------------------------------- - * NTR / layeredFS - * - * NTR injects itself in the process' memory, so the plugin running - * is a part of the program for all intents. That explains a few - * things. - * - * What layeredFS does is hook fsRegArchive with its' own callback, - * and fsOpenFile as well (in the program.) The fsRegArchive hook - * registers a SDMC archive as ram:/ (instead of rom:/) as well as - * the usual setup. When calling fsOpenFile, it checks to see if - * a rom:/ path is used and if a file exists at ram:/ (and if so, - * replaces o -> a. - * - * Things running in NTR are automatically patched for SD access, - * too, which can be solved from here (considering we patch OURSELF - * to do so in loader) - * - * layeredFS lacks any comments to help decipher but that's what I - * understand, at least. - * - * While it also could memsearch at runtime and work as generic, - * it doesn't. It uses a python script to find static offsets. - * There's really no good reason for it to be implemented this way. - * - * ----------------------------------------------------------------- - * HANS - * - * So, considering the code isn't terribly well documented, this may - * be wrong. Feel free to correct me. - * - * All the archive mounting/reading functions are taken over by HANS - * and replaced with its own hooks instead. - * - * HANS does so in an incredibly interesting way using darm. It - * disassembles the code to find what it's looking for, and extracts - * offsets from branches. It calculates where it can inject the code - * and re-allocates the space for its own hooks. - * - * In the end, HANS takes over the RomFS mounting code so it mounts - * off the SD rather than the game. It doesn't take over fsOpenFile - * because the game has correct handles passed around for the RomFS. - * - * This is probably incredibly inefficient but also entirely fool- - * proof. - * ----------------------------------------------------------------- - * - * The best approach here is to implement the hooks like layeredFS - * does and append code to the text segment. This has a few - * negatives, namely, we have to write it as assembler. - * - * Otherwise, it is completely viable to do this from loader. - */ + // FUTURE NOTE - Luma has this halfway w/ Romfs redirection. Their method consists of overwriting + // a known unused SDK function (possibly?) which is a clever workaround for lack of code expansion. } void @@ -416,76 +365,105 @@ code_handler(u64 progId, EXHEADER_prog_addrs *shared) if (!(highTid == 0x00040000 || highTid == 0x00040002) && !config.options[OPTION_LOADER_DUMPCODE_ALL]) return; - static char text_path[] = TEXT_PATH; - static char data_path[] = DATA_PATH; - static char ro_path[] = RO_PATH; - Handle code_f; + if (config.options[OPTION_LOADER_DUMPCODE_MERGED]) { + static char merge_path[] = MERGE_PATH; + Handle code_f; - hexdump_titleid(progId, text_path); - hexdump_titleid(progId, data_path); - hexdump_titleid(progId, ro_path); + hexdump_titleid(progId, merge_path); - u32 len; + u32 len; - // Text section. + u32 size = (shared->text_size + shared->ro_size + shared->data_size) << 12; - // Attempts to load code section from SD card, including system titles/modules/etc. - if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, text_path, FS_OPEN_READ)) && config.options[OPTION_LOADER_LOADCODE]) { - FSFILE_Read(code_f, &len, 0, (void*)shared->text_addr, shared->text_size << 12); - logstr(" loaded text from "); - logstr(text_path); - logstr("\n"); - } - // Either system title with OPTION_LOADER_DUMPCODE_ALL enabled, or regular title - else if (config.options[OPTION_LOADER_DUMPCODE]) { - if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, text_path, FS_OPEN_WRITE | FS_OPEN_CREATE))) { - FSFILE_Write(code_f, &len, 0, (void*)shared->text_addr, shared->text_size << 12, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME); - logstr(" dumped text to "); + // Attempts to load code section from SD card, including system titles/modules/etc. + if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, merge_path, FS_OPEN_READ)) && config.options[OPTION_LOADER_LOADCODE]) { + FSFILE_Read(code_f, &len, 0, (void*)shared->text_addr, size); + logstr(" loaded codebin from "); + logstr(merge_path); + logstr("\n"); + } + // Either system title with OPTION_LOADER_DUMPCODE_ALL enabled, or regular title + else if (config.options[OPTION_LOADER_DUMPCODE]) { + if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, merge_path, FS_OPEN_WRITE | FS_OPEN_CREATE))) { + FSFILE_Write(code_f, &len, 0, (void*)shared->text_addr, size, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME); + logstr(" dumped codebin to "); + logstr(merge_path); + logstr("\n"); + } + } + FSFILE_Close(code_f); + } else { + static char text_path[] = TEXT_PATH; + static char data_path[] = DATA_PATH; + static char ro_path[] = RO_PATH; + Handle code_f; + + hexdump_titleid(progId, text_path); + hexdump_titleid(progId, data_path); + hexdump_titleid(progId, ro_path); + + u32 len; + + // Text section. + + // Attempts to load code section from SD card, including system titles/modules/etc. + if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, text_path, FS_OPEN_READ)) && config.options[OPTION_LOADER_LOADCODE]) { + FSFILE_Read(code_f, &len, 0, (void*)shared->text_addr, shared->text_size << 12); + logstr(" loaded text from "); logstr(text_path); logstr("\n"); } - } - FSFILE_Close(code_f); + // Either system title with OPTION_LOADER_DUMPCODE_ALL enabled, or regular title + else if (config.options[OPTION_LOADER_DUMPCODE]) { + if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, text_path, FS_OPEN_WRITE | FS_OPEN_CREATE))) { + FSFILE_Write(code_f, &len, 0, (void*)shared->text_addr, shared->text_size << 12, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME); + logstr(" dumped text to "); + logstr(text_path); + logstr("\n"); + } + } + FSFILE_Close(code_f); - // Data section. + // Data section. - // Attempts to load code section from SD card, including system titles/modules/etc. - if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, data_path, FS_OPEN_READ)) && config.options[OPTION_LOADER_LOADCODE]) { - FSFILE_Read(code_f, &len, 0, (void*)shared->data_addr, shared->data_size << 12); - logstr(" loaded data from "); - logstr(data_path); - logstr("\n"); - } - // Either system title with OPTION_LOADER_DUMPCODE_ALL enabled, or regular title - else if (config.options[OPTION_LOADER_DUMPCODE]) { - if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, data_path, FS_OPEN_WRITE | FS_OPEN_CREATE))) { - FSFILE_Write(code_f, &len, 0, (void*)shared->data_addr, shared->data_size << 12, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME); - logstr(" dumped data to "); + // Attempts to load code section from SD card, including system titles/modules/etc. + if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, data_path, FS_OPEN_READ)) && config.options[OPTION_LOADER_LOADCODE]) { + FSFILE_Read(code_f, &len, 0, (void*)shared->data_addr, shared->data_size << 12); + logstr(" loaded data from "); logstr(data_path); logstr("\n"); } - } - FSFILE_Close(code_f); + // Either system title with OPTION_LOADER_DUMPCODE_ALL enabled, or regular title + else if (config.options[OPTION_LOADER_DUMPCODE]) { + if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, data_path, FS_OPEN_WRITE | FS_OPEN_CREATE))) { + FSFILE_Write(code_f, &len, 0, (void*)shared->data_addr, shared->data_size << 12, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME); + logstr(" dumped data to "); + logstr(data_path); + logstr("\n"); + } + } + FSFILE_Close(code_f); - // RO Section. + // RO Section. - // Attempts to load code section from SD card, including system titles/modules/etc. - if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, ro_path, FS_OPEN_READ)) && config.options[OPTION_LOADER_LOADCODE]) { - FSFILE_Read(code_f, &len, 0, (void*)shared->ro_addr, shared->ro_size << 12); - logstr(" loaded ro from "); - logstr(ro_path); - logstr("\n"); - } - // Either system title with OPTION_LOADER_DUMPCODE_ALL enabled, or regular title - else if (config.options[OPTION_LOADER_DUMPCODE]) { - if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, ro_path, FS_OPEN_WRITE | FS_OPEN_CREATE))) { - FSFILE_Write(code_f, &len, 0, (void*)shared->ro_addr, shared->ro_size << 12, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME); - logstr(" dumped ro to "); + // Attempts to load code section from SD card, including system titles/modules/etc. + if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, ro_path, FS_OPEN_READ)) && config.options[OPTION_LOADER_LOADCODE]) { + FSFILE_Read(code_f, &len, 0, (void*)shared->ro_addr, shared->ro_size << 12); + logstr(" loaded ro from "); logstr(ro_path); logstr("\n"); } + // Either system title with OPTION_LOADER_DUMPCODE_ALL enabled, or regular title + else if (config.options[OPTION_LOADER_DUMPCODE]) { + if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, ro_path, FS_OPEN_WRITE | FS_OPEN_CREATE))) { + FSFILE_Write(code_f, &len, 0, (void*)shared->ro_addr, shared->ro_size << 12, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME); + logstr(" dumped ro to "); + logstr(ro_path); + logstr("\n"); + } + } + FSFILE_Close(code_f); } - FSFILE_Close(code_f); } // This is only for the .code segment. diff --git a/include/option.h b/include/option.h index 851a06e..a043043 100644 --- a/include/option.h +++ b/include/option.h @@ -71,6 +71,8 @@ extern struct config_file *config; #define OPTION_SILENT_NOSCREEN 22 ///< Silenced autoboot will not init the screen. +#define OPTION_LOADER_DUMPCODE_MERGED 23 ///< Dump and load merged codebins (Luma-style) rather than split segment. Note that this is lossy and you will be unable to split these properly without the exheader information. + #define OPTION_SAVE_LOGS 253 ///< Save log files during boot and from loader. Slows down boot a bit. #define OPTION_OVERLY_VERBOSE 254 ///< Output so much debugging info, it'd make your head spin. diff --git a/source/menu.c b/source/menu.c index 1a7d127..09c383a 100644 --- a/source/menu.c +++ b/source/menu.c @@ -87,11 +87,12 @@ static struct options_s options[] = { { "Load Code Sections", "Loads code sections (text/ro/data) from SD card and patches afterwards.", option, (void*)OPTION_LOADER_LOADCODE, change_opt, get_opt, 0, 0 }, - { "Dump Code Sections", "Dumps code sections for titles to SD card the first time they're loaded. Slows things down on first launch.", option, (void*)OPTION_LOADER_DUMPCODE, change_opt, get_opt, 0, 0 }, - + { "Merged codebins", + "Use merged codebins rather than segment split files.", + option, (void*)OPTION_LOADER_DUMPCODE_MERGED, change_opt, get_opt, 1, 0 }, { "+ System Titles", "Dumps code sections for system titles, too. Expect to sit at a blank screen for >3mins on the first time you do this, because it dumps everything.", option, (void*)OPTION_LOADER_DUMPCODE_ALL, change_opt, get_opt, 1, 0 },