From 61ba39a23786a7ae9694705af1d146c00a319144 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Sat, 5 Feb 2011 04:35:27 +0100 Subject: Getting rid of newlib, starting to implement a libc. Highly experimental, highly untested. --- libc/src/exit.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 libc/src/exit.c (limited to 'libc/src/exit.c') diff --git a/libc/src/exit.c b/libc/src/exit.c new file mode 100644 index 0000000..fc2446f --- /dev/null +++ b/libc/src/exit.c @@ -0,0 +1,65 @@ +#include +#include + +extern void (*__preinit_array_start []) (void) __attribute__((weak)); +extern void (*__preinit_array_end []) (void) __attribute__((weak)); +extern void (*__init_array_start []) (void) __attribute__((weak)); +extern void (*__init_array_end []) (void) __attribute__((weak)); +extern void (*__fini_array_start []) (void) __attribute__((weak)); +extern void (*__fini_array_end []) (void) __attribute__((weak)); + +void _init(); +void _fini(); +void _exit(int return_code) __attribute__((noreturn)); + + +void __libc_init_array() { + size_t count, i; + + count = __preinit_array_end - __preinit_array_start; + for (i = 0; i < count; i++) + __preinit_array_start[i](); + + _init(); + + count = __init_array_end - __init_array_start; + for (i = 0; i < count; i++) + __init_array_start[i](); +} + +void __libc_fini_array() { + size_t count, i; + + count = __preinit_array_end - __preinit_array_start; + for (i = count - 1; i >= 0; i--) + __fini_array_start[i](); + + _fini(); +} + +#define MAX_ATEXIT 32 + +static volatile uint8_t atexit_count = 0; +static volatile atexit_func_t atexit_funcs[MAX_ATEXIT]; + +int atexit(atexit_func_t func) { + uint8_t pos = __sync_fetch_and_add(&atexit_count, 1); + + if (pos >= MAX_ATEXIT) { + atexit_count = 32; + return -1; + } + + atexit_funcs[pos] = func; + return 0; +} + +void exit(int return_code) { + uint8_t i; + + for (i = 0; i < atexit_count; i++) { + atexit_funcs[i](); + } + + _exit(return_code); +} -- cgit v1.2.3