aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@leaflabs.com>2011-09-07 14:39:44 -0400
committerMarti Bolivar <mbolivar@leaflabs.com>2011-09-07 23:34:24 -0400
commit3c0a3ee2516e6709484a922b8298c84eccf87490 (patch)
treef245144d9759921907a66df1300083b4d60ae911
parentaa4f3b6645a17c98aa4679323208ed8636ba89b1 (diff)
syscalls.c: Bugfix _sbrk() implementation.
Fix _sbrk() implementation so it properly rejects negative arguments which would send the program break below the heap start. Fix incorrect check against argument causing heap overflow. Also set errno properly to ENOMEM when the call fails. Beginning and end of the heap are now determined by HEAP_START and HEAP_END macros. Their current values seem to work OK for heaps on the internal SRAM, but they'll need to get generalized for Maple Native.
-rw-r--r--libmaple/syscalls.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/libmaple/syscalls.c b/libmaple/syscalls.c
index ae80010..f28202c 100644
--- a/libmaple/syscalls.c
+++ b/libmaple/syscalls.c
@@ -25,32 +25,47 @@
*****************************************************************************/
#include "libmaple.h"
+
#include <sys/stat.h>
+#include <errno.h>
-/* _end is set in the linker command file */
-extern caddr_t _end;
+/* Set by the linker script */
+extern int _end;
+/* FIXME these should be determined by the linker script.
+ *
+ * Doing so will allow the heap to be configured on a per-board basis.
+ * Current values are just stopgaps for a heap in built-in SRAM.
+ *
+ * STACK_RESERVED_BYTES is just a hack to ensure a minimum stack size.
+ * It should probably go away as well. */
+#define STACK_RESERVED_BYTES 1024
+#define HEAP_START ((caddr_t)&_end)
+#define HEAP_END ((caddr_t)((uint32)STM32_SRAM_END - \
+ STACK_RESERVED_BYTES))
/*
- * sbrk -- changes heap size size. Get nbytes more
- * RAM. We just increment a pointer in what's
- * left of memory on the board.
+ * _sbrk -- Increment the program break.
+ *
+ * Get incr bytes more RAM (for use by the heap). malloc() and
+ * friends call this function behind the scenes.
*/
-caddr_t _sbrk(int nbytes) {
- static caddr_t heap_ptr = NULL;
- caddr_t base;
+caddr_t _sbrk(int incr) {
+ static caddr_t pbreak = NULL; /* current program break */
+ caddr_t ret;
- if (heap_ptr == NULL) {
- heap_ptr = (caddr_t)&_end;
+ if (pbreak == NULL) {
+ pbreak = HEAP_START;
}
- if ((STACK_TOP - (unsigned int)heap_ptr) >= 0) {
- base = heap_ptr;
- heap_ptr += nbytes;
- return (base);
- } else {
- return ((caddr_t)-1);
+ if ((HEAP_END - pbreak < incr) || (pbreak - HEAP_START < -incr)) {
+ errno = ENOMEM;
+ return (caddr_t)-1;
}
+
+ ret = pbreak;
+ pbreak += incr;
+ return ret;
}
int _open(const char *path, int flags, ...) {