Merge changes I8ee7d119,Ibf8d2f54,I5fb92299,I07315f1b

* changes:
  [ion] Initialize static C++ objects
  [liba] Define __aeabi_atexit
  [libaxx] Define __cxa_atexit
  [libaxx] Explicitely define __cxa_pure_virtual
This commit is contained in:
Émilie Feral
2016-12-08 15:19:29 +01:00
committed by Gerrit
7 changed files with 61 additions and 10 deletions

View File

@@ -36,15 +36,17 @@ SECTIONS {
.text : {
. = ALIGN(4);
/* C++ code calls __cxa_pure_virtual when a pure-virtual method is called.
* This is an error case, so we just redirect it to abort. */
PROVIDE(__cxa_pure_virtual = abort);
*(.text)
*(.text.*)
} >FLASH
.init_array : {
. = ALIGN(4);
_init_array_start = .;
KEEP (*(.init_array*))
_init_array_end = .;
} >FLASH
.rodata : {
. = ALIGN(4);
*(.rodata)

View File

@@ -6,11 +6,17 @@ extern "C" {
#include <ion.h>
#include "../device.h"
extern char _data_section_start_flash;
extern char _data_section_start_ram;
extern char _data_section_end_ram;
extern char _bss_section_start_ram;
extern char _bss_section_end_ram;
typedef void (*cxx_constructor)();
extern "C" {
char _data_section_start_flash;
char _data_section_start_ram;
char _data_section_end_ram;
char _bss_section_start_ram;
char _bss_section_end_ram;
cxx_constructor _init_array_start;
cxx_constructor _init_array_end;
}
void abort() {
#ifdef DEBUG
@@ -38,6 +44,16 @@ void start() {
size_t bssSectionLength = (&_bss_section_end_ram - &_bss_section_start_ram);
memset(&_bss_section_start_ram, 0, bssSectionLength);
/* Call static C++ object constructors
* The C++ compiler creates an initialization function for each static object.
* The linker then stores the address of each of those functions consecutively
* between _init_array_start and _init_array_end. So to initialize all C++
* static objects we just have to iterate between theses two addresses and
* call the pointed function. */
for (cxx_constructor * c = &_init_array_start; c<&_init_array_end; c++) {
(*c)();
}
Ion::Device::init();
ion_app();

View File

@@ -56,6 +56,7 @@ tests += $(addprefix liba/test/, \
# The use of aeabi-rt could be made conditional to an AEABI target.
# In practice we're always using liba on such a target.
objs += $(addprefix liba/src/aeabi-rt/, \
atexit.o \
memclr.o \
memcpy.o \
)

View File

@@ -0,0 +1,7 @@
/* See the "Run-time ABI for the ARM Architecture", Section 4.4.5 */
int __cxa_atexit(void (* dtor)(void * this), void * object, void * handle);
int __aeabi_atexit(void * object, void (*destroyer)(void *), void * dso_handle) {
return __cxa_atexit(destroyer, object, dso_handle);
}

View File

@@ -1 +1,2 @@
objs += $(addprefix libaxx/src/, new.o)
objs += $(addprefix libaxx/src/cxxabi/, atexit.o pure_virtual.o)

View File

@@ -0,0 +1,14 @@
/* C++ expects the __dso_handle symbol to be defined to some unique value in
* each dynamic shared object. Even though we're not using dynamic loading,
* we still have to define __dso_handle. */
void * __dso_handle = nullptr;
/* The __cxa_atexit function registers a function to be called when the program
* exits or when a shared library is unloaded.
* We don't support shared libraries and our program should never exit, so we
* can simply do nothing and return zero. */
extern "C" int __cxa_atexit(void (*dtor)(void *), void * object, void * handle) {
return 0;
}

View File

@@ -0,0 +1,10 @@
extern "C" {
#include <stdlib.h>
}
/* C++ code calls __cxa_pure_virtual when a pure-virtual method is called.
* This is an error case, so we just redirect it to abort. */
extern "C" void __cxa_pure_virtual() {
abort();
}