xref: /nrf52832-nimble/rt-thread/components/cplusplus/crt_init.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero  * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero  *
4*10465441SEvalZero  * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero  *
6*10465441SEvalZero * Change Logs:
7*10465441SEvalZero * Date           Author       Notes
8*10465441SEvalZero * 2014-12-03     Bernard      Add copyright header.
9*10465441SEvalZero * 2014-12-29     Bernard      Add cplusplus initialization for ARMCC.
10*10465441SEvalZero * 2016-06-28     Bernard      Add _init/_fini routines for GCC.
11*10465441SEvalZero * 2016-10-02     Bernard      Add WEAK for cplusplus_system_init routine.
12*10465441SEvalZero */
13*10465441SEvalZero 
14*10465441SEvalZero #include <rtthread.h>
15*10465441SEvalZero 
16*10465441SEvalZero #ifdef __CC_ARM
17*10465441SEvalZero extern void $Super$$__cpp_initialize__aeabi_(void);
18*10465441SEvalZero /* we need to change the cpp_initialize order */
$Sub$$__cpp_initialize__aeabi_(void)19*10465441SEvalZero void $Sub$$__cpp_initialize__aeabi_(void)
20*10465441SEvalZero {
21*10465441SEvalZero     /* empty */
22*10465441SEvalZero }
23*10465441SEvalZero #elif defined(__GNUC__) && !defined(__CS_SOURCERYGXX_MAJ__)
24*10465441SEvalZero /* The _init()/_fini() routines has been defined in codesourcery g++ lite */
_init()25*10465441SEvalZero RT_WEAK void _init()
26*10465441SEvalZero {
27*10465441SEvalZero }
28*10465441SEvalZero 
_fini()29*10465441SEvalZero RT_WEAK void _fini()
30*10465441SEvalZero {
31*10465441SEvalZero }
32*10465441SEvalZero 
33*10465441SEvalZero RT_WEAK void *__dso_handle = 0;
34*10465441SEvalZero 
35*10465441SEvalZero #endif
36*10465441SEvalZero 
37*10465441SEvalZero RT_WEAK
cplusplus_system_init(void)38*10465441SEvalZero int cplusplus_system_init(void)
39*10465441SEvalZero {
40*10465441SEvalZero #if defined(__GNUC__) && !defined(__CC_ARM)
41*10465441SEvalZero     typedef void (*pfunc) ();
42*10465441SEvalZero     extern pfunc __ctors_start__[];
43*10465441SEvalZero     extern pfunc __ctors_end__[];
44*10465441SEvalZero     pfunc *p;
45*10465441SEvalZero 
46*10465441SEvalZero     for (p = __ctors_start__; p < __ctors_end__; p++)
47*10465441SEvalZero         (*p)();
48*10465441SEvalZero 
49*10465441SEvalZero #elif defined(__CC_ARM)
50*10465441SEvalZero     /* If there is no SHT$$INIT_ARRAY, calling
51*10465441SEvalZero      * $Super$$__cpp_initialize__aeabi_() will cause fault. At least until Keil5.12
52*10465441SEvalZero      * the problem still exists. So we have to initialize the C++ runtime by ourself.
53*10465441SEvalZero      */
54*10465441SEvalZero     typedef void PROC();
55*10465441SEvalZero     extern const unsigned long SHT$$INIT_ARRAY$$Base[];
56*10465441SEvalZero     extern const unsigned long SHT$$INIT_ARRAY$$Limit[];
57*10465441SEvalZero 
58*10465441SEvalZero     const unsigned long *base = SHT$$INIT_ARRAY$$Base;
59*10465441SEvalZero     const unsigned long *lim  = SHT$$INIT_ARRAY$$Limit;
60*10465441SEvalZero 
61*10465441SEvalZero     for (; base != lim; base++)
62*10465441SEvalZero     {
63*10465441SEvalZero         PROC *proc = (PROC*)((const char*)base + *base);
64*10465441SEvalZero         (*proc)();
65*10465441SEvalZero     }
66*10465441SEvalZero #endif
67*10465441SEvalZero 
68*10465441SEvalZero     return 0;
69*10465441SEvalZero }
70*10465441SEvalZero INIT_COMPONENT_EXPORT(cplusplus_system_init);
71*10465441SEvalZero 
72