diff --git a/lang/cem/libcc.ansi/malloc/calloc.c b/lang/cem/libcc.ansi/malloc/calloc.c new file mode 100644 index 000000000..2e9d3be16 --- /dev/null +++ b/lang/cem/libcc.ansi/malloc/calloc.c @@ -0,0 +1,23 @@ +#include +#include +#include + +void* calloc(size_t nmemb, size_t size) +{ + size_t bytes = nmemb * size; + void* ptr; + + /* Test for overflow. + * See http://stackoverflow.com/questions/1815367/multiplication-of-large-numbers-how-to-catch-overflow + */ + + if ((nmemb == 0) || (size == 0) || (nmemb > (SIZE_MAX / size))) + return NULL; + + ptr = malloc(bytes); + if (!ptr) + return NULL; + + memset(ptr, 0, bytes); + return ptr; +} diff --git a/plat/cpm/include/unistd.h b/plat/cpm/include/unistd.h index 2af9db921..ea4f51c0f 100644 --- a/plat/cpm/include/unistd.h +++ b/plat/cpm/include/unistd.h @@ -37,7 +37,7 @@ extern char** environ; extern void _exit(int); extern pid_t getpid(void); -extern void* sbrk(intptr_t increment); +extern void* sbrk(int increment); extern int isatty(int d); extern off_t lseek(int fildes, off_t offset, int whence); extern int close(int d); diff --git a/plat/cpm/libsys/brk.c b/plat/cpm/libsys/brk.c index e29dc565b..0b83b2523 100644 --- a/plat/cpm/libsys/brk.c +++ b/plat/cpm/libsys/brk.c @@ -28,7 +28,7 @@ int brk(void* newend) return 0; } -void* sbrk(intptr_t increment) +void* sbrk(int increment) { char* old; diff --git a/plat/linux/libsys/brk.c b/plat/linux/libsys/brk.c deleted file mode 100644 index 7ce5c5fc8..000000000 --- a/plat/linux/libsys/brk.c +++ /dev/null @@ -1,17 +0,0 @@ -/* $Source: /cvsroot/tack/Ack/plat/linux386/libsys/brk.c,v $ - * $State: Exp $ - * $Revision: 1.1 $ - */ - -#include -#include -#include -#include "libsys.h" - -int brk(void* end) -{ - int e = _syscall(__NR_brk, (quad) end, 0, 0); - if (e == -1) - errno = ENOMEM; - return e; -} diff --git a/plat/linux/libsys/sbrk.c b/plat/linux/libsys/sbrk.c index 35810ef89..7aeeecb86 100644 --- a/plat/linux/libsys/sbrk.c +++ b/plat/linux/libsys/sbrk.c @@ -12,7 +12,17 @@ static char* current = NULL; -void* sbrk(intptr_t increment) +int brk(void* end) +{ + int e = _syscall(__NR_brk, (quad) end, 0, 0); + if (e == -1) + errno = ENOMEM; + else + current = end; + return e; +} + +void* sbrk(int increment) { char* old; char* new; diff --git a/plat/linux386/include/unistd.h b/plat/linux386/include/unistd.h index 715e321d7..35dc8dde7 100644 --- a/plat/linux386/include/unistd.h +++ b/plat/linux386/include/unistd.h @@ -67,7 +67,7 @@ extern char** environ; extern void _exit(int); extern pid_t getpid(void); extern int brk(void* ptr); -extern void* sbrk(intptr_t increment); +extern void* sbrk(int increment); extern int isatty(int d); /* Signal handling */ diff --git a/plat/linux68k/include/unistd.h b/plat/linux68k/include/unistd.h index 5cbdc1b5d..307192f77 100644 --- a/plat/linux68k/include/unistd.h +++ b/plat/linux68k/include/unistd.h @@ -65,7 +65,7 @@ extern char** environ; extern void _exit(int); extern pid_t getpid(void); extern int brk(void* ptr); -extern void* sbrk(intptr_t increment); +extern void* sbrk(int increment); extern int isatty(int d); /* Signal handling */ diff --git a/plat/linuxppc/include/unistd.h b/plat/linuxppc/include/unistd.h index 5cbdc1b5d..307192f77 100644 --- a/plat/linuxppc/include/unistd.h +++ b/plat/linuxppc/include/unistd.h @@ -65,7 +65,7 @@ extern char** environ; extern void _exit(int); extern pid_t getpid(void); extern int brk(void* ptr); -extern void* sbrk(intptr_t increment); +extern void* sbrk(int increment); extern int isatty(int d); /* Signal handling */ diff --git a/plat/pc86/include/unistd.h b/plat/pc86/include/unistd.h index 2af9db921..ea4f51c0f 100644 --- a/plat/pc86/include/unistd.h +++ b/plat/pc86/include/unistd.h @@ -37,7 +37,7 @@ extern char** environ; extern void _exit(int); extern pid_t getpid(void); -extern void* sbrk(intptr_t increment); +extern void* sbrk(int increment); extern int isatty(int d); extern off_t lseek(int fildes, off_t offset, int whence); extern int close(int d); diff --git a/plat/pc86/libsys/brk.c b/plat/pc86/libsys/brk.c index 02e213399..952a9c747 100644 --- a/plat/pc86/libsys/brk.c +++ b/plat/pc86/libsys/brk.c @@ -28,7 +28,7 @@ int brk(void* newend) return 0; } -void* sbrk(intptr_t increment) +void* sbrk(int increment) { char* old; diff --git a/plat/qemuppc/include/unistd.h b/plat/qemuppc/include/unistd.h index 5cbdc1b5d..307192f77 100644 --- a/plat/qemuppc/include/unistd.h +++ b/plat/qemuppc/include/unistd.h @@ -65,7 +65,7 @@ extern char** environ; extern void _exit(int); extern pid_t getpid(void); extern int brk(void* ptr); -extern void* sbrk(intptr_t increment); +extern void* sbrk(int increment); extern int isatty(int d); /* Signal handling */ diff --git a/plat/qemuppc/libsys/brk.c b/plat/qemuppc/libsys/brk.c index 02e213399..952a9c747 100644 --- a/plat/qemuppc/libsys/brk.c +++ b/plat/qemuppc/libsys/brk.c @@ -28,7 +28,7 @@ int brk(void* newend) return 0; } -void* sbrk(intptr_t increment) +void* sbrk(int increment) { char* old; diff --git a/plat/qemuppc/tests/brk_c.c b/plat/qemuppc/tests/brk_c.c new file mode 100644 index 000000000..aa0f7ef99 --- /dev/null +++ b/plat/qemuppc/tests/brk_c.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include +#include +#include "test.h" + +int main(int argc, const char* argv[]) +{ + void* p; + + ASSERT(-1 == (intptr_t)brk((void*)0xffffffff)); + ASSERT(ENOMEM == errno); + + p = sbrk(0); + ASSERT(p == sbrk(0)); + ASSERT(p == sbrk(8)); + ASSERT(p != sbrk(0)); + ASSERT(p != sbrk(-8)); + ASSERT(p == sbrk(0)); + + /* We assume the test environment has less than 2GB of RAM. */ + ASSERT(-1 == (intptr_t)sbrk(INT_MAX)); + ASSERT(-1 == (intptr_t)sbrk(INT_MIN)); + + finished(); +} + diff --git a/plat/qemuppc/tests/calloc_c.c b/plat/qemuppc/tests/calloc_c.c new file mode 100644 index 000000000..518aa7e49 --- /dev/null +++ b/plat/qemuppc/tests/calloc_c.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include "test.h" + +int main(int argc, const char* argv[]) +{ + const char* p; + int i; + + ASSERT(0 == calloc(0, 0)); + ASSERT(0 == calloc(0, 1)); + ASSERT(0 == calloc(1, 0)); + ASSERT(0 == calloc(SIZE_MAX/2, 3)); + ASSERT(0 == calloc(SIZE_MAX/2, 2)); + ASSERT(0 != calloc(1, 1)); + + p = calloc(10, 1); + for (i=0; i<10; i++) + ASSERT(0 == p[i]); + + finished(); +} diff --git a/plat/rpi/include/unistd.h b/plat/rpi/include/unistd.h index a4d0c4507..196b823c4 100644 --- a/plat/rpi/include/unistd.h +++ b/plat/rpi/include/unistd.h @@ -59,7 +59,7 @@ extern char** environ; extern void _exit(int); extern pid_t getpid(void); -extern void* sbrk(intptr_t increment); +extern void* sbrk(int increment); extern int isatty(int d); extern off_t lseek(int fildes, off_t offset, int whence); extern int close(int d); diff --git a/plat/rpi/libsys/brk.c b/plat/rpi/libsys/brk.c index 36c7d4a6f..171b8e5cf 100644 --- a/plat/rpi/libsys/brk.c +++ b/plat/rpi/libsys/brk.c @@ -30,7 +30,7 @@ int brk(void* newend) return 0; } -void* sbrk(intptr_t increment) +void* sbrk(int increment) { char* old;