From 1974bec8bf09e2e4e26bfc67ae0664c1b032eaae Mon Sep 17 00:00:00 2001 From: Bernard Xiong Date: Sat, 1 Nov 2014 14:12:58 +0800 Subject: [PATCH] [C++] fix the ctors initialization issue --- components/cplusplus/README.md | 42 ++++++++++++++++++++++++++++++++- components/cplusplus/SConscript | 4 ++-- components/cplusplus/crt.h | 1 + components/cplusplus/crt_init.c | 24 +++++++++++++++++++ 4 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 components/cplusplus/crt_init.c diff --git a/components/cplusplus/README.md b/components/cplusplus/README.md index cd133effa..44851db56 100644 --- a/components/cplusplus/README.md +++ b/components/cplusplus/README.md @@ -10,4 +10,44 @@ Because RT-Thread RTOS is used in embedded system mostly, there are some rules f 4. Static class variables are discouraged. The time and place to call their constructor function could not be precisely controlled and make multi-threaded programming a nightmare. 5. Multiple inheritance is strongly discouraged, as it can cause intolerable confusion. -*NOTE*: For armcc compiler, the libc must be enable. +*NOTE*: The libc must be enable. + +About GNU GCC compiler + +please add following string in your ld link script: +// in your .text section + PROVIDE(__ctors_start__ = .); + /* old GCC version uses .ctors */ + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + /* new GCC version uses .init_array */ + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE(__ctors_end__ = .); + + . = ALIGN(4); + +// as a standalone section if you use ARM target. + + /* The .ARM.exidx section is used for C++ exception handling. */ + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + + /* This is used by the startup in order to initialize the .data secion */ + _sidata = .; + } > CODE + __exidx_end = .; + + /* .data section which is used for initialized data */ + +// in your .data section + PROVIDE(__dtors_start__ = .); + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + PROVIDE(__dtors_end__ = .); + + . = ALIGN(4); + diff --git a/components/cplusplus/SConscript b/components/cplusplus/SConscript index eb95aaa3c..b41537a52 100644 --- a/components/cplusplus/SConscript +++ b/components/cplusplus/SConscript @@ -3,9 +3,9 @@ from building import * cwd = GetCurrentDir() -src = Glob('*.cpp') +src = Glob('*.cpp') + Glob('*.c') CPPPATH = [cwd] -group = DefineGroup('CPlusPlus', src, depend = ['RT_USING_CPLUSPLUS'], CPPPATH = CPPPATH) +group = DefineGroup('CPlusPlus', src, depend = ['RT_USING_CPLUSPLUS', 'RT_USING_LIBC'], CPPPATH = CPPPATH) Return('group') diff --git a/components/cplusplus/crt.h b/components/cplusplus/crt.h index 04fba47a6..fd287c2ad 100644 --- a/components/cplusplus/crt.h +++ b/components/cplusplus/crt.h @@ -11,5 +11,6 @@ void operator delete(void * ptr); void operator delete[] (void *ptr); extern "C" void __cxa_pure_virtual(void); +extern "C" int cplusplus_system_init(void); #endif diff --git a/components/cplusplus/crt_init.c b/components/cplusplus/crt_init.c new file mode 100644 index 000000000..20f81cdb5 --- /dev/null +++ b/components/cplusplus/crt_init.c @@ -0,0 +1,24 @@ +#include + +int cplusplus_system_init(void) +{ +#if defined(__GNUC__) && !defined(__CC_ARM) + extern unsigned char __ctors_start__; + extern unsigned char __ctors_end__; + typedef void (*func)(void); + + /* .ctors initalization */ + func *ctors_func; + + for (ctors_func = (func *)&__ctors_start__; + ctors_func < (func *)&__ctors_end__; + ctors_func ++) + { + (*ctors_func)(); + } +#endif + + return 0; +} +INIT_COMPONENT_EXPORT(cplusplus_system_init); + -- GitLab