diff options
Diffstat (limited to 'code/fe310/gloss/sys_sbrk.c')
-rw-r--r-- | code/fe310/gloss/sys_sbrk.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/code/fe310/gloss/sys_sbrk.c b/code/fe310/gloss/sys_sbrk.c new file mode 100644 index 0000000..cc01c8f --- /dev/null +++ b/code/fe310/gloss/sys_sbrk.c @@ -0,0 +1,39 @@ +#include <sys/types.h> + +/* brk is handled entirely within the C library. This limits METAL programs that + * use the C library to be disallowed from dynamically allocating memory + * without talking to the C library, but that sounds like a sane way to go + * about it. Note that there is no error checking anywhere in this file, users + * will simply get the relevant error when actually trying to use the memory + * that's been allocated. */ +extern char metal_segment_heap_target_start; +extern char metal_segment_heap_target_end; +static char *brk = &metal_segment_heap_target_start; + +int +_brk(void *addr) +{ + brk = addr; + return 0; +} + +char * +_sbrk(ptrdiff_t incr) +{ + char *old = brk; + + /* If __heap_size == 0, we can't allocate memory on the heap */ + if(&metal_segment_heap_target_start == &metal_segment_heap_target_end) { + return (void *)-1; + } + + /* Don't move the break past the end of the heap */ + if ((brk + incr) < &metal_segment_heap_target_end) { + brk += incr; + } else { + brk = &metal_segment_heap_target_end; + return (void *)-1; + } + + return old; +} |