My Project
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules
initSystem.c
Go to the documentation of this file.
1 #include <sys/iosupport.h>
2 #include <string.h>
3 #include <3ds.h>
4 
5 // System globals we define here
7 char** __system_argv;
8 void (*__system_retAddr)(void);
10 
11 // Data from _prm structure
12 extern void* __service_ptr; // used to detect if we're run from a homebrew launcher
14 extern const char* __system_arglist;
15 
16 // newlib definitions we need
17 void __libc_init_array(void);
18 void __libc_fini_array(void);
19 extern char* fake_heap_start;
20 extern char* fake_heap_end;
21 
22 static void initArgv();
23 static u32 heapBase;
24 
25 void __destroy_handle_list(void);
26 
27 void __attribute__((noreturn)) __ctru_exit(int rc)
28 {
29  // Run the global destructors
31 
32  // TODO: APT exit goes here
33 
34  // Unmap the linear heap
36 
37  // Unmap the application heap
38  svcControlMemory(&heapBase, heapBase, 0x0, __heap_size, MEMOP_FREE, 0x0);
39 
40  // Close some handles
42 
43  // Jump to the loader if it provided a callback
44  if (__system_retAddr)
46 
47  // Since above did not jump, end this process
48  svcExitProcess();
49 }
50 
51 void initSystem(void (*retAddr)(void))
52 {
53  // Register newlib exit() syscall
54  __syscalls.exit = __ctru_exit;
55  __system_retAddr = __service_ptr ? retAddr : NULL;
56 
57  // Allocate the application heap
58  heapBase = 0x08000000;
59  svcControlMemory(&heapBase, heapBase, 0x0, __heap_size, MEMOP_ALLOC, 0x3);
60 
61  // Allocate the linear heap
63 
64  // Set up newlib heap
65  fake_heap_start = (char*)heapBase;
67 
68  // Build argc/argv if present
69  initArgv();
70 
71  // TODO: APT init goes here
72 
73  // Run the global constructors
75 }
76 
77 void initArgv()
78 {
79  int i;
80  const char* temp = __system_arglist;
81 
82  // Check if the argument list is present
83  if (!temp)
84  return;
85 
86  // Retrieve argc
87  __system_argc = *(u32*)temp;
88  temp += sizeof(u32);
89 
90  // Find the end of the argument data
91  for (i = 0; i < __system_argc; i ++)
92  {
93  for (; *temp; temp ++);
94  temp ++;
95  }
96 
97  // Reserve heap memory for argv data
98  u32 argSize = temp - __system_arglist - sizeof(u32);
100  fake_heap_start += sizeof(char**)*(__system_argc + 1);
101  char* argCopy = fake_heap_start;
102  fake_heap_start += argSize;
103 
104  // Fill argv array
105  memcpy(argCopy, &__system_arglist[4], argSize);
106  temp = argCopy;
107  for (i = 0; i < __system_argc; i ++)
108  {
109  __system_argv[i] = (char*)temp;
110  for (; *temp; temp ++);
111  temp ++;
112  }
113  __system_argv[__system_argc] = NULL;
114 }
void * __service_ptr
Definition: svc.h:9
char ** __system_argv
Definition: initSystem.c:7
u32 __linear_heap_size
u32 __heap_size
void initSystem(void(*retAddr)(void))
Definition: initSystem.c:51
void __destroy_handle_list(void)
Definition: srv.c:61
void __attribute__((noreturn))
Definition: initSystem.c:27
uint32_t u32
Definition: types.h:23
char * fake_heap_end
u32 __linear_heap
Definition: initSystem.c:9
int __system_argc
Definition: initSystem.c:6
s32 svcControlMemory(u32 *addr_out, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm)
void(* __system_retAddr)(void)
Definition: initSystem.c:8
char * fake_heap_start
void __libc_fini_array(void)
void __libc_init_array(void)
const char * __system_arglist