Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/libc/bzero.src
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@

.ifdef __TICE__

.ifdef PREFER_OS_LIBC

; ti.boot.memclear
.set _bzero, 0x0000B0

.else

; uses the hardware specific $E40000 memory location

; void bzero(void* buf, size_t n)
Expand All @@ -24,6 +31,8 @@ _bzero:
ldir
ret

.endif

.else

; makes no hardware assumptions
Expand Down
29 changes: 17 additions & 12 deletions src/libc/calloc.src
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,27 @@ _calloc:
pop bc ; BC = size
; test for NULL
add hl, bc
; or a, a ; .assumes that ptr + size does not overflow
; or a, a ; assumes that ptr + size does not overflow
sbc hl, bc
ret z ; return NULL
; inlined bzero
push hl
ex de, hl ; DE = dest
; test if the size is zero

dec bc
add hl, bc ; move to the end of dst
; non-zero + (size - 1) sets carry if size is zero
jr c, .L.zero_size
inc bc
ex de, hl ; DE = dst
; uses an all zeros address range $FB0000-$FFFFFF on the Ti84CE (327680 bytes)
; $FF0000-$FFFFFF (65536 bytes) has 1 wait state.
; $FB0000-$FEFFFF has 2 wait states, but a calloc larger than 65536 bytes is basically never.
; Since we are only reading zeros, writing to this address range should not interfere with CEmu.
scf
sbc hl, hl
add hl, bc
jr nc, .L.finish
; large region of all zeros on the Ti84CE
ld hl, $E40000 ; HL = src
ldir
.L.finish:
pop hl ; return value
sbc hl, hl ; HL = src
lddr
ex de, hl
.L.zero_size:
inc hl
ret

.else
Expand Down
65 changes: 58 additions & 7 deletions test/standalone/asprintf_fprintf/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ __attribute__((__unused__)) static void print_string(const char* str) {
// prevents Clang from replacing function calls with builtins
#if RENAME_FUNCTIONS

// this does not have __attribute__((malloc)) so we can test aliasing
void *T_malloc(size_t size);

// this does not have __attribute__((malloc)) so we can test aliasing
void *T_calloc(size_t nmemb, size_t size);

void T_bzero(void* s, size_t n);

void *T_memccpy(void *__restrict dest, const void *__restrict src, int c, size_t n)
Expand Down Expand Up @@ -182,6 +188,8 @@ char *T_strtok_r(char *__restrict s, const char *__restrict delim, char **__rest

#else

#define T_malloc malloc
#define T_calloc calloc
#define T_bzero bzero
#define T_memccpy memccpy
#define T_memchr memchr
Expand Down Expand Up @@ -571,12 +579,6 @@ 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");
Expand Down Expand Up @@ -662,7 +664,7 @@ int bzero_test(void) {
if (T_strlen(&data[2]) != 0) {
return __LINE__;
}
T_bzero(NULL, 0);

T_bzero(&data[8], 17);
int cmp = T_memcmp(data, truth, 32);
if (cmp != 0) {
Expand Down Expand Up @@ -1520,8 +1522,57 @@ int mem65536_test(void) {
return 0;
}

int alloc_test(void) {
/* test that malloc works and returns mutable memory */

buf = (char*)T_malloc(1);
C(buf != NULL);
*buf = 0xFF;
C(T_memcmp(buf, SINK, 1) > 0);
*buf = 0x00;
C(T_memcmp(buf, SINK, 1) == 0);
free(buf);

/* check that no crashes occur with small calloc sizes */

buf = (char*)T_calloc(1, sizeof(char));
C(buf != NULL && *buf == 0x00);
free(buf);

buf = (char*)T_calloc(2, sizeof(char));
C(buf != NULL && buf[0] == 0x00 && buf[1] == 0x00);
free(buf);

/* test allocating zero bytes */

/**
* malloc(0) is implementation defined, but it should be safe to assume
* that it does not return `buf`
*/
char * const Pointer_Not_From_Malloc = (char*)&buf;

buf = (char*)T_malloc(0);
C(buf != Pointer_Not_From_Malloc);
free(buf);

buf = (char*)T_calloc(0, sizeof(char));
C(buf != Pointer_Not_From_Malloc);
free(buf);

// ensure that we do not free twice
buf = NULL;
return 0;
}

int run_tests(void) {
int ret = 0;
buf = NULL;

/* malloc and calloc */
ret = alloc_test();
free(buf); buf = NULL;
if (ret != 0) { return ret; }

/* boot_asprintf */
ret = boot_sprintf_tests();
free(buf); buf = NULL;
Expand Down
68 changes: 39 additions & 29 deletions test/standalone/asprintf_fprintf/src/rename.s
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ _NULL_ptr:

.section .text

.global _T_malloc
.global _T_calloc
.global _T_bzero
.global _T_memccpy
.global _T_memchr
Expand Down Expand Up @@ -42,6 +44,12 @@ _NULL_ptr:

;-------------------------------------------------------------------------------

_T_malloc:
jp _malloc

_T_calloc:
jp _calloc

_T_bzero:
jp _bzero

Expand Down Expand Up @@ -131,32 +139,34 @@ _T_strtok_r:

;-------------------------------------------------------------------------------

.global _bzero
.global _memccpy
.global _memchr
.global _memcmp
.global _memcpy
.global _memmem
.global _memmove
.global _mempcpy
.global _memrchr
.global _memrmem
.global _memset
.global _stpcpy
.global _stpncpy
.global _strcat
.global _strchr
.global _strchrnul
.global _strcmp
.global _strcpy
.global _strlcat
.global _strlen
.global _strncat
.global _strncmp
.global _strncpy
.global _strnlen
.global _strrchr
.global _strrstr
.global _strstr
.global _strtok
.global _strtok_r
.extern _malloc
.extern _calloc
.extern _bzero
.extern _memccpy
.extern _memchr
.extern _memcmp
.extern _memcpy
.extern _memmem
.extern _memmove
.extern _mempcpy
.extern _memrchr
.extern _memrmem
.extern _memset
.extern _stpcpy
.extern _stpncpy
.extern _strcat
.extern _strchr
.extern _strchrnul
.extern _strcmp
.extern _strcpy
.extern _strlcat
.extern _strlen
.extern _strncat
.extern _strncmp
.extern _strncpy
.extern _strnlen
.extern _strrchr
.extern _strrstr
.extern _strstr
.extern _strtok
.extern _strtok_r
Loading