From 0aac9aafd3a4e81171d1a4a4ed50f39366df1450 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 23 Nov 2016 22:04:21 +0100 Subject: [PATCH 1/5] Combine brk() with sbrk(); modify brk() to update the sbrk(0) value. --- plat/linux/libsys/brk.c | 17 ----------------- plat/linux/libsys/sbrk.c | 10 ++++++++++ 2 files changed, 10 insertions(+), 17 deletions(-) delete mode 100644 plat/linux/libsys/brk.c 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..0948a41b8 100644 --- a/plat/linux/libsys/sbrk.c +++ b/plat/linux/libsys/sbrk.c @@ -12,6 +12,16 @@ static char* current = NULL; +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(intptr_t increment) { char* old; From 36ab90385fb33c3e7bec0fcb58de70ad1b464d4a Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 23 Nov 2016 22:06:24 +0100 Subject: [PATCH 2/5] Change sbrk() to take an int rather than an intptr_t (following the OpenBSD way rather than the Linux way; various non-C bits of the ACK assume it takes an int, so it's cleaner). --- plat/cpm/include/unistd.h | 2 +- plat/cpm/libsys/brk.c | 2 +- plat/linux/libsys/sbrk.c | 2 +- plat/linux386/include/unistd.h | 2 +- plat/linux68k/include/unistd.h | 2 +- plat/linuxppc/include/unistd.h | 2 +- plat/pc86/include/unistd.h | 2 +- plat/pc86/libsys/brk.c | 2 +- plat/qemuppc/include/unistd.h | 2 +- plat/qemuppc/libsys/brk.c | 2 +- plat/rpi/include/unistd.h | 2 +- plat/rpi/libsys/brk.c | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) 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/sbrk.c b/plat/linux/libsys/sbrk.c index 0948a41b8..7aeeecb86 100644 --- a/plat/linux/libsys/sbrk.c +++ b/plat/linux/libsys/sbrk.c @@ -22,7 +22,7 @@ int brk(void* end) return e; } -void* sbrk(intptr_t increment) +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/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; From 9481487e3d156ca18742c124735f1bc52ebfa616 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 23 Nov 2016 22:16:25 +0100 Subject: [PATCH 3/5] Implement calloc() (accidentally got dropped with the malloc rewrite). --- lang/cem/libcc.ansi/malloc/calloc.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 lang/cem/libcc.ansi/malloc/calloc.c 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; +} From 6cd2a9ba81788cf89ae2ff1c7fcf4b5c4c715181 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 23 Nov 2016 22:22:04 +0100 Subject: [PATCH 4/5] Add a test for calloc(). --- plat/qemuppc/tests/calloc_c.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 plat/qemuppc/tests/calloc_c.c 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(); +} From 991f47098ceb2d812808f730d15f7fa21c79d33e Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 23 Nov 2016 22:28:21 +0100 Subject: [PATCH 5/5] Add a test for brk() and sbrk(). --- plat/qemuppc/tests/brk_c.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 plat/qemuppc/tests/brk_c.c 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(); +} +