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)19void _init(void) 20 { 21 } 22 _fini(void)23void _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)43void __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)64void __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