]> Chaos Git - corbenik/corbenik.git/commitdiff
Allow merged codebins as option.
authorchaoskagami <chaos.kagami@gmail.com>
Mon, 26 Dec 2016 23:38:51 +0000 (18:38 -0500)
committerchaoskagami <chaos.kagami@gmail.com>
Mon, 26 Dec 2016 23:38:51 +0000 (18:38 -0500)
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.

external/loader/source/patcher.c
include/option.h
source/menu.c

index 7ce49308b1d65226e0fe1ace378974a8087128f1..eb161868e7047cbaebb289a447e6486eee17f54b 100644 (file)
 #endif
 #include <option.h>
 
-#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.
index 851a06ea8c62d0b32f4ba494c9bf58575b4ef561..a043043e47aec697b1946bbe2b1b3b8f42fe925b 100644 (file)
@@ -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.
index 1a7d12720702d7f679e786f8c86ed06d4ec53163..09c383a6173428a68115fe58d5bc655571aec461 100644 (file)
@@ -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 },