1 /*
2  * Copyright (c) 2021-2022 HPMicro
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #include <stdint.h>
7 
8 #ifndef USE_LIBC_INITFINI
9 #define USE_LIBC_INITFINI 0
10 #endif
11 
12 #if USE_LIBC_INITFINI
13 
14 /*
15  * The _init() and _fini() will be called respectively when use __libc_init_array()
16  * and __libc_fnit_array() in libc.a to perform constructor and destructor handling.
17  * The dummy versions of these functions should be provided.
18  */
_init(void)19 void _init(void)
20 {
21 }
22 
_fini(void)23 void _fini(void)
24 {
25 }
26 
27 #else
28 
29 /* These magic symbols are provided by the linker.  */
30 extern void (*__preinit_array_start[])(void) __attribute__((weak));
31 extern void (*__preinit_array_end[])(void) __attribute__((weak));
32 extern void (*__init_array_start[])(void) __attribute__((weak));
33 extern void (*__init_array_end[])(void) __attribute__((weak));
34 
35 /*
36  * The __libc_init_array()/__libc_fnit_array() function is used to do global
37  * constructor/destructor and can NOT be compilied to generate the code coverage
38  * data. We have the function attribute to be 'no_profile_instrument_function'
39  * to prevent been instrumented for coverage analysis when GCOV=1 is applied.
40  */
41 /* Iterate over all the init routines.  */
42 void __libc_init_array(void) __attribute__((no_profile_instrument_function));
__libc_init_array(void)43 void __libc_init_array(void)
44 {
45     uint32_t count;
46     uint32_t i;
47 
48     count = __preinit_array_end - __preinit_array_start;
49     for (i = 0; i < count; i++) {
50         __preinit_array_start[i]();
51     }
52 
53     count = __init_array_end - __init_array_start;
54     for (i = 0; i < count; i++) {
55         __init_array_start[i]();
56     }
57 }
58 
59 extern void (*__fini_array_start[])(void) __attribute__((weak));
60 extern void (*__fini_array_end[])(void) __attribute__((weak));
61 
62 /* Run all the cleanup routines.  */
63 void __libc_fini_array(void) __attribute__((no_profile_instrument_function));
__libc_fini_array(void)64 void __libc_fini_array(void)
65 {
66     uint32_t count;
67     uint32_t i;
68 
69     count = __fini_array_end - __fini_array_start;
70     for (i = count; i > 0; i--) {
71         __fini_array_start[i - 1]();
72     }
73 }
74 
75 #endif
76