diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/__readonly.c | 37 | ||||
-rw-r--r-- | src/_readonly.h | 12 | ||||
-rw-r--r-- | src/_syscall.h | 1 | ||||
-rw-r--r-- | src/locale/setlocale.c | 10 | ||||
-rw-r--r-- | src/signal/sigaction.c | 9 | ||||
-rw-r--r-- | src/signal/siginfo_t.h | 75 | ||||
-rw-r--r-- | src/stdlib/__jkmalloc.c | 381 | ||||
-rw-r--r-- | src/stdlib/_jkmalloc.h | 6 | ||||
-rw-r--r-- | src/stdlib/aligned_alloc.c | 5 | ||||
-rw-r--r-- | src/stdlib/calloc.c | 19 | ||||
-rw-r--r-- | src/stdlib/free.c | 7 | ||||
-rw-r--r-- | src/stdlib/malloc.c | 7 | ||||
-rw-r--r-- | src/stdlib/realloc.c | 46 | ||||
-rw-r--r-- | src/string/strerror.c | 13 | ||||
-rw-r--r-- | src/tgmath/acos.h | 19 |
15 files changed, 564 insertions, 83 deletions
diff --git a/src/__readonly.c b/src/__readonly.c new file mode 100644 index 00000000..74837a91 --- /dev/null +++ b/src/__readonly.c @@ -0,0 +1,37 @@ +#include <stdlib.h> +#include "_readonly.h" + +#ifdef _POSIX_C_SOURCE +#include <sys/mman.h> +#include <limits.h> +#else +#include "_syscall.h" +#define mprotect(__ptr, __len, __prot) __syscall(__sys_mprotect, __ptr, __len, __prot) +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PAGESIZE 4096 +#endif + +void* __readonly(ro_action_t action, void *ptr) +{ + switch (action) { + case RO_ALLOC: + /* set magic to JK_READONLY */ + /* set label to ptr */ + return malloc(PAGESIZE); + + case RO_FREE: + free(ptr); + return NULL; + + case RO_LOCK: + mprotect(ptr, PAGESIZE, PROT_READ); + break; + + case RO_UNLOCK: + mprotect(ptr, PAGESIZE, PROT_READ | PROT_WRITE); + break; + } + + return ptr; +} diff --git a/src/_readonly.h b/src/_readonly.h new file mode 100644 index 00000000..a3e07d60 --- /dev/null +++ b/src/_readonly.h @@ -0,0 +1,12 @@ +#ifndef ___READONLY_H__ + +typedef enum { + RO_ALLOC, + RO_FREE, + RO_LOCK, + RO_UNLOCK, +} ro_action_t; + +void *__readonly(ro_action_t, void *); + +#endif diff --git a/src/_syscall.h b/src/_syscall.h index aa97fadf..d47aff32 100644 --- a/src/_syscall.h +++ b/src/_syscall.h @@ -83,6 +83,7 @@ long __syscall(long __number, ...); #define __sys_mknod 133 #define __sys_mmap 9 #define __sys_munmap 11 +#define __sys_mprotect 10 #define __sys_nanosleep 35 /* needed for POSIX < 199309 when nanosleep becomes __nanosleep */ diff --git a/src/locale/setlocale.c b/src/locale/setlocale.c index bfc15342..43a69787 100644 --- a/src/locale/setlocale.c +++ b/src/locale/setlocale.c @@ -3,11 +3,13 @@ #include <stdlib.h> #include "_locale.h" #include "_safety.h" +#include "_readonly.h" /** get or set program locale **/ char * setlocale(int category, const char *locale) { + static char *retname = NULL; struct __locale_t *l = __get_locale(); int mask = 0; @@ -42,7 +44,13 @@ char * setlocale(int category, const char *locale) } /* TODO: mark return value read-only */ - return __load_locale(l, mask, locale); + if (retname == NULL) { + retname = __readonly(RO_ALLOC, "setlocale"); + } + __readonly(RO_UNLOCK, retname); + strcpy(retname, __load_locale(l, mask, locale)); + //__readonly(RO_LOCK, retname); + return retname; } CHECK_2(char *, NULL, setlocale, int, const char *) diff --git a/src/signal/sigaction.c b/src/signal/sigaction.c index f95301e9..1e9db8cb 100644 --- a/src/signal/sigaction.c +++ b/src/signal/sigaction.c @@ -1,9 +1,8 @@ -#if 0 #include <stddef.h> -#include <sys/types.h> #include <signal.h> #include "_syscall.h" +#include "_safety.h" int sigaction(int sig, const struct sigaction * restrict act, struct sigaction * restrict oact) { @@ -12,7 +11,7 @@ int sigaction(int sig, const struct sigaction * restrict act, struct sigaction * struct linux_action { union { void (*handler)(int); - void (*action)(int, struct sigaction *, void *); + void (*action)(int, siginfo_t *, void *); } fn; unsigned long flags; void (*restorer)(void); @@ -27,6 +26,7 @@ int sigaction(int sig, const struct sigaction * restrict act, struct sigaction * #ifdef SA_SIGINFO if (act->sa_flags & SA_SIGINFO) { a.fn.action = act->sa_sigaction; + } #endif a.flags = act->sa_flags; @@ -51,6 +51,3 @@ int sigaction(int sig, const struct sigaction * restrict act, struct sigaction * /* POSIX(1) */ - - -#endif diff --git a/src/signal/siginfo_t.h b/src/signal/siginfo_t.h index 39c0b19a..19a443e8 100644 --- a/src/signal/siginfo_t.h +++ b/src/signal/siginfo_t.h @@ -1,5 +1,6 @@ #include <signal.h> +#if 0 typedef struct { int si_signo; int si_code; @@ -11,6 +12,80 @@ typedef struct { int si_errno; union sigval si_value; } siginfo_t; +#else + +typedef struct { +#ifdef __SI_SWAP_ERRNO_CODE + int si_signo, si_code, si_errno; +#else + int si_signo, si_errno, si_code; +#endif + union { + char __pad[128 - 2*sizeof(int) - sizeof(long)]; + struct { + union { + struct { + pid_t si_pid; + uid_t si_uid; + } __piduid; + struct { + int si_timerid; + int si_overrun; + } __timer; + } __first; + union { + union sigval si_value; + struct { + int si_status; + clock_t si_utime, si_stime; + } __sigchld; + } __second; + } __si_common; + struct { + void *si_addr; + short si_addr_lsb; + union { + struct { + void *si_lower; + void *si_upper; + } __addr_bnd; + unsigned si_pkey; + } __first; + } __sigfault; + struct { + long si_band; + int si_fd; + } __sigpoll; + struct { + void *si_call_addr; + int si_syscall; + unsigned si_arch; + } __sigsys; + } __si_fields; +} siginfo_t; + +#define si_pid __si_fields.__si_common.__first.__piduid.si_pid +#define si_uid __si_fields.__si_common.__first.__piduid.si_uid +#define si_status __si_fields.__si_common.__second.__sigchld.si_status +#define si_utime __si_fields.__si_common.__second.__sigchld.si_utime +#define si_stime __si_fields.__si_common.__second.__sigchld.si_stime +#define si_value __si_fields.__si_common.__second.si_value +#define si_addr __si_fields.__sigfault.si_addr +#define si_addr_lsb __si_fields.__sigfault.si_addr_lsb +#define si_lower __si_fields.__sigfault.__first.__addr_bnd.si_lower +#define si_upper __si_fields.__sigfault.__first.__addr_bnd.si_upper +#define si_pkey __si_fields.__sigfault.__first.si_pkey +#define si_band __si_fields.__sigpoll.si_band +#define si_fd __si_fields.__sigpoll.si_fd +#define si_timerid __si_fields.__si_common.__first.__timer.si_timerid +#define si_overrun __si_fields.__si_common.__first.__timer.si_overrun +#define si_ptr si_value.sival_ptr +#define si_int si_value.sival_int +#define si_call_addr __si_fields.__sigsys.si_call_addr +#define si_syscall __si_fields.__sigsys.si_syscall +#define si_arch __si_fields.__sigsys.si_arch + +#endif /* XOPEN(400) diff --git a/src/stdlib/__jkmalloc.c b/src/stdlib/__jkmalloc.c new file mode 100644 index 00000000..b97fa10c --- /dev/null +++ b/src/stdlib/__jkmalloc.c @@ -0,0 +1,381 @@ +#include <errno.h> +#include <limits.h> +#include <stdlib.h> +#include <signal.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#ifdef _XOPEN_SOURCE +#include <fcntl.h> +#include <sys/mman.h> +#include <unistd.h> +#else +#include "_syscall.h" + +#define sysconf(__n) 4096 + +#define mprotect(__ptr, __len, __prot) __syscall(__sys_mprotect, __ptr, __len, __prot) +#define mmap(_a, _l, _p, _fl, _fd, _o) (void*)__syscall(__sys_mmap, _a, _l, _p, _fl, _fd, _o) +#define munmap(_a, _l) __syscall(__sys_munmap, _a, _l) +#define open(_p, _a, _m) __syscall(__sys_open, _p, _a, _m) + +typedef unsigned long pid_t; +typedef unsigned long uid_t; +typedef unsigned long clock_t; +#include "signal/sigset_t.h" +#include "signal/union_sigval.h" +#include "signal/siginfo_t.h" + +#define _POSIX_C_SOURCE 199506L +#include "signal/struct_sigaction.h" + +static int sigaction(int, const struct sigaction * restrict, struct sigaction * restrict); + +#include "signal/sigaction.c" + +#define SA_RESTART 0x10000000 +#define SA_RESTORER 0x04000000 + +#define O_RDWR 02 +#define PROT_NONE 0x0 +#define PROT_READ 0x1 +#define PROT_WRITE 0x2 +#define MAP_PRIVATE 0x02 +#define MAP_FAILED (void*)(-1) +#define MAP_ANONYMOUS (0x20) +#define psiginfo(x, y) fprintf(stderr, "%s (%p)\n", (char*)(y), (void*)(x)) + +#define sigemptyset(x) memset(x, 0, sizeof(*x)) + +#endif + +#include "_jkmalloc.h" + +#if defined __OpenBSD__ || defined __FreeBSD__ || defined __APPLE__ +#define psiginfo(x, y) ((y) ? fprintf(stderr, "%s\n", (char*)(y)) : 0) +#ifndef SA_SIGINFO +#define SA_SIGINFO (0) +#endif +#endif + +#define PTR_BITS (CHAR_BIT * sizeof(uintptr_t)) + +#define JKMALLOC_EXIT_VALUE (127 + SIGSEGV) +#define JK_FREE_LIST_SIZE (8) + +/* magic numbers derived from CRC-32 of jk_foo_block */ +#define JK_FREE_MAGIC (0x551a51dc) +#define JK_UNDER_MAGIC (0xcb2873ac) +#define JK_OVER_MAGIC (0x18a12c17) +#define JK_RONLY_MAGIC (0xdeadb00d) + +#define jk_pages(bytes) (((bytes + __jk_pagesize - 1) / __jk_pagesize) + 2) +#define jk_pageof(addr) ((void*)((uintptr_t)addr - ((uintptr_t)addr % __jk_pagesize))) +#define jk_bucketof(addr) ((void*)((uintptr_t)jk_pageof(addr) - __jk_pagesize)) + +struct jk_bucket { + uint32_t magic; + uintptr_t start; + size_t size; + size_t align; + size_t pages; + size_t tlen; + char trace[]; +}; + +struct jk_source { + const char *file; + const char *func; + uintmax_t line; + struct jk_bucket *bucket; +}; + +static struct jk_bucket *__jk_free_list[JK_FREE_LIST_SIZE]; +static size_t __jk_free_buckets = 0; +static size_t __jk_pagesize = 0; + +static void __jk_error(const char *s, void *addr, struct jk_source *src) +{ + if (s && *s) { + fputs(s, stderr); + if (addr != NULL) { + fprintf(stderr, "%p", addr); + } + fputs("\n", stderr); + } + + if (src && src->bucket && src->bucket->trace[0] != '\0') { + fwrite(src->bucket->trace, src->bucket->tlen, 1, stderr); + fputs("\n", stderr); + } + + if (src && src->file) { + fprintf(stderr, "!!! %s() (%s:%ju)\n", src->func, src->file, src->line); + } + + _Exit(JKMALLOC_EXIT_VALUE); +} + +static void *__jk_page_alloc(size_t npages) +{ + int fd = -1; + int prot = PROT_READ | PROT_WRITE; + int flags = MAP_PRIVATE; + + #ifdef MAP_ANONYMOUS + flags |= MAP_ANONYMOUS; + #else + fd = open("/dev/zero", O_RDONLY, 0666); + #endif + + void *pages = mmap(NULL, npages * __jk_pagesize, prot, flags, fd, 0); + + #ifndef MAP_ANONYMOUS + if (fd != -1) { + close(fd); + } + #endif + + return pages; +} + +static void __jk_sigaction(int sig, siginfo_t *si, void *addr) +{ + ___signal.current = 0; + (void)sig; (void)addr; + if (si->si_addr == NULL) { + psiginfo(si, "NULL pointer dereference"); + __jk_error(NULL, NULL, NULL); + } + + struct jk_bucket *bucket = jk_pageof(si->si_addr); + if (mprotect(bucket, __jk_pagesize, PROT_READ) != 0) { + psiginfo(si, NULL); + __jk_error(NULL, NULL, NULL); + } + + switch (bucket->magic) { + case JK_UNDER_MAGIC: + if (bucket->size == 0) { + psiginfo(si, "Attempt to use 0-byte allocation"); + } else { + psiginfo(si, "Heap underflow detected"); + } + break; + + case JK_OVER_MAGIC: + if (bucket->size == 0) { + psiginfo(si, "Attempt to use 0-byte allocation"); + } else { + psiginfo(si, "Heap overflow detected"); + fprintf(stderr, "Allocation of size %zu at %p, overflow at %p (offset %zu)\n", bucket->size, (void*)bucket->start, si->si_addr, (size_t)((char*)si->si_addr - (char*)bucket->start)); + fprintf(stderr, "Buffer begins with %4s\n", (char*)bucket->start); + } + break; + + case JK_FREE_MAGIC: + psiginfo(si, "Use after free() detected"); + break; + + default: + psiginfo(si, NULL); + } + + struct jk_source src = { .bucket = bucket }; + __jk_error(NULL, NULL, &src); +} + +/* +static void jk_sigsegv(int sig) +{ + ___signal.current = 0; + fprintf(stderr, "JK SIGSEGV!\n"); + __jk_sigaction(sig, NULL, NULL); +} +*/ + +void* __jkmalloc(const char *file, const char *func, uintmax_t line, void *ptr, size_t alignment, size_t size1, size_t size2) +{ + static int sa_set = 0; + if (!sa_set) { + struct sigaction sa = { + .sa_flags = SA_SIGINFO, + .sa_sigaction = __jk_sigaction, + }; + //sigemptyset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, NULL); + //signal(SIGSEGV, jk_sigsegv); + sa_set = 1; + } + + if (__jk_pagesize == 0) { + __jk_pagesize = sysconf(_SC_PAGESIZE); + } + + struct jk_source src = { + .file = file, + .func = func, + .line = line, + }; + + /* free() */ + if (alignment == 0) { + if (ptr == NULL) { + return NULL; + } + + /* TODO: Add source line information to the following errors */ + + struct jk_bucket *b = jk_bucketof(ptr); + if (mprotect(b, __jk_pagesize, PROT_READ | PROT_WRITE) != 0) { + __jk_error("Attempt to free() non-dynamic address", ptr, &src); + } + + src.bucket = b; + + if (b->magic == JK_FREE_MAGIC) { + __jk_error("Double free() detected", ptr, &src); + } + + if (b->magic != JK_UNDER_MAGIC) { + __jk_error("Attempt to free() non-dynamic address", ptr, &src); + } + + if (b->start != (uintptr_t)ptr) { + __jk_error("Attempt to free() incorrect address", ptr, &src); + } + + char *base = (char*)b; + mprotect(base, __jk_pagesize * b->pages, PROT_READ | PROT_WRITE); + + if (file) { + size_t len = b->tlen; + b->tlen += snprintf(b->trace + len, __jk_pagesize - sizeof(*b) - len, + "%s--- %s() (%s:%ju)", len ? "\n" : "", func, file, line); + } + + b->magic = JK_FREE_MAGIC; + + for (size_t i = 1; i < b->pages; i++) { + memmove(base + i * __jk_pagesize, b, __jk_pagesize); + } + + size_t fb = __jk_free_buckets % JK_FREE_LIST_SIZE; + if (__jk_free_buckets > JK_FREE_LIST_SIZE) { + mprotect(__jk_free_list[fb], __jk_pagesize, PROT_READ); + munmap(__jk_free_list[fb], __jk_pagesize * __jk_free_list[fb]->pages); + } + __jk_free_list[fb] = b; + __jk_free_buckets++; + mprotect(b, __jk_pagesize * b->pages, PROT_NONE); + return NULL; + } + + /* realloc() */ + if (ptr) { + + /* TODO: Add source line information to the following errors */ + + struct jk_bucket *b = jk_bucketof(ptr); + if (mprotect(b, __jk_pagesize, PROT_READ | PROT_WRITE) != 0) { + __jk_error("Attempt to realloc() non-dynamic address", ptr, &src); + } + + src.bucket = b; + + if (b->magic == JK_FREE_MAGIC) { + __jk_error("Attempt to realloc() after free()", ptr, &src); + } + + if (b->magic != JK_UNDER_MAGIC) { + __jk_error("Attempt to realloc() non-dynamic address", ptr, &src); + } + + if (b->start != (uintptr_t)ptr) { + __jk_error("Attempt to reallocate() incorrect address", ptr, &src); + } + + void *newptr = __jkmalloc(NULL, NULL, 0, NULL, alignment, size1, size2); + if (newptr != NULL) { + memmove(newptr, ptr, b->size); + free(ptr); + } + return newptr; + } + + size_t size = size1; + + /* calloc() */ + if (size2) { + size = size1 * size2; + if (size < size1 || size < size2) { + /* overflow */ + errno = ENOMEM; + return NULL; + } + } + + size_t pages = jk_pages(size); + + struct jk_bucket *under = __jk_page_alloc(pages); + if (under == MAP_FAILED) { + errno = ENOMEM; + return NULL; + } + + under->magic = JK_UNDER_MAGIC; + under->size = size; + under->align = alignment; + under->pages = pages; + under->start = (uintptr_t)under + __jk_pagesize; + if (size % __jk_pagesize != 0) { + under->start += __jk_pagesize - size % __jk_pagesize; + if (under->start % under->align != 0) { + under->start -= under->start % under->align; + } + } + + struct jk_bucket *over = (void*)((char*)under + __jk_pagesize * (pages - 1)); + over->magic = JK_OVER_MAGIC; + over->start = under->start; + over->size = under->size; + + ptr = (void*)under->start; + + if (file) { + under->tlen = snprintf(under->trace, __jk_pagesize - sizeof(*under), "+++ %s() (%s:%ju)", func, file, line); + memmove(over->trace, under->trace, under->tlen + 1); + over->tlen = under->tlen; + } else { + under->trace[0] = '\0'; + over->trace[0] = '\0'; + } + + /* calloc() */ + if (size2) { + char *p = ptr; + for (size_t i = 0; i < size; i++) { + p[i] = '\0'; + } + } + + mprotect(under, __jk_pagesize, PROT_NONE); + mprotect(over, __jk_pagesize, PROT_NONE); + return ptr; +} + +/* +int (jk_memalign)(void **ptr, size_t a, size_t n) +{ + if (ptr == NULL) { + return EINVAL; + } + + if (((*ptr) = __jkmalloc(NULL, NULL, 0, NULL, a, n, 0)) == NULL) { + return errno; + } + + return 0; +} +*/ diff --git a/src/stdlib/_jkmalloc.h b/src/stdlib/_jkmalloc.h new file mode 100644 index 00000000..8786acea --- /dev/null +++ b/src/stdlib/_jkmalloc.h @@ -0,0 +1,6 @@ +#ifndef ___JKMALLOC_H__ +#define ___JKMALLOC_H__ + +void* __jkmalloc(const char *file, const char *func, uintmax_t line, void *ptr, size_t alignment, size_t size1 , size_t size2); + +#endif diff --git a/src/stdlib/aligned_alloc.c b/src/stdlib/aligned_alloc.c index 983cb7de..f699014b 100644 --- a/src/stdlib/aligned_alloc.c +++ b/src/stdlib/aligned_alloc.c @@ -1,12 +1,11 @@ #include <stdlib.h> #include "_stdlib.h" +#include "_jkmalloc.h" void *aligned_alloc(size_t alignment, size_t size) { SIGNAL_SAFE(0); - /* all allocations are page aligned */ - (void)alignment; - return malloc(size); + return __jkmalloc(NULL, NULL, 0, NULL, alignment, size, 0); } /* diff --git a/src/stdlib/calloc.c b/src/stdlib/calloc.c index e5b5f38b..b5203a57 100644 --- a/src/stdlib/calloc.c +++ b/src/stdlib/calloc.c @@ -1,30 +1,15 @@ #include <stdlib.h> #include <string.h> #include "_stdlib.h" +#include "_jkmalloc.h" /** allocate and initialize memory **/ void * calloc(size_t nmemb, size_t size) { - void *p = NULL; - size_t total = nmemb * size; - SIGNAL_SAFE(0); - if (total < nmemb || total < size) { - return NULL; - } - - if (nmemb == 0 || size == 0) { - return NULL; - } - - p = malloc(total); - if (p != NULL) { - memset(p, 0, size * nmemb); - } - - return p; + return __jkmalloc(NULL, NULL, 0, NULL, 1, nmemb, size); } /*** diff --git a/src/stdlib/free.c b/src/stdlib/free.c index e0a1270a..47c04dd0 100644 --- a/src/stdlib/free.c +++ b/src/stdlib/free.c @@ -1,5 +1,6 @@ #include <stdlib.h> #include "_stdlib.h" +#include "_jkmalloc.h" /** deallocate memory **/ @@ -7,11 +8,9 @@ void free(void * ptr) { SIGNAL_SAFE(0); - if (ptr == NULL) { - return; + if (ptr) { + __jkmalloc(NULL, NULL, 0, ptr, 0, 0, 0); } - - realloc(ptr, 0); } /*** diff --git a/src/stdlib/malloc.c b/src/stdlib/malloc.c index 733d73b3..d372fd6b 100644 --- a/src/stdlib/malloc.c +++ b/src/stdlib/malloc.c @@ -1,16 +1,13 @@ #include <stdlib.h> #include "_stdlib.h" +#include "_jkmalloc.h" /** allocate memory **/ void * malloc(size_t size) { SIGNAL_SAFE(0); - if (size == 0) { - return NULL; - } - - return realloc(NULL, size); + return __jkmalloc(NULL, NULL, 0, NULL, 1, size, 0); } /*** diff --git a/src/stdlib/realloc.c b/src/stdlib/realloc.c index 12729f87..17696bbf 100644 --- a/src/stdlib/realloc.c +++ b/src/stdlib/realloc.c @@ -1,28 +1,6 @@ -#if ((!defined _POSIX_C_SOURCE) || (_POSIX_C_SOURCE < 199309L)) -#undef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 199309L /* force mmap() constants */ -#define POSIX_FORCED -#endif - #include <stdlib.h> #include "_stdlib.h" -#if 0 -#include <sys/types.h> -#include <fcntl.h> -#include <sys/mman.h> -#endif - -#ifdef POSIX_FORCED -#include "_syscall.h" -#define mmap(_a, _l, _p, _fl, _fd, _o) __scall6(mmap, _a, _l, _p, _fl, _fd, _o) -#define open(_p, _a, _m) __scall3(open, _p, _a, _m) -#endif - -#define O_RDWR 02 -#define PROT_READ 0x1 -#define PROT_WRITE 0x2 -#define MAP_PRIVATE 0x02 -#define MAP_FAILED (void*)(-1) +#include "_jkmalloc.h" /** change the amount of memory allocated **/ @@ -30,27 +8,7 @@ void * realloc(void * ptr, size_t size) { SIGNAL_SAFE(0); - /* FIXME: forward dependency on POSIX.1b-1993, non-std /dev/zero */ - static int backing = -1; - - if (backing == -1) { - backing = open("/dev/zero", O_RDWR /* | O_CLOEXEC */, 0); - } - - if (ptr == NULL) { - /* malloc() */ - ptr = (void*)(long)mmap(NULL, size, PROT_READ | PROT_WRITE, - MAP_PRIVATE, backing, 0); - if (ptr == MAP_FAILED) { - return NULL; - } - } else if (size == 0) { - /* free() */ - } - - /* TODO: reallocate */ - - return ptr; + return __jkmalloc(NULL, NULL, 0, ptr, 1, size, 0); } /*** diff --git a/src/string/strerror.c b/src/string/strerror.c index 69984886..5f83b2c4 100644 --- a/src/string/strerror.c +++ b/src/string/strerror.c @@ -2,17 +2,22 @@ #include <stdio.h> #include <string.h> #include "_safety.h" - -# define __LONGEST_STRERR 64 /* FIXME */ +#include "_readonly.h" /** convert error number to string **/ char * strerror(int errnum) { - static char errstr[__LONGEST_STRERR+1]; + static char *errstr = NULL; SIGNAL_SAFE(0); + if (errstr == NULL) { + errstr = __readonly(RO_ALLOC, "strerror"); + } + + __readonly(RO_UNLOCK, errstr); + switch (errnum) { #include "_strerror.h" default: @@ -20,6 +25,8 @@ char * strerror(int errnum) break; } + __readonly(RO_LOCK, errstr); + /* RETURN_ALWAYS(a pointer to the message string); */ diff --git a/src/tgmath/acos.h b/src/tgmath/acos.h new file mode 100644 index 00000000..c7697ea2 --- /dev/null +++ b/src/tgmath/acos.h @@ -0,0 +1,19 @@ +#define acos(__x) _Generic((__x), \ + long double complex: cacosl, \ + double complex: cacos, \ + float complex: cacosf, \ + long double: $sl, \ + double: acos, \ + unsigned long long: acos, \ + long long: acos, \ + unsigned long: acos, \ + long: acos, \ + unsigned int: acos, \ + int: acos, \ + unsigned short: acos, \ + short: acos, \ + unsigned char: acos, \ + signed char: acos, \ + char: acos, \ + float: acos \ + )(__x)\n |