]> Chaos Git - corbenik/corbenik.git/commitdiff
Loader enhancements
authorchaoskagami <chaos.kagami@gmail.com>
Sat, 1 Oct 2016 15:53:03 +0000 (11:53 -0400)
committerchaoskagami <chaos.kagami@gmail.com>
Sat, 1 Oct 2016 15:53:03 +0000 (11:53 -0400)
external/loader/source/loader.c
external/loader/source/logger.c
external/loader/source/logger.h
external/loader/source/statics.c [new file with mode: 0644]

index 389994ed9dd0c613d88cb2feeaf930addf993546..b753db4d577894deac64f31168daa3199e6e7df6 100644 (file)
@@ -26,12 +26,10 @@ static Result
 allocate_shared_mem(prog_addrs_t *shared, prog_addrs_t *vaddr, int flags)
 {
     // Somehow, we need to allow reallocating.
-
     u32 dummy;
 
     memcpy(shared, vaddr, sizeof(prog_addrs_t));
-    shared->text_addr = 0x10000000; // Code is forcibly relocated to this
-                                    // address to kill ASLR (I believe.)
+    shared->text_addr = 0x10000000; // Base virtual address for code.
     shared->ro_addr = shared->text_addr + (shared->text_size << 12);
     shared->data_addr = shared->ro_addr + (shared->ro_size << 12);
     return svcControlMemory(&dummy, shared->text_addr, 0, shared->total_size << 12, (flags & 0xF00) | MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE);
@@ -252,11 +250,9 @@ loader_RegisterProgram(u64 *prog_handle, FS_ProgramInfo *title, FS_ProgramInfo *
 
     if (title->mediaType != update->mediaType)
         panicstr("Program and update are different mediaTypes, abort.\n");
-    }
 
-    if (prog_id != update->programId) {
+    if (prog_id != update->programId)
         panicstr("Program and update have different titleIDs, abort.\n");
-    }
 
     res = FSREG_LoadProgram(prog_handle, title);
     if (R_SUCCEEDED(res)) {
@@ -383,47 +379,6 @@ should_terminate(int *term_request)
     return 0;
 }
 
-// this is called before main
-void
-__appInit()
-{
-    srvSysInit();
-    fsregInit();
-    fsldrInit();
-    pxipmInit();
-}
-
-// this is called after main exits
-void
-__appExit()
-{
-    pxipmExit();
-    fsldrExit();
-    fsregExit();
-    srvSysExit();
-}
-
-// stubs for non-needed pre-main functions
-void __sync_init();
-void __sync_fini();
-void __system_initSyscalls();
-
-void
-__ctru_exit()
-{
-    __appExit();
-    __sync_fini();
-    svcExitProcess();
-}
-
-void
-initSystem()
-{
-    __sync_init();
-    __system_initSyscalls();
-    __appInit();
-}
-
 int
 main()
 {
index 3d62a8e5a14cba9b44f3668eefa484c8976e90a1..f57627388878db9f7b78107699a509c91cf8b6f7 100644 (file)
@@ -36,14 +36,6 @@ openLogger()
     logger_is_initd = 1;
 }
 
-void
-breakstr(const char *str)
-{
-    logstr(str);
-    closeLogger();
-    svcBreak(USERBREAK_ASSERT);
-}
-
 void
 logstr(const char *str)
 {
@@ -89,3 +81,12 @@ closeLogger()
     FSFILE_Close(log_file_hdl);
     logger_is_initd = 0;
 }
+
+void
+panicstr(const char *str)
+{
+    logstr(str);
+    closeLogger();
+    svcBreak(USERBREAK_ASSERT);
+}
+
index 8dcf50505582375143b72f6fe26a1d003d32ed24..e6aeddd65d40e1a2df26a7a7602e0e539dbd5e85 100644 (file)
@@ -5,5 +5,6 @@ void openLogger();
 void logstr(const char *str);
 void logu64(u64 progId);
 void closeLogger();
+void panicstr(const char *str);
 
 #endif
diff --git a/external/loader/source/statics.c b/external/loader/source/statics.c
new file mode 100644 (file)
index 0000000..856f92f
--- /dev/null
@@ -0,0 +1,106 @@
+#include <3ds.h>
+#include "patcher.h"
+#include "exheader.h"
+#include "fsldr.h"
+#include "fsreg.h"
+#include "pxipm.h"
+#include "srvsys.h"
+#include "internal.h"
+#include "logger.h"
+
+extern char* fake_heap_start;
+extern char* fake_heap_end;
+extern u32 __ctru_heap;
+extern u32 __ctru_heap_size;
+extern u32 __ctru_linear_heap;
+extern u32 __ctru_linear_heap_size;
+
+// NOTE - stubs for non-needed pre-main functions
+void __sync_init();
+void __sync_fini();
+void __system_initSyscalls(void);
+
+// Pre-main initialization function.
+void
+__appInit()
+{
+    srvSysInit();
+    fsregInit();
+    fsldrInit();
+    pxipmInit();
+}
+
+// Post-main cleanup function.
+void
+__appExit()
+{
+    pxipmExit();
+    fsldrExit();
+    fsregExit();
+    srvSysExit();
+}
+
+void __system_allocateHeaps(void) {
+    u32 dummy = 0;
+
+    // Allocate a small-ish heap. Why, you ask? Half the system hasn't started up (we start it)
+    // so we actually don't know how much memory is needed later.
+    // If we do it ctrulib-ish like this:
+
+    // u32 size = (osGetMemRegionFree(MEMREGION_BASE) / 2) & 0xFFFFF000;
+
+    // Things just go terribly awry, because we'll eventually OOM when loading everything in the base region.
+    // This results in HOME loading and half the system modules not loading.
+
+    // According to 3dbrew, on 4.5.0 we have 0x001FE000 bytes in BASE once HOME is loaded. We play it safe and take a very tiny amount.
+    u32 size = 0x20000;
+    __ctru_heap_size = size;
+
+    // Allocate the module's heap
+    __ctru_heap        = 0x08000000;
+    if(R_FAILED(svcControlMemory(&dummy, __ctru_heap, 0x0, __ctru_heap_size, MEMOP_ALLOC | MEMOP_REGION_BASE, MEMPERM_READ | MEMPERM_WRITE)))
+        svcBreak(USERBREAK_ASSERT); // Memory allocation failed.
+
+    // Set up newlib heap
+    fake_heap_start = (char*)__ctru_heap;
+    fake_heap_end = fake_heap_start + __ctru_heap_size;
+}
+
+void __libctru_init()
+{
+    // Initialize newlib support system calls
+    __system_initSyscalls();
+
+    // Allocate module heap
+    __system_allocateHeaps();
+}
+
+void __attribute__((noreturn)) __libctru_exit()
+{
+    u32 dummy = 0;
+
+    // Unmap the application heap
+    svcControlMemory(&dummy, __ctru_heap, 0x0, __ctru_heap_size, MEMOP_FREE, 0x0);
+
+    // Since above did not jump, end this process
+    svcExitProcess();
+}
+
+// See: https://github.com/smealum/ctrulib/blob/master/libctru/source/system/stack_adjust.s
+// This is overridden in all likelyhood to avoid the stack being fucked.
+void
+initSystem()
+{
+    __libctru_init();
+    __appInit();
+}
+
+
+// See above initSystem for why this is overridden.
+void
+__ctru_exit()
+{
+    __appExit();
+    __libctru_exit();
+}
+