浏览代码

[C++] fix the ctors initialization issue

Bernard Xiong 10 年之前
父节点
当前提交
1974bec8bf
共有 4 个文件被更改,包括 68 次插入3 次删除
  1. 41 1
      components/cplusplus/README.md
  2. 2 2
      components/cplusplus/SConscript
  3. 1 0
      components/cplusplus/crt.h
  4. 24 0
      components/cplusplus/crt_init.c

+ 41 - 1
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);
+

+ 2 - 2
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')

+ 1 - 0
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

+ 24 - 0
components/cplusplus/crt_init.c

@@ -0,0 +1,24 @@
+#include <rtthread.h>
+
+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);
+