diff --git a/src/libc/allocator.src b/src/libc/allocator.src index 20edd7567..938576f70 100644 --- a/src/libc/allocator.src +++ b/src/libc/allocator.src @@ -4,6 +4,49 @@ public _malloc, _free, _realloc public _calloc + +if defined __TICE__ + +; uses the hardware specific $E40000 memory location + +; void *calloc(size_t nmemb, size_t size) +_calloc: + pop de + pop bc + ex (sp), hl + push bc + push de + call __imulu + push hl + push hl + call _malloc + pop bc ; reset SP + ; test for NULL + add hl, bc + ; or a, a ; assumes that ptr + size does not overflow on TICE + sbc hl, bc + pop bc ; BC = size + ret z ; return NULL + ; inlined bzero + push hl + ex de, hl ; DE = dest + ; test if the size is zero + scf + sbc hl, hl + add hl, bc + jr nc, .finish + ; large region of all zeros on the Ti84CE + ld hl, $E40000 ; HL = src + ldir +.finish: + pop hl ; return value + ret + +else + +; makes no hardware assumptions + +; void *calloc(size_t nmemb, size_t size) _calloc: pop de pop bc @@ -27,6 +70,8 @@ _calloc: pop de ret +end if + if defined ALLOCATOR_SIMPLE _malloc := __simple_malloc diff --git a/src/libc/allocator_simple.src b/src/libc/allocator_simple.src index 9ddde95d9..2c16ce612 100644 --- a/src/libc/allocator_simple.src +++ b/src/libc/allocator_simple.src @@ -4,13 +4,15 @@ public __simple_malloc __simple_malloc: + ; returns NULL when size is zero pop bc ex (sp),hl push bc ld de,(_heap_ptr) + dec hl add hl,de jr c,.null - ld bc,___heaptop + ld bc,___heaptop-1 sbc hl,bc jr nc,.null add hl,bc diff --git a/src/libc/allocator_standard.c b/src/libc/allocator_standard.c index aa78ec87a..f2af8aa25 100644 --- a/src/libc/allocator_standard.c +++ b/src/libc/allocator_standard.c @@ -21,7 +21,8 @@ void *_standard_malloc(size_t alloc_size) /* add size of block header to real size */ const size_t size = alloc_size + sizeof(block_t); - if (size < alloc_size) + /* abort if alloc_size is 0 or size overflowed */ + if (size <= alloc_size) { return NULL; } diff --git a/test/standalone/asprintf_fprintf/src/main.c b/test/standalone/asprintf_fprintf/src/main.c index 7fcde2e94..70515b59d 100644 --- a/test/standalone/asprintf_fprintf/src/main.c +++ b/test/standalone/asprintf_fprintf/src/main.c @@ -418,6 +418,12 @@ int memccpy_tests(void) { return __LINE__; } + /* check that no crashes occur with small calloc sizes */ + buf = (char*)calloc(1, sizeof(char)); + free(buf); + buf = (char*)calloc(0, sizeof(char)); + free(buf); + buf = (char*)calloc(file_size + 1, sizeof(char)); if (buf == NULL) { perror("calloc failure");