diff options
Diffstat (limited to 'libc/stdlib')
-rw-r--r-- | libc/stdlib/abort.c | 129 | ||||
-rw-r--r-- | libc/stdlib/atexit.c | 3 | ||||
-rw-r--r-- | libc/stdlib/malloc-simple/alloc.c | 189 | ||||
-rw-r--r-- | libc/stdlib/malloc-standard/malloc.c | 4 |
4 files changed, 165 insertions, 160 deletions
diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c index e34c86778..77c2cdc69 100644 --- a/libc/stdlib/abort.c +++ b/libc/stdlib/abort.c @@ -30,99 +30,120 @@ Cambridge, MA 02139, USA. */ /* Our last ditch effort to commit suicide */ -#if defined(__i386__) +#if defined(__alpha__) +#define ABORT_INSTRUCTION asm ("call_pal 0") +#elif defined(__hppa__) +#define ABORT_INSTRUCTION asm ("iitlbp %r0,(%r0)") +#elif defined(__i386__) #define ABORT_INSTRUCTION asm ("hlt") #elif defined(__ia64__) #define ABORT_INSTRUCTION asm ("break 0") +#elif defined(__m68k__) +#define ABORT_INSTRUCTION asm ("illegal") #elif defined(__mc68000__) #define ABORT_INSTRUCTION asm (".long 0xffffffff") #elif defined(__mips__) #define ABORT_INSTRUCTION asm ("break 255") +#elif defined(__powerpc__) +#define ABORT_INSTRUCTION asm (".long 0") #elif defined(__s390__) #define ABORT_INSTRUCTION asm (".word 0") #elif defined(__sparc__) #define ABORT_INSTRUCTION asm ("unimp 0xf00") -#elif defined(__x86_64__) -#define ABORT_INSTRUCTION asm ("hlt") -#elif defined(__hppa__) -#define ABORT_INSTRUCTION asm ("iitlbp %r0,(%r0)") -#elif defined(__powerpc__) -#define ABORT_INSTRUCTION asm (".long 0") #elif defined(__SH5__) #define ABORT_INSTRUCTION asm ("movi 0x10, r9; shori 0xff, r9; trapa r9") #elif defined(__sh2__) #define ABORT_INSTRUCTION asm ("trapa #32") #elif defined(__sh__) #define ABORT_INSTRUCTION asm ("trapa #0xff") +#elif defined(__x86_64__) +#define ABORT_INSTRUCTION asm ("hlt") #else #define ABORT_INSTRUCTION +#warning no abort instruction define for your arch #endif +#ifdef __UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT__ +extern void weak_function _stdio_term(void); +#endif extern void _exit __P((int __status)) __attribute__ ((__noreturn__)); static int been_there_done_that = 0; -/* Be prepared in case multiple threads try to abort(). */ +/* Be prepared in case multiple threads try to abort() */ #ifdef __UCLIBC_HAS_THREADS__ -#include <pthread.h> +# include <pthread.h> static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; # define LOCK __pthread_mutex_lock(&mylock) -# define UNLOCK __pthread_mutex_unlock(&mylock); +# define UNLOCK __pthread_mutex_unlock(&mylock) #else # define LOCK # define UNLOCK #endif -/* Cause an abnormal program termination with core-dump. */ +/* Cause an abnormal program termination with core-dump */ void abort(void) { - sigset_t sigset; - - /* Make sure we acquire the lock before proceeding. */ - LOCK; - - /* Unmask SIGABRT to be sure we can get it */ - if (__sigemptyset(&sigset) == 0 && __sigaddset(&sigset, SIGABRT) == 0) { - sigprocmask(SIG_UNBLOCK, &sigset, (sigset_t *) NULL); - } - - while (1) { - /* Try to suicide with a SIGABRT. */ - if (been_there_done_that == 0) { - been_there_done_that++; - UNLOCK; - raise(SIGABRT); - LOCK; - } + sigset_t sigset; - /* Still here? Try to remove any signal handlers. */ - if (been_there_done_that == 1) { - struct sigaction act; + /* Make sure we acquire the lock before proceeding */ + LOCK; - been_there_done_that++; - memset (&act, '\0', sizeof (struct sigaction)); - act.sa_handler = SIG_DFL; - __sigfillset (&act.sa_mask); - act.sa_flags = 0; - sigaction (SIGABRT, &act, NULL); + /* Unmask SIGABRT to be sure we can get it */ + if (__sigemptyset(&sigset) == 0 && __sigaddset(&sigset, SIGABRT) == 0) { + sigprocmask(SIG_UNBLOCK, &sigset, (sigset_t *) NULL); } - /* Still here? Try to suicide with an illegal instruction */ - if (been_there_done_that == 2) { - been_there_done_that++; - ABORT_INSTRUCTION; - } + while (1) { + /* Try to suicide with a SIGABRT */ + if (been_there_done_that == 0) { + been_there_done_that++; + +#ifdef __UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT__ + /* If we are using stdio, try to shut it down. At the very least, + * this will attemt to commit all buffered writes. It may also + * unboffer all writable files, or close them outright. + * Check the stdio routines for details. */ + if (_stdio_term) { + _stdio_term(); + } +#endif - /* Still here? Try to at least exit */ - if (been_there_done_that == 3) { - been_there_done_that++; - _exit (127); +abort_it: + UNLOCK; + raise(SIGABRT); + LOCK; + } + + /* Still here? Try to remove any signal handlers */ + if (been_there_done_that == 1) { + struct sigaction act; + + been_there_done_that++; + memset(&act, '\0', sizeof(struct sigaction)); + act.sa_handler = SIG_DFL; + __sigfillset(&act.sa_mask); + act.sa_flags = 0; + sigaction(SIGABRT, &act, NULL); + + goto abort_it; + } + + /* Still here? Try to suicide with an illegal instruction */ + if (been_there_done_that == 2) { + been_there_done_that++; + ABORT_INSTRUCTION; + } + + /* Still here? Try to at least exit */ + if (been_there_done_that == 3) { + been_there_done_that++; + _exit(127); + } + + /* Still here? We're screwed. Sleepy time. Good night. */ + while (1) + /* Try for ever and ever */ + ABORT_INSTRUCTION; } - - /* Still here? We're screwed. Sleepy time. Good night */ - while (1) - /* Try for ever and ever. */ - ABORT_INSTRUCTION; - } } - diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c index d5f83ee8e..280f42cb7 100644 --- a/libc/stdlib/atexit.c +++ b/libc/stdlib/atexit.c @@ -239,8 +239,7 @@ void exit(int rv) if (__app_fini != NULL) (__app_fini)(); #endif -#ifdef _DL_DO_FINI_IN_LIBC -/* arches that has moved their ldso FINI handling should #define _DL_DO_FINI_IN_LIBC */ +#ifndef _DL_FINI_CRT_COMPAT if (__rtld_fini != NULL) (__rtld_fini)(); #endif diff --git a/libc/stdlib/malloc-simple/alloc.c b/libc/stdlib/malloc-simple/alloc.c index 68cd77665..ed14c37c4 100644 --- a/libc/stdlib/malloc-simple/alloc.c +++ b/libc/stdlib/malloc-simple/alloc.c @@ -1,6 +1,6 @@ /* alloc.c * - * Written by Erik Andersen <andersee@debian.org> + * Written by Erik Andersen <andersee@codepoet.org> * LGPLv2 * * Parts of the memalign code were stolen from malloc-930716. @@ -20,31 +20,29 @@ #ifdef L_malloc void *malloc(size_t size) { - void *result; + void *result; - if (unlikely(size == 0)) { + if (unlikely(size == 0)) { #if defined(__MALLOC_GLIBC_COMPAT__) - size++; + size++; #else - /* Some programs will call malloc (0). Lets be strict and return NULL */ - return 0; + /* Some programs will call malloc (0). Lets be strict and return NULL */ + return 0; #endif - } + } #ifdef __ARCH_HAS_MMU__ - result = mmap((void *) 0, size + sizeof(size_t), PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); - if (result == MAP_FAILED) - return 0; - * (size_t *) result = size; - return(result + sizeof(size_t)); +# define MMAP_FLAGS MAP_PRIVATE | MAP_ANONYMOUS #else - result = mmap((void *) 0, size, PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_ANONYMOUS, 0, 0); - if (result == MAP_FAILED) - return 0; - return(result); +# define MMAP_FLAGS MAP_SHARED | MAP_ANONYMOUS #endif + + result = mmap((void *) 0, size + sizeof(size_t), PROT_READ | PROT_WRITE, + MMAP_FLAGS, 0, 0); + if (result == MAP_FAILED) + return 0; + * (size_t *) result = size; + return(result + sizeof(size_t)); } #endif @@ -76,27 +74,21 @@ void * calloc(size_t nmemb, size_t lsize) #ifdef L_realloc void *realloc(void *ptr, size_t size) { - void *newptr = NULL; - - if (!ptr) - return malloc(size); - if (!size) { - free(ptr); - return malloc(0); - } - - newptr = malloc(size); - if (newptr) { - memcpy(newptr, ptr, -#ifdef __ARCH_HAS_MMU__ - *((size_t *) (ptr - sizeof(size_t))) -#else - size -#endif - ); - free(ptr); - } - return newptr; + void *newptr = NULL; + + if (!ptr) + return malloc(size); + if (!size) { + free(ptr); + return malloc(0); + } + + newptr = malloc(size); + if (newptr) { + memcpy(newptr, ptr, *((size_t *) (ptr - sizeof(size_t)))); + free(ptr); + } + return newptr; } #endif @@ -104,19 +96,14 @@ void *realloc(void *ptr, size_t size) extern int weak_function __libc_free_aligned(void *ptr); void free(void *ptr) { - if (ptr == NULL) - return; - if (unlikely(__libc_free_aligned!=NULL)) { - if (__libc_free_aligned(ptr)) { - return; + if (unlikely(ptr == NULL)) + return; + if (unlikely(__libc_free_aligned != NULL)) { + if (__libc_free_aligned(ptr)) + return; } - } -#ifdef __ARCH_HAS_MMU__ - ptr -= sizeof(size_t); - munmap(ptr, * (size_t *) ptr + sizeof(size_t)); -#else - munmap(ptr, 0); -#endif + ptr -= sizeof(size_t); + munmap(ptr, * (size_t *) ptr + sizeof(size_t)); } #endif @@ -134,73 +121,67 @@ pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; /* List of blocks allocated with memalign or valloc */ struct alignlist { - struct alignlist *next; - __ptr_t aligned; /* The address that memaligned returned. */ - __ptr_t exact; /* The address that malloc returned. */ + struct alignlist *next; + __ptr_t aligned; /* The address that memaligned returned. */ + __ptr_t exact; /* The address that malloc returned. */ }; struct alignlist *_aligned_blocks; /* Return memory to the heap. */ int __libc_free_aligned(void *ptr) { - struct alignlist *l; + struct alignlist *l; - if (ptr == NULL) - return 0; + if (ptr == NULL) + return 0; - LOCK; - for (l = _aligned_blocks; l != NULL; l = l->next) { - if (l->aligned == ptr) { - /* Mark the block as free */ - l->aligned = NULL; - ptr = l->exact; -#ifdef __ARCH_HAS_MMU__ - ptr -= sizeof(size_t); - munmap(ptr, * (size_t *) ptr + sizeof(size_t)); -#else - munmap(ptr, 0); -#endif - return 1; + LOCK; + for (l = _aligned_blocks; l != NULL; l = l->next) { + if (l->aligned == ptr) { + /* Mark the block as free */ + l->aligned = NULL; + ptr = l->exact; + ptr -= sizeof(size_t); + munmap(ptr, * (size_t *) ptr + sizeof(size_t)); + return 1; + } } - } - UNLOCK; - return 0; + UNLOCK; + return 0; } void * memalign (size_t alignment, size_t size) { - void * result; - unsigned long int adj; - - result = malloc (size + alignment - 1); - if (result == NULL) - return NULL; - adj = (unsigned long int) ((unsigned long int) ((char *) result - - (char *) NULL)) % alignment; - if (adj != 0) - { - struct alignlist *l; - LOCK; - for (l = _aligned_blocks; l != NULL; l = l->next) - if (l->aligned == NULL) - /* This slot is free. Use it. */ - break; - if (l == NULL) - { - l = (struct alignlist *) malloc (sizeof (struct alignlist)); - if (l == NULL) { - free(result); - UNLOCK; + void * result; + unsigned long int adj; + + result = malloc (size + alignment - 1); + if (result == NULL) return NULL; - } - l->next = _aligned_blocks; - _aligned_blocks = l; + + adj = (unsigned long int) ((unsigned long int) ((char *) result - + (char *) NULL)) % alignment; + if (adj != 0) { + struct alignlist *l; + LOCK; + for (l = _aligned_blocks; l != NULL; l = l->next) + if (l->aligned == NULL) + /* This slot is free. Use it. */ + break; + if (l == NULL) { + l = (struct alignlist *) malloc (sizeof (struct alignlist)); + if (l == NULL) { + free(result); + UNLOCK; + return NULL; + } + l->next = _aligned_blocks; + _aligned_blocks = l; + } + l->exact = result; + result = l->aligned = (char *) result + alignment - adj; + UNLOCK; } - l->exact = result; - result = l->aligned = (char *) result + alignment - adj; - UNLOCK; - } - return result; + return result; } #endif - diff --git a/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c index 51e02a240..7025e8335 100644 --- a/libc/stdlib/malloc-standard/malloc.c +++ b/libc/stdlib/malloc-standard/malloc.c @@ -827,6 +827,10 @@ void* malloc(size_t bytes) mchunkptr bck; /* misc temp for linking */ void * sysmem; +#if !defined(__MALLOC_GLIBC_COMPAT__) + if (!bytes) return NULL; +#endif + LOCK; av = get_malloc_state(); /* |