From 8c1ab65c0f548d20b7f177bdb736daaf603340e1 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 15:54:38 +0200 Subject: Adding upstream version 0.0~git20221206.8b7148f. Signed-off-by: Daniel Baumann --- libc-top-half/musl/src/exit/_Exit.c | 8 +++ libc-top-half/musl/src/exit/abort.c | 30 +++++++++ libc-top-half/musl/src/exit/abort_lock.c | 3 + libc-top-half/musl/src/exit/arm/__aeabi_atexit.c | 6 ++ libc-top-half/musl/src/exit/assert.c | 8 +++ libc-top-half/musl/src/exit/at_quick_exit.c | 35 ++++++++++ libc-top-half/musl/src/exit/atexit.c | 82 ++++++++++++++++++++++++ libc-top-half/musl/src/exit/exit.c | 52 +++++++++++++++ libc-top-half/musl/src/exit/quick_exit.c | 11 ++++ 9 files changed, 235 insertions(+) create mode 100644 libc-top-half/musl/src/exit/_Exit.c create mode 100644 libc-top-half/musl/src/exit/abort.c create mode 100644 libc-top-half/musl/src/exit/abort_lock.c create mode 100644 libc-top-half/musl/src/exit/arm/__aeabi_atexit.c create mode 100644 libc-top-half/musl/src/exit/assert.c create mode 100644 libc-top-half/musl/src/exit/at_quick_exit.c create mode 100644 libc-top-half/musl/src/exit/atexit.c create mode 100644 libc-top-half/musl/src/exit/exit.c create mode 100644 libc-top-half/musl/src/exit/quick_exit.c (limited to 'libc-top-half/musl/src/exit') diff --git a/libc-top-half/musl/src/exit/_Exit.c b/libc-top-half/musl/src/exit/_Exit.c new file mode 100644 index 0000000..7a6115c --- /dev/null +++ b/libc-top-half/musl/src/exit/_Exit.c @@ -0,0 +1,8 @@ +#include +#include "syscall.h" + +_Noreturn void _Exit(int ec) +{ + __syscall(SYS_exit_group, ec); + for (;;) __syscall(SYS_exit, ec); +} diff --git a/libc-top-half/musl/src/exit/abort.c b/libc-top-half/musl/src/exit/abort.c new file mode 100644 index 0000000..f21f458 --- /dev/null +++ b/libc-top-half/musl/src/exit/abort.c @@ -0,0 +1,30 @@ +#include +#include +#include "syscall.h" +#include "pthread_impl.h" +#include "atomic.h" +#include "lock.h" +#include "ksigaction.h" + +_Noreturn void abort(void) +{ + raise(SIGABRT); + + /* If there was a SIGABRT handler installed and it returned, or if + * SIGABRT was blocked or ignored, take an AS-safe lock to prevent + * sigaction from installing a new SIGABRT handler, uninstall any + * handler that may be present, and re-raise the signal to generate + * the default action of abnormal termination. */ + __block_all_sigs(0); + LOCK(__abort_lock); + __syscall(SYS_rt_sigaction, SIGABRT, + &(struct k_sigaction){.handler = SIG_DFL}, 0, _NSIG/8); + __syscall(SYS_tkill, __pthread_self()->tid, SIGABRT); + __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, + &(long[_NSIG/(8*sizeof(long))]){1UL<<(SIGABRT-1)}, 0, _NSIG/8); + + /* Beyond this point should be unreachable. */ + a_crash(); + raise(SIGKILL); + _Exit(127); +} diff --git a/libc-top-half/musl/src/exit/abort_lock.c b/libc-top-half/musl/src/exit/abort_lock.c new file mode 100644 index 0000000..3af72c7 --- /dev/null +++ b/libc-top-half/musl/src/exit/abort_lock.c @@ -0,0 +1,3 @@ +#include "pthread_impl.h" + +volatile int __abort_lock[1]; diff --git a/libc-top-half/musl/src/exit/arm/__aeabi_atexit.c b/libc-top-half/musl/src/exit/arm/__aeabi_atexit.c new file mode 100644 index 0000000..ce16101 --- /dev/null +++ b/libc-top-half/musl/src/exit/arm/__aeabi_atexit.c @@ -0,0 +1,6 @@ +int __cxa_atexit(void (*func)(void *), void *arg, void *dso); + +int __aeabi_atexit (void *obj, void (*func) (void *), void *d) +{ + return __cxa_atexit (func, obj, d); +} diff --git a/libc-top-half/musl/src/exit/assert.c b/libc-top-half/musl/src/exit/assert.c new file mode 100644 index 0000000..94edd82 --- /dev/null +++ b/libc-top-half/musl/src/exit/assert.c @@ -0,0 +1,8 @@ +#include +#include + +_Noreturn void __assert_fail(const char *expr, const char *file, int line, const char *func) +{ + fprintf(stderr, "Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line); + abort(); +} diff --git a/libc-top-half/musl/src/exit/at_quick_exit.c b/libc-top-half/musl/src/exit/at_quick_exit.c new file mode 100644 index 0000000..429d0b0 --- /dev/null +++ b/libc-top-half/musl/src/exit/at_quick_exit.c @@ -0,0 +1,35 @@ +#include +#include "libc.h" +#include "lock.h" +#include "fork_impl.h" + +#define COUNT 32 + +static void (*funcs[COUNT])(void); +static int count; +#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) +static volatile int lock[1]; +volatile int *const __at_quick_exit_lockptr = lock; +#endif + +void __funcs_on_quick_exit() +{ + void (*func)(void); + LOCK(lock); + while (count > 0) { + func = funcs[--count]; + UNLOCK(lock); + func(); + LOCK(lock); + } +} + +int at_quick_exit(void (*func)(void)) +{ + int r = 0; + LOCK(lock); + if (count == 32) r = -1; + else funcs[count++] = func; + UNLOCK(lock); + return r; +} diff --git a/libc-top-half/musl/src/exit/atexit.c b/libc-top-half/musl/src/exit/atexit.c new file mode 100644 index 0000000..155292d --- /dev/null +++ b/libc-top-half/musl/src/exit/atexit.c @@ -0,0 +1,82 @@ +#include +#include +#include "libc.h" +#include "lock.h" +#include "fork_impl.h" + +#define malloc __libc_malloc +#define calloc __libc_calloc +#define realloc undef +#define free undef + +/* Ensure that at least 32 atexit handlers can be registered without malloc */ +#define COUNT 32 + +static struct fl +{ + struct fl *next; + void (*f[COUNT])(void *); + void *a[COUNT]; +} builtin, *head; + +static int slot; + +#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) +static volatile int lock[1]; +volatile int *const __atexit_lockptr = lock; +#endif + +void __funcs_on_exit() +{ + void (*func)(void *), *arg; + LOCK(lock); + for (; head; head=head->next, slot=COUNT) while(slot-->0) { + func = head->f[slot]; + arg = head->a[slot]; + UNLOCK(lock); + func(arg); + LOCK(lock); + } +} + +void __cxa_finalize(void *dso) +{ +} + +int __cxa_atexit(void (*func)(void *), void *arg, void *dso) +{ + LOCK(lock); + + /* Defer initialization of head so it can be in BSS */ + if (!head) head = &builtin; + + /* If the current function list is full, add a new one */ + if (slot==COUNT) { + struct fl *new_fl = calloc(sizeof(struct fl), 1); + if (!new_fl) { + UNLOCK(lock); + return -1; + } + new_fl->next = head; + head = new_fl; + slot = 0; + } + + /* Append function to the list. */ + head->f[slot] = func; + head->a[slot] = arg; + slot++; + + UNLOCK(lock); + return 0; +} + +static void call(void *p) +{ + ((void (*)(void))(uintptr_t)p)(); +} + +int atexit(void (*func)(void)) +{ + return __cxa_atexit(call, (void *)(uintptr_t)func, 0); +} diff --git a/libc-top-half/musl/src/exit/exit.c b/libc-top-half/musl/src/exit/exit.c new file mode 100644 index 0000000..1536d7d --- /dev/null +++ b/libc-top-half/musl/src/exit/exit.c @@ -0,0 +1,52 @@ +#include +#include +#include "libc.h" + +static void dummy() +{ +} + +/* atexit.c and __stdio_exit.c override these. the latter is linked + * as a consequence of linking either __toread.c or __towrite.c. */ +weak_alias(dummy, __funcs_on_exit); +weak_alias(dummy, __stdio_exit); +#ifdef __wasilibc_unmodified_upstream // fini +weak_alias(dummy, _fini); + +extern weak hidden void (*const __fini_array_start)(void), (*const __fini_array_end)(void); + +static void libc_exit_fini(void) +{ + uintptr_t a = (uintptr_t)&__fini_array_end; + for (; a>(uintptr_t)&__fini_array_start; a-=sizeof(void(*)())) + (*(void (**)())(a-sizeof(void(*)())))(); + _fini(); +} + +weak_alias(libc_exit_fini, __libc_exit_fini); +#endif + +#ifdef __wasilibc_unmodified_upstream // WASI libc uses a custom exit +_Noreturn void exit(int code) +{ + __funcs_on_exit(); + __libc_exit_fini(); + __stdio_exit(); + _Exit(code); +} +#else +// Split out the cleanup functions so that we can call them without calling +// _Exit if we don't need to. This allows _start to just return if main +// returns 0. +void __wasm_call_dtors(void) +{ + __funcs_on_exit(); + __stdio_exit(); +} + +_Noreturn void exit(int code) +{ + __wasm_call_dtors(); + _Exit(code); +} +#endif diff --git a/libc-top-half/musl/src/exit/quick_exit.c b/libc-top-half/musl/src/exit/quick_exit.c new file mode 100644 index 0000000..ada9134 --- /dev/null +++ b/libc-top-half/musl/src/exit/quick_exit.c @@ -0,0 +1,11 @@ +#include +#include "libc.h" + +static void dummy() { } +weak_alias(dummy, __funcs_on_quick_exit); + +_Noreturn void quick_exit(int code) +{ + __funcs_on_quick_exit(); + _Exit(code); +} -- cgit v1.2.3