void __attribute__((noreturn)) __libctru_exit(int rc) { u32 tmp=0; if(__system_argv) free(__system_argv); // Unmap the linear heap svcControlMemory(&tmp, __linear_heap, 0x0, __linear_heap_size, MEMOP_FREE, 0x0); // Unmap the application heap svcControlMemory(&tmp, __heapBase, 0x0, __heap_size, MEMOP_FREE, 0x0); if (__stack_size_extra) svcControlMemory(&tmp, __stack_bottom, 0x0, __stack_size_extra, MEMOP_FREE, 0x0); // Close some handles envDestroyHandles(); if (__sync_fini) __sync_fini(); // Jump to the loader if it provided a callback if (__system_retAddr) __system_retAddr(); // Since above did not jump, end this process svcExitProcess(); }
void __system_allocateHeaps() { extern unsigned int __service_ptr; u32 tmp=0; int64_t mem_used; u32 app_memory = 0x04000000; if(!__service_ptr) app_memory = *CTR_APPMEMALLOC_PTR; svcGetSystemInfo(&mem_used, 0, 1); __linear_heap_size_local = CTR_LINEAR_HEAP_SIZE; __heap_size_local = (app_memory - mem_used - __linear_heap_size_local - 0x10000) & 0xFFFFF000; // Allocate the application heap __heapBase = 0x08000000; svcControlMemory(&tmp, __heapBase, 0x0, __heap_size_local, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE); // Allocate the linear heap svcControlMemory(&__linear_heap, 0x0, 0x0, __linear_heap_size_local, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE); // Set up newlib heap fake_heap_start = (char*)__heapBase; fake_heap_end = fake_heap_start + __heap_size_local; }
void __system_allocateHeaps() { u32 tmp=0; MemInfo stack_memInfo; PageInfo stack_pageInfo; register u32 sp_val __asm__("sp"); svcQueryMemory(&stack_memInfo, &stack_pageInfo, sp_val); __stacksize__ += 0xFFF; __stacksize__ &= ~0xFFF; __stack_size_extra = __stacksize__ > stack_memInfo.size ? __stacksize__ - stack_memInfo.size: 0; __stack_bottom = stack_memInfo.base_addr - __stack_size_extra; if (__stack_size_extra) { svcControlMemory(&tmp, __stack_bottom, 0x0, __stack_size_extra, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE); memset((void*)__stack_bottom, 0xFC, __stack_size_extra); } // setup the application heap __heapBase = 0x08000000; __heap_size = 0; // Allocate the linear heap svcControlMemory(&__linear_heap, 0x0, 0x0, __linear_heap_size, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE); // Set up newlib heap extern char* fake_heap_end; fake_heap_end = (char*)0x13F00000; }
void initSystem(void (*retAddr)(void)) { // Register newlib exit() syscall __syscalls.exit = __ctru_exit; __system_retAddr = __service_ptr ? retAddr : NULL; // Allocate the application heap heapBase = 0x08000000; svcControlMemory(&heapBase, heapBase, 0x0, __heap_size, MEMOP_ALLOC, 0x3); // Allocate the linear heap svcControlMemory(&__linear_heap, 0x0, 0x0, __linear_heap_size, MEMOP_ALLOC_LINEAR, 0x3); // Set up newlib heap fake_heap_start = (char*)heapBase; fake_heap_end = fake_heap_start + __heap_size; // Build argc/argv if present initArgv(); // TODO: APT init goes here // Run the global constructors __libc_init_array(); }
void __attribute__((weak)) __system_allocateHeaps(void) { u32 tmp=0; if(envIsHomebrew()) { // Use launcher-provided heap information. __ctru_heap_size = envGetHeapSize(); __ctru_linear_heap_size = envGetLinearHeapSize(); } else { // Distribute available memory into halves, aligning to page size. u32 size = (osGetMemRegionFree(MEMREGION_APPLICATION) / 2) & 0xFFFFF000; __ctru_heap_size = size; __ctru_linear_heap_size = size; } // Allocate the application heap __ctru_heap = 0x08000000; svcControlMemory(&tmp, __ctru_heap, 0x0, __ctru_heap_size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE); // Allocate the linear heap svcControlMemory(&__ctru_linear_heap, 0x0, 0x0, __ctru_linear_heap_size, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE); // Set up newlib heap fake_heap_start = (char*)__ctru_heap; fake_heap_end = fake_heap_start + __ctru_heap_size; }
void __system_allocateHeaps() { extern unsigned int __service_ptr; u32 tmp=0; int64_t mem_used; u32 app_memory = 0x04000000; if(!__service_ptr) app_memory = *CTR_APPMEMALLOC_PTR; svcGetSystemInfo(&mem_used, 0, 1); // For n3DS running with 124MB, only 110MB appears actually available app_memory = app_memory > 0x6E00000 ? 0x6E00000 : app_memory; heap_size = (app_memory - mem_used - linear_heap_size - 0x10000) & 0xFFFFF000; // Allocate the application heap __heapBase = 0x08000000; svcControlMemory(&tmp, __heapBase, 0x0, heap_size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE); // Allocate the linear heap svcControlMemory(&__linear_heap, 0x0, 0x0, linear_heap_size, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE); // Set up newlib heap fake_heap_start = (char*)__heapBase; fake_heap_end = fake_heap_start + heap_size; }
Result miniSocInit() { if(AtomicPostIncrement(&miniSocRefCount)) return 0; u32 tmp = 0; Result ret = 0; bool isSocURegistered; ret = srvIsServiceRegistered(&isSocURegistered, "soc:U"); if(ret != 0) goto cleanup; if(!isSocURegistered) { ret = -1; goto cleanup; } ret = srvGetServiceHandle(&SOCU_handle, "soc:U"); if(ret != 0) goto cleanup; ret = svcControlMemory(&tmp, socContextAddr, 0, socContextSize, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE); if(ret != 0) goto cleanup; socContextAddr = tmp; ret = svcCreateMemoryBlock(&socMemhandle, (u32)socContextAddr, socContextSize, 0, 3); if(ret != 0) goto cleanup; ret = SOCU_Initialize(socMemhandle, socContextSize); if(ret != 0) goto cleanup; svcKernelSetState(0x10000, 2); miniSocEnabled = true; return 0; cleanup: AtomicDecrement(&miniSocRefCount); if(socMemhandle != 0) { svcCloseHandle(socMemhandle); socMemhandle = 0; } if(SOCU_handle != 0) { SOCU_Shutdown(); svcCloseHandle(SOCU_handle); SOCU_handle = 0; } if(tmp != 0) svcControlMemory(&tmp, socContextAddr, socContextAddr, socContextSize, MEMOP_FREE, MEMPERM_DONTCARE); return ret; }
static void alloc_thread_entry(void) { u32 tmp; svcControlMemory(&tmp, mch2.alloc_address, 0x0, mch2.alloc_size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE); svcExitThread(); }
void __attribute__((noreturn)) __ctru_exit(int rc) { // Run the global destructors __libc_fini_array(); // TODO: APT exit goes here // Unmap the linear heap svcControlMemory(&__linear_heap, __linear_heap, 0x0, __linear_heap_size, MEMOP_FREE, 0x0); // Unmap the application heap svcControlMemory(&heapBase, heapBase, 0x0, __heap_size, MEMOP_FREE, 0x0); // Jump to the loader if it provided a callback if (__system_retAddr) __system_retAddr(); // Since above did not jump, end this process svcExitProcess(); }
void __attribute__((noreturn)) __libctru_exit(int rc) { u32 tmp=0; // Unmap the linear heap svcControlMemory(&tmp, __linear_heap, 0x0, linear_heap_size, MEMOP_FREE, 0x0); // Unmap the application heap svcControlMemory(&tmp, __heapBase, 0x0, heap_size, MEMOP_FREE, 0x0); // Close some handles __destroy_handle_list(); // Jump to the loader if it provided a callback if (__system_retAddr) __system_retAddr(); // Since above did not jump, end this process svcExitProcess(); }
static void alloc_thread(void* arg) { u32 tmp; alloc_finished = false; while (lock_alloc) svcSleepThread(100); svcControlMemory(&tmp, alloc_address, 0x0, alloc_size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE); alloc_finished = true; svcExitThread(); }
void __attribute__((weak)) __system_allocateHeaps(void) { u32 tmp=0; if (!__ctru_heap_size) { // Automatically allocate all remaining free memory, aligning to page size. __ctru_heap_size = osGetMemRegionFree(MEMREGION_APPLICATION) &~ 0xFFF; if (__ctru_heap_size <= __ctru_linear_heap_size) svcBreak(USERBREAK_PANIC); __ctru_heap_size -= __ctru_linear_heap_size; } // Allocate the application heap __ctru_heap = 0x08000000; svcControlMemory(&tmp, __ctru_heap, 0x0, __ctru_heap_size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE); // Allocate the linear heap svcControlMemory(&__ctru_linear_heap, 0x0, 0x0, __ctru_linear_heap_size, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE); // Set up newlib heap fake_heap_start = (char*)__ctru_heap; fake_heap_end = fake_heap_start + __ctru_heap_size; }
static void memchunkhax_write_pair(u32 val1, u32 val2) { u32 linear_buffer; u8* flush_buffer; u32 tmp; u32* next_ptr3; u32* prev_ptr3; u32* next_ptr1; u32* prev_ptr6; svcControlMemory(&linear_buffer, 0, 0, 0x10000, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE); flush_buffer = (u8*)(linear_buffer + 0x8000); svcControlMemory(&tmp, linear_buffer + 0x1000, 0, 0x1000, MEMOP_FREE, 0); svcControlMemory(&tmp, linear_buffer + 0x3000, 0, 0x2000, MEMOP_FREE, 0); svcControlMemory(&tmp, linear_buffer + 0x6000, 0, 0x1000, MEMOP_FREE, 0); next_ptr1 = (u32*)(linear_buffer + 0x0004); svchax_gspwn(linear_buffer + 0x0000, linear_buffer + 0x1000, 16, flush_buffer); next_ptr3 = (u32*)(linear_buffer + 0x2004); prev_ptr3 = (u32*)(linear_buffer + 0x2008); svchax_gspwn(linear_buffer + 0x2000, linear_buffer + 0x3000, 16, flush_buffer); prev_ptr6 = (u32*)(linear_buffer + 0x5008); svchax_gspwn(linear_buffer + 0x5000, linear_buffer + 0x6000, 16, flush_buffer); *next_ptr1 = *next_ptr3; *prev_ptr6 = *prev_ptr3; *prev_ptr3 = val1 - 4; *next_ptr3 = val2; svchax_gspwn(linear_buffer + 0x3000, linear_buffer + 0x2000, 16, flush_buffer); svcControlMemory(&tmp, 0, 0, 0x2000, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE); svchax_gspwn(linear_buffer + 0x1000, linear_buffer + 0x0000, 16, flush_buffer); svchax_gspwn(linear_buffer + 0x6000, linear_buffer + 0x5000, 16, flush_buffer); svcControlMemory(&tmp, linear_buffer + 0x0000, 0, 0x1000, MEMOP_FREE, 0); svcControlMemory(&tmp, linear_buffer + 0x2000, 0, 0x4000, MEMOP_FREE, 0); svcControlMemory(&tmp, linear_buffer + 0x7000, 0, 0x9000, MEMOP_FREE, 0); }
extern "C" void ctr_linear_free_pages(u32 pages) { if(sLinearPool.last->base + sLinearPool.last->size != (u8*)__linear_heap + __linear_heap_size) return; u32 size = pages << 12; if(size > sLinearPool.last->size) return; sLinearPool.last->size -= size; __linear_heap_size -= size; u32 tmp; svcControlMemory(&tmp, __linear_heap + __linear_heap_size, 0x0, size, MEMOP_FREE, (MemPerm)(MEMPERM_READ | MEMPERM_WRITE)); #if 0 printf("l:0x%08X-->0x%08X(-0x%08X) \n", sLinearPool.last->size + size, sLinearPool.last->size, size); DEBUG_HOLD(); #endif }
Result miniSocExit(void) { if(AtomicDecrement(&miniSocRefCount)) return 0; Result ret = 0; u32 tmp; svcCloseHandle(socMemhandle); socMemhandle = 0; ret = SOCU_Shutdown(); svcCloseHandle(SOCU_handle); SOCU_handle = 0; svcControlMemory(&tmp, socContextAddr, socContextAddr, socContextSize, MEMOP_FREE, MEMPERM_DONTCARE); if(ret == 0) { svcKernelSetState(0x10000, 2); miniSocEnabled = false; } return ret; }
int execute_cmd(int sock, cmd_t* cmd) { memset(&resp, 0, sizeof(resp)); resp.numarg=7; switch(cmd->type) { case 0: // exit return 0xDEAD; case 1: { // read u32 u32* p = (u32*) cmd->args[0]; resp.args[0] = *p; break; } case 2: { // write u32 u32* p = (u32*) cmd->args[0]; *p = cmd->args[1]; break; } case 3: { // get tls resp.args[0] = (u32) getThreadCommandBuffer(); break; } case 4: { // querymem MemInfo info; PageInfo flags; memset(&info, 0, sizeof(info)); memset(&flags, 0, sizeof(flags)); int ret = svcQueryMemory(&info, &flags, cmd->args[0]); resp.args[0] = ret; resp.args[1] = info.base_addr; resp.args[2] = info.size; resp.args[3] = info.perm; resp.args[4] = info.state; resp.args[5] = flags.flags; break; } case 5: { // creatememblock u32 handle = 0; int ret = svcCreateMemoryBlock(&handle, cmd->args[0], cmd->args[1], cmd->args[2], cmd->args[3]); resp.args[0] = ret; resp.args[1] = handle; break; } case 6: { // controlmem u32 outaddr = 0; int ret = svcControlMemory(&outaddr, cmd->args[0], cmd->args[1], cmd->args[2], cmd->args[3], cmd->args[4]); resp.args[0] = ret; resp.args[1] = outaddr; break; } case 7: { // getservicehandle Handle handle = 0; int ret = srvGetServiceHandle(&handle, (const char*) &cmd->args[0]); resp.args[0] = ret; resp.args[1] = handle; break; } case 8: { // syncrequest int ret = svcSendSyncRequest(cmd->args[0]); resp.args[0] = ret; break; } case 9: { // closehandle int ret = svcCloseHandle(cmd->args[0]); resp.args[0] = ret; break; } case 10: { // getctrulibhandle switch(cmd->args[0]) { case 0: { // gsp_handle extern Handle gspGpuHandle; resp.args[0] = gspGpuHandle; break; } } break; } case 11: { // malloc/free char* p = NULL; switch(cmd->args[0]) { case 0: { // normal-mem p = malloc(0x100); break; } case 1: { // linear-mem p = linearAlloc(0x100); break; } case 2: { // free normal-mem free((void*)cmd->args[1]); break; } case 3: { // free linear-mem linearFree((void*)cmd->args[1]); break; } } resp.args[0] = (u32) p; break; } case 12: { // enable/disable drawing enable_draw = cmd->args[0]; break; } default: return 0xDEAD; // unknown cmd } return 0; }