diff --git a/lib/ulibc/CMakeLists.txt b/lib/ulibc/CMakeLists.txt index 209e181..3f1136f 100644 --- a/lib/ulibc/CMakeLists.txt +++ b/lib/ulibc/CMakeLists.txt @@ -1,4 +1,4 @@ -set(source_dirs string stdio unistd) +set(source_dirs string stdio unistd stdlib) foreach (dir ${source_dirs}) file(GLOB dir_sources ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*.c) file(GLOB dir_headers ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*.h) diff --git a/lib/ulibc/include/errno.h b/lib/ulibc/include/errno.h new file mode 100644 index 0000000..7deb9de --- /dev/null +++ b/lib/ulibc/include/errno.h @@ -0,0 +1,7 @@ +#ifndef ERRNO_H_ +#define ERRNO_H_ + +#define EINVAL 1 +#define ENOMEM 2 + +#endif diff --git a/lib/ulibc/include/stdlib.h b/lib/ulibc/include/stdlib.h new file mode 100644 index 0000000..9bab2c4 --- /dev/null +++ b/lib/ulibc/include/stdlib.h @@ -0,0 +1,13 @@ +#ifndef STDLIB_H_ +#define STDLIB_H_ + +#include + +extern void abort(void); + +extern void *malloc(size_t count); +extern void *calloc(size_t count, size_t size); +extern void *realloc(void *p, size_t count); +extern void free(void *p); + +#endif diff --git a/lib/ulibc/stdlib/abort.c b/lib/ulibc/stdlib/abort.c new file mode 100644 index 0000000..eb4d4ce --- /dev/null +++ b/lib/ulibc/stdlib/abort.c @@ -0,0 +1,4 @@ +void abort(void) +{ + /* TODO */ +} diff --git a/lib/ulibc/stdlib/malloc.c b/lib/ulibc/stdlib/malloc.c index 9f4bcf6..b5aa73b 100644 --- a/lib/ulibc/stdlib/malloc.c +++ b/lib/ulibc/stdlib/malloc.c @@ -589,7 +589,15 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP #endif /* DARWIN */ #if defined(__mango__) -#define LACKS_SYS_TYPES_H +#include +#define LACKS_SYS_TYPES_H 1 +#define NO_MALLOC_STATS 1 +#define HAVE_MORECORE 1 +#define HAVE_MMAP 0 +#define LACKS_TIME_H 1 +#define LACKS_SCHED_H 1 +#define LACKS_SYS_PARAM_H 1 +#define MALLOC_FAILURE_ACTION #endif #ifndef LACKS_SYS_TYPES_H diff --git a/lib/ulibc/unistd/sbrk.c b/lib/ulibc/unistd/sbrk.c index 20eb133..1c42030 100644 --- a/lib/ulibc/unistd/sbrk.c +++ b/lib/ulibc/unistd/sbrk.c @@ -1,25 +1,96 @@ +#include +#include #include #include #include #define BRK_SIZE 0x400000 -static kern_handle_t heap_region = KERN_HANDLE_INVALID; -static kern_handle_t heap_object = KERN_HANDLE_INVALID; +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; - return NULL; + 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 (heap_region == KERN_HANDLE_INVALID - || heap_object == KERN_HANDLE_INVALID) { - return init_brk(BRK_SIZE); + if (brk_region == KERN_HANDLE_INVALID + || brk_object == KERN_HANDLE_INVALID) { + init_brk(BRK_SIZE); } - return (void *)-1; + if (brk_ptr == 0 || brk_ptr >= brk_base + BRK_SIZE) { + return (void *)-1; + } + + void *result = (void *)brk_ptr; + brk_ptr += increment; + return result; }