1 /*
2 Copyright (c) 2004 Paul Brook <paul@codesourcery.com>
3
4 Common routine to implement atexit-like functionality.
5
6 This is also the key function to be configured as lite exit, a size-reduced
7 implementation of exit that doesn't invoke clean-up functions such as _fini
8 or global destructors.
9
10 Default (without lite exit) call graph is like:
11 start -> atexit -> __register_exitproc
12 start -> __libc_init_array -> __cxa_atexit -> __register_exitproc
13 on_exit -> __register_exitproc
14 start -> exit -> __call_exitprocs
15
16 Here an -> means arrow tail invokes arrow head. All invocations here
17 are non-weak reference in current newlib.
18
19 Lite exit makes some of above calls as weak reference, so that size expansive
20 functions __register_exitproc and __call_exitprocs may not be linked. These
21 calls are:
22 start w-> atexit
23 cxa_atexit w-> __register_exitproc
24 exit w-> __call_exitprocs
25
26 Lite exit also makes sure that __call_exitprocs will be referenced as non-weak
27 whenever __register_exitproc is referenced as non-weak.
28
29 Thus with lite exit libs, a program not explicitly calling atexit or on_exit
30 will escape from the burden of cleaning up code. A program with atexit or on_exit
31 will work consistently to normal libs.
32
33 Lite exit is enabled with --enable-lite-exit, and is controlled with macro
34 LITE_EXIT.
35 */
36 /*
37 * Implementation of __cxa_atexit.
38 */
39
40 #include <stddef.h>
41 #include <stdlib.h>
42 #include <sys/lock.h>
43 #include "atexit.h"
44
45 /*
46 * Register a function to be performed at exit or DSO unload.
47 */
48
49 int
__cxa_atexit(void (* fn)(void *),void * arg,void * d)50 __cxa_atexit (void (*fn) (void *),
51 void *arg,
52 void *d)
53 {
54 #ifdef _LITE_EXIT
55 /* Refer to comments in __atexit.c for more details of lite exit. */
56 int __register_exitproc (int, void (*fn) (void), void *, void *)
57 __attribute__ ((weak));
58
59 if (!__register_exitproc)
60 return 0;
61 else
62 #endif
63 return __register_exitproc (__et_cxa, (void (*)(void)) fn, arg, d);
64 }
65