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);
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)) {
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()
{
--- /dev/null
+#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();
+}
+