lzss_decompress((u8 *)shared->text_addr + size);
}
+ // Dump code section
+ dump_code(progid, (u8 *)shared->text_addr, shared->total_size << 12);
+
// Patch segments
patch_exe (progid, progver, (u8 *)shared->text_addr, shared->text_size << 12, original->text_size << 12,
(u8 *)shared->data_addr, shared->data_size << 12, original->data_size << 12,
#endif
#include "../../../source/config.h"
+#define CODE_PATH PATH_EXEFS "/0000000000000000"
+
+static const char hexDigits[] = "0123456789ABCDEF";
+
int
fileOpen(Handle *file, FS_ArchiveID id, const char *path, int flags)
{
char path[] = "/corbenik/locale/0000000000000000";
u32 i = 32;
while (progId) {
- static const char hexDigits[] = "0123456789ABCDEF";
path[i--] = hexDigits[(u32)(progId & 0xF)];
progId >>= 4;
}
// TODO - Implement. Needs some thought. This should allow usage of files off SD rather than RomFS.
}
+void
+dump_code(u64 progId, u8 *code_loc, u32 code_len)
+{
+ // If configuration was not loaded, or the option is disabled
+ if (failed_load_config || !config.options[OPTION_LOADER_DUMPCODE])
+ return;
+
+ u32 highTid = progId >> 0x20;
+
+ // Only regular titles and demos will get dumped
+ // Otherwise it's insanely slow
+ if (highTid != 0x00040000 && highTid != 0x00040002)
+ return;
+
+ char code_path[] = CODE_PATH;
+ u32 i = strlen(code_path) - 1;
+ Handle code_f;
+ while (progId) {
+ code_path[i--] = hexDigits[(u32)(progId & 0xF)];
+ progId >>= 4;
+ }
+
+ if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, code_path, FS_OPEN_READ)))
+ // Code was already dumped, do nothing
+ {
+ FSFILE_Close(code_f);
+ return;
+ }
+
+ else
+ {
+ if (R_SUCCEEDED(fileOpen(&code_f, ARCHIVE_SDMC, code_path, FS_OPEN_WRITE | FS_OPEN_CREATE)))
+ {
+ u32 len = 0;
+ FSFILE_Write(code_f, &len, 0, code_loc, code_len, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME);
+ logstr("dumped code to ");
+ logstr(code_path);
+ logstr("\n");
+ }
+ }
+
+ return;
+}
+
// This is only for the .code segment.
void
patch_exe(u64 progId, u16 progver,
u8* data, u32 data_size, u32 orig_data,
u8* ro, u32 ro_size, u32 orig_ro);
+void dump_code(u64 progId, u8 *code_loc, u32 code_len);
+
u32 get_text_extend(u64 progId, u16 progver, u32 size_orig);
u32 get_ro_extend(u64 progId, u16 progver, u32 size_orig);
u32 get_data_extend(u64 progId, u16 progver, u32 size_orig);
// Which EmuNAND to use (currently only allows 10 total, but eh, I can change that if anyone truly needs it)
#define OPTION_EMUNAND_INDEX 17
+// Dump titles' code section as they're loaded by the loader module
+// WARNING!! Slows down boot time considerably the first time!
+#define OPTION_LOADER_DUMPCODE 252
+
// Save log files during boot and from loader.
// This will slow things down a bit.
#define OPTION_SAVE_LOGS 253
{ OPTION_LOADER_CPU_L2, " CPU - L2 cache", "Forces the system to use the L2 cache. Ignored if not a N3DS.", boolean_val, 0, 0 },
{ OPTION_LOADER_CPU_800MHZ, " CPU - 800Mhz", "Forces the system to run in 800Mhz mode. Ignored if not a N3DS.", boolean_val, 0, 0 },
{ OPTION_LOADER_LANGEMU, " Language Emulation", "Reads language emulation configuration and imitates the region/language.", boolean_val, 0, 0 },
+ { OPTION_LOADER_DUMPCODE, " Dump code section", "Dumps code sections to SD card only the first time they're loaded.", boolean_val, 0, 0 },
{ 0, "", "", not_option, 0, 0 },