#include <3ds.h> #include #include #include #include "ctr_debug.h" //void* malloc(size_t nbytes) //{ // void* ret = _malloc_r (_REENT, nbytes); // return ret; //} //void free (void* aptr) //{ // _free_r (_REENT, aptr); //} extern u32 __heapBase; extern u32 __heap_size; extern u32 __stack_bottom; extern u32 __stack_size_extra; extern u32 __stacksize__; u32 ctr_get_linear_free(void); u32 ctr_get_linear_unused(void); u32 ctr_get_stack_free(void) { extern u32 __stack_bottom; uint32_t* stack_bottom_current = (u32*)__stack_bottom; while(*stack_bottom_current++ == 0xFCFCFCFC); stack_bottom_current--; return ((u32)stack_bottom_current - __stack_bottom); } u32 ctr_get_stack_usage(void) { extern u32 __stacksize__; u32 stack_free = ctr_get_stack_free(); return __stacksize__ > stack_free? __stacksize__ - stack_free: 0; } void ctr_linear_free_pages(u32 pages); void ctr_free_pages(u32 pages) { if(!pages) return; u32 linear_free_pages = ctr_get_linear_free() >> 12; if((ctr_get_linear_unused() >> 12) > pages + 0x100) return ctr_linear_free_pages(pages); // if(linear_free_pages > pages + 0x400) // return ctr_linear_free_pages(pages); u32 stack_free = ctr_get_stack_free(); u32 stack_usage = __stacksize__ > stack_free? __stacksize__ - stack_free: 0; stack_free = stack_free > __stack_size_extra ? __stack_size_extra : stack_free; u32 stack_free_pages = stack_free >> 12; if(linear_free_pages + (stack_free_pages - (stack_usage >> 12)) > pages) { stack_free_pages -= (stack_usage >> 12); stack_free_pages = stack_free_pages > pages ? pages : stack_free_pages; linear_free_pages = pages - stack_free_pages; } else if(linear_free_pages + stack_free_pages > pages) stack_free_pages = pages - linear_free_pages; else return; if(linear_free_pages) ctr_linear_free_pages(linear_free_pages); if(stack_free_pages) { u32 tmp; svcControlMemory(&tmp, __stack_bottom, 0x0, stack_free_pages << 12, MEMOP_FREE, MEMPERM_READ | MEMPERM_WRITE); __stack_bottom += stack_free_pages << 12; __stack_size_extra -= stack_free_pages << 12; __stacksize__ -= stack_free_pages << 12; // printf("s:0x%08X-->0x%08X(-0x%08X) \n", stack_free, // stack_free - (stack_free_pages << 12), stack_free_pages << 12); // DEBUG_HOLD(); } } u32 ctr_get_free_space(void) { u32 app_memory = *((u32*)0x1FF80040); s64 mem_used; svcGetSystemInfo(&mem_used, 0, 1); return app_memory - (u32)mem_used; } void ctr_request_free_pages(u32 pages) { u32 free_pages = ctr_get_free_space() >> 12; if (pages > free_pages) { ctr_free_pages(pages - free_pages); free_pages = ctr_get_free_space() >> 12; } } void* _sbrk_r(struct _reent *ptr, ptrdiff_t incr) { static u32 sbrk_top = 0; if (!sbrk_top) sbrk_top = __heapBase; u32 tmp; int diff = ((sbrk_top + incr + 0xFFF) & ~0xFFF) - (__heapBase + __heap_size); if (diff > 0) { ctr_request_free_pages(diff >> 12); if (svcControlMemory(&tmp, __heapBase + __heap_size, 0x0, diff, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE) < 0) { ptr->_errno = ENOMEM; return (caddr_t) -1; } } __heap_size += diff; if (diff < 0) svcControlMemory(&tmp, __heapBase + __heap_size, 0x0, -diff, MEMOP_FREE, MEMPERM_READ | MEMPERM_WRITE); sbrk_top += incr; return (caddr_t)(sbrk_top - incr); }