#include #include #include #include #include #define BRK_SIZE 0x400000 static virt_addr_t brk_base = 0, brk_ptr = 0; static kern_handle_t brk_region = KERN_HANDLE_INVALID; static kern_handle_t brk_object = KERN_HANDLE_INVALID; static void *init_brk(size_t size) { kern_status_t status = KERN_OK; kern_handle_t self, address_space; status = task_self(&self); if (status != KERN_OK) { return (void *)-1; } status = task_get_address_space(self, &address_space); if (status != KERN_OK) { kern_handle_close(self); return (void *)-1; } status = vm_object_create( "ulibc-brk", 10, BRK_SIZE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_USER, &brk_object); if (status != KERN_OK) { kern_handle_close(address_space); kern_handle_close(self); return (void *)-1; } status = vm_region_create( address_space, "ulibc-brk", 10, VM_REGION_ANY_OFFSET, BRK_SIZE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_USER, &brk_region, &brk_base); if (status != KERN_OK) { kern_handle_close(brk_object); kern_handle_close(address_space); kern_handle_close(self); brk_object = KERN_HANDLE_INVALID; return (void *)-1; } status = vm_region_map_relative( brk_region, 0, brk_object, 0, BRK_SIZE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_USER, NULL); if (status != KERN_OK) { kern_handle_close(brk_object); kern_handle_close(brk_region); kern_handle_close(address_space); kern_handle_close(self); brk_region = KERN_HANDLE_INVALID; brk_object = KERN_HANDLE_INVALID; return (void *)-1; } brk_ptr = brk_base; return (void *)brk_ptr; } void *sbrk(intptr_t increment) { kern_status_t status = KERN_OK; if (brk_region == KERN_HANDLE_INVALID || brk_object == KERN_HANDLE_INVALID) { init_brk(BRK_SIZE); } if (brk_ptr == 0 || brk_ptr >= brk_base + BRK_SIZE) { return (void *)-1; } void *result = (void *)brk_ptr; brk_ptr += increment; return result; }