mirror of
https://git.planet-casio.com/Vhex-Kernel-Core/fxlibc.git
synced 2025-05-28 22:45:15 +02:00
dso, stdlib: __cxa_atexit(), __dso_handle, atexit() (TEST)
This commit is contained in:
parent
95e33092ec
commit
7c4de3e295
6 changed files with 81 additions and 2 deletions
|
@ -70,6 +70,8 @@ set(SOURCES
|
||||||
3rdparty/grisu2b_59_56/grisu2b_59_56.c
|
3rdparty/grisu2b_59_56/grisu2b_59_56.c
|
||||||
3rdparty/tinymt32/rand.c
|
3rdparty/tinymt32/rand.c
|
||||||
3rdparty/tinymt32/tinymt32.c
|
3rdparty/tinymt32/tinymt32.c
|
||||||
|
# C++ API details
|
||||||
|
src/dso.c
|
||||||
# assert
|
# assert
|
||||||
src/assert/assert.c
|
src/assert/assert.c
|
||||||
# ctype
|
# ctype
|
||||||
|
@ -157,6 +159,7 @@ set(SOURCES
|
||||||
# stdlib
|
# stdlib
|
||||||
src/stdlib/abort.c
|
src/stdlib/abort.c
|
||||||
src/stdlib/abs.c
|
src/stdlib/abs.c
|
||||||
|
src/stdlib/atexit.c
|
||||||
src/stdlib/atof.c
|
src/stdlib/atof.c
|
||||||
src/stdlib/atoi.c
|
src/stdlib/atoi.c
|
||||||
src/stdlib/atol.c
|
src/stdlib/atol.c
|
||||||
|
|
4
STATUS
4
STATUS
|
@ -162,7 +162,7 @@ TEST: Function/symbol/macro needs to be tested
|
||||||
7.20.3.3 malloc - (gint)
|
7.20.3.3 malloc - (gint)
|
||||||
7.20.3.4 realloc - (gint)
|
7.20.3.4 realloc - (gint)
|
||||||
7.20.4.1 abort - (stream flushing/closing/etc?)
|
7.20.4.1 abort - (stream flushing/closing/etc?)
|
||||||
7.20.4.2 atexit TODO
|
7.20.4.2 atexit TEST
|
||||||
7.20.4.3 exit - (stream flushing/closing/etc?)
|
7.20.4.3 exit - (stream flushing/closing/etc?)
|
||||||
7.20.4.4 _Exit - (gint)
|
7.20.4.4 _Exit - (gint)
|
||||||
7.20.4.5 getenv TODO
|
7.20.4.5 getenv TODO
|
||||||
|
@ -173,6 +173,8 @@ TEST: Function/symbol/macro needs to be tested
|
||||||
7.20.6.2 div, ldiv, lldiv -
|
7.20.6.2 div, ldiv, lldiv -
|
||||||
7.20.7 Multibyte/wide char conv TODO
|
7.20.7 Multibyte/wide char conv TODO
|
||||||
7.20.8 Multibyte/wide string conv TODO
|
7.20.8 Multibyte/wide string conv TODO
|
||||||
|
(EXT) __cxa_atexit TEST
|
||||||
|
(EXT) __cxa_finalize TEST
|
||||||
|
|
||||||
7.21 <string.h>
|
7.21 <string.h>
|
||||||
7.21.2.1 memcpy -
|
7.21.2.1 memcpy -
|
||||||
|
|
|
@ -38,6 +38,7 @@ extern void free(void *__ptr);
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn))
|
||||||
extern void abort(void);
|
extern void abort(void);
|
||||||
|
|
||||||
|
/* Register a function to be called at program exit. */
|
||||||
extern int atexit(void (*__func)(void));
|
extern int atexit(void (*__func)(void));
|
||||||
|
|
||||||
/* Exit; calls handlers, flushes and closes streams and temporary files. */
|
/* Exit; calls handlers, flushes and closes streams and temporary files. */
|
||||||
|
|
62
src/dso.c
Normal file
62
src/dso.c
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* We don't support shared object loading, so provide a single handle */
|
||||||
|
__attribute__((visibility("hidden")))
|
||||||
|
void *__dso_handle = (void *)&__dso_handle;
|
||||||
|
|
||||||
|
/* Number of atexit() calls supported, must be at least 32 (7.20.4.2§3).*/
|
||||||
|
#define ATEXIT_MAX 32
|
||||||
|
|
||||||
|
struct dtor {
|
||||||
|
void (*f)(void *);
|
||||||
|
void *p;
|
||||||
|
void *d;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct dtor _dtors[ATEXIT_MAX];
|
||||||
|
static int _dtor_count = 0;
|
||||||
|
|
||||||
|
int __cxa_atexit(void (*f)(void *), void *p, void *d)
|
||||||
|
{
|
||||||
|
if(_dtor_count >= ATEXIT_MAX)
|
||||||
|
return 1;
|
||||||
|
_dtors[_dtor_count++] = (struct dtor){ f, p, d };
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We walk the destructor list in reverse order. Destructors may themselves
|
||||||
|
call __cxa_atexit(), causing new destructors to be added. When that
|
||||||
|
happens, we must call the new ones first before resuming (7.20.4.3§3). We
|
||||||
|
track changes in _dtor_count to detect this situation.
|
||||||
|
|
||||||
|
This function calls destructs in the interval [low..high) that match DSO
|
||||||
|
handle d, plus any other destructors registered as a consequence.
|
||||||
|
_dtor_count may increase. */
|
||||||
|
static void call_dtors_in_interval(void *d, int low, int high)
|
||||||
|
{
|
||||||
|
int end = _dtor_count;
|
||||||
|
|
||||||
|
for(int i = high - 1; i >= low; i--) {
|
||||||
|
if(d == NULL || _dtors[i].d == d)
|
||||||
|
_dtors[i].f(_dtors[i].p);
|
||||||
|
|
||||||
|
if(_dtor_count > end) {
|
||||||
|
call_dtors_in_interval(d, end, _dtor_count);
|
||||||
|
end = _dtor_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cxa_finalize(void *d)
|
||||||
|
{
|
||||||
|
call_dtors_in_interval(d, 0, _dtor_count);
|
||||||
|
|
||||||
|
/* Re-compact the array to keep only destructors we didn't call. */
|
||||||
|
int j = 0;
|
||||||
|
for(int i = 0; i < _dtor_count; i++) {
|
||||||
|
if(d == NULL || _dtors[i].d == d)
|
||||||
|
continue;
|
||||||
|
_dtors[j++] = _dtors[i];
|
||||||
|
}
|
||||||
|
_dtor_count = j;
|
||||||
|
}
|
8
src/stdlib/atexit.c
Normal file
8
src/stdlib/atexit.c
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
extern int __cxa_atexit(void (*f)(void *), void *p, void *d);
|
||||||
|
|
||||||
|
int atexit(void (*f)(void))
|
||||||
|
{
|
||||||
|
return __cxa_atexit((void (*)(void *))f, NULL, NULL);
|
||||||
|
}
|
|
@ -1,8 +1,11 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
extern void __cxa_finalize(void *d);
|
||||||
|
|
||||||
void exit(int rc)
|
void exit(int rc)
|
||||||
{
|
{
|
||||||
/* TODO: invoke atexit callbacks */
|
__cxa_finalize(NULL);
|
||||||
|
|
||||||
/* TODO: exit: Flush all streams */
|
/* TODO: exit: Flush all streams */
|
||||||
/* TODO: exit: Close all streams */
|
/* TODO: exit: Close all streams */
|
||||||
/* TODO: exit: Remove temporary files */
|
/* TODO: exit: Remove temporary files */
|
||||||
|
|
Loading…
Add table
Reference in a new issue