From 33ab387a79a67585bae356196e1ed9b58e123b3f Mon Sep 17 00:00:00 2001 From: Alexey Guseynov Date: Sun, 12 Aug 2012 23:07:41 +0400 Subject: [PATCH 1/2] Correct implementation of gcc specific internal functions --- hardware/arduino/cores/arduino/abi.cpp | 61 ++++++++++++++++++++++++++ hardware/arduino/cores/arduino/abi.h | 19 ++++++++ hardware/arduino/cores/arduino/new.cpp | 7 --- hardware/arduino/cores/arduino/new.h | 8 ---- 4 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 hardware/arduino/cores/arduino/abi.cpp create mode 100644 hardware/arduino/cores/arduino/abi.h diff --git a/hardware/arduino/cores/arduino/abi.cpp b/hardware/arduino/cores/arduino/abi.cpp new file mode 100644 index 00000000000..f9f8b1fc454 --- /dev/null +++ b/hardware/arduino/cores/arduino/abi.cpp @@ -0,0 +1,61 @@ +#include +#include +// TODO Uncomment this once you have libstdc++ +//#include + +#include +#include + +namespace { +// guard is an integer type big enough to hold flag and a mutex. +// By default gcc uses long long int and avr ABI does not change it +// So we have 32 or 64 bits available. Actually, we need 16. + +inline char& flag_part(__guard *g) { + return *(reinterpret_cast(g)); +} + +inline uint8_t& sreg_part(__guard *g) { + return *(reinterpret_cast(g) + sizeof(char)); +} +} + +int __cxa_guard_acquire(__guard *g) { + uint8_t oldSREG = SREG; + cli(); + // Initialization of static variable has to be done with blocked interrupts + // because if this function is called from interrupt and sees that somebody + // else is already doing initialization it MUST wait until initializations + // is complete. That's impossible. + // If you don't want this overhead compile with -fno-threadsafe-statics + if (flag_part(g)) { + SREG = oldSREG; + return false; + } else { + sreg_part(g) = oldSREG; + return true; + } +} + +void __cxa_guard_release (__guard *g) { + flag_part(g) = 1; + SREG = sreg_part(g); +} + +void __cxa_guard_abort (__guard *g) { + SREG = sreg_part(g); +} + +void __cxa_pure_virtual(void) { + // We might want to write some diagnostics to uart in this case + // TODO Uncomment this once you have libstdc++ + //std::terminate(); + abort(); +} + +void __cxa_deleted_virtual(void) { + // We might want to write some diagnostics to uart in this case + // TODO Uncomment this once you have libstdc++ + //std::terminate(); + abort(); +} diff --git a/hardware/arduino/cores/arduino/abi.h b/hardware/arduino/cores/arduino/abi.h new file mode 100644 index 00000000000..370087e8c20 --- /dev/null +++ b/hardware/arduino/cores/arduino/abi.h @@ -0,0 +1,19 @@ +/* Header to define cxx abi parts missing from avrlibc */ + +#ifndef ABI_H_INCLUDED +#define ABI_H_INCLUDED + +#include + +__extension__ typedef int __guard __attribute__((mode (__DI__))); + +extern "C" { +int __cxa_guard_acquire(__guard *); +void __cxa_guard_release (__guard *); +void __cxa_guard_abort (__guard *); + +void __cxa_pure_virtual(void) __attribute__ ((__noreturn__)); +void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__)); +} + +#endif diff --git a/hardware/arduino/cores/arduino/new.cpp b/hardware/arduino/cores/arduino/new.cpp index 0f6d4220ef7..35d66a58c11 100644 --- a/hardware/arduino/cores/arduino/new.cpp +++ b/hardware/arduino/cores/arduino/new.cpp @@ -9,10 +9,3 @@ void operator delete(void * ptr) { free(ptr); } - -int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);}; -void __cxa_guard_release (__guard *g) {*(char *)g = 1;}; -void __cxa_guard_abort (__guard *) {}; - -void __cxa_pure_virtual(void) {}; - diff --git a/hardware/arduino/cores/arduino/new.h b/hardware/arduino/cores/arduino/new.h index cd940ce8b26..bd2a1b0ce38 100644 --- a/hardware/arduino/cores/arduino/new.h +++ b/hardware/arduino/cores/arduino/new.h @@ -10,13 +10,5 @@ void * operator new(size_t size); void operator delete(void * ptr); -__extension__ typedef int __guard __attribute__((mode (__DI__))); - -extern "C" int __cxa_guard_acquire(__guard *); -extern "C" void __cxa_guard_release (__guard *); -extern "C" void __cxa_guard_abort (__guard *); - -extern "C" void __cxa_pure_virtual(void); - #endif From 0097c00c88d49e85e35829c2366d0ad3a216795a Mon Sep 17 00:00:00 2001 From: Alexey Guseynov Date: Sun, 12 Aug 2012 23:10:04 +0400 Subject: [PATCH 2/2] operator new violates C++ standard. There is uclibc++ port whoch suppplies correct realization for all required operator new and operator delete overloads. Please use it. --- hardware/arduino/cores/arduino/Printable.h | 2 -- hardware/arduino/cores/arduino/abi.cpp | 11 +++-------- hardware/arduino/cores/arduino/new.cpp | 11 ----------- hardware/arduino/cores/arduino/new.h | 14 -------------- 4 files changed, 3 insertions(+), 35 deletions(-) delete mode 100644 hardware/arduino/cores/arduino/new.cpp delete mode 100644 hardware/arduino/cores/arduino/new.h diff --git a/hardware/arduino/cores/arduino/Printable.h b/hardware/arduino/cores/arduino/Printable.h index d03c9af62c4..54f7d717c60 100644 --- a/hardware/arduino/cores/arduino/Printable.h +++ b/hardware/arduino/cores/arduino/Printable.h @@ -20,8 +20,6 @@ #ifndef Printable_h #define Printable_h -#include - class Print; /** The Printable class provides a way for new classes to allow themselves to be printed. diff --git a/hardware/arduino/cores/arduino/abi.cpp b/hardware/arduino/cores/arduino/abi.cpp index f9f8b1fc454..3c2dfed537f 100644 --- a/hardware/arduino/cores/arduino/abi.cpp +++ b/hardware/arduino/cores/arduino/abi.cpp @@ -1,7 +1,6 @@ #include #include -// TODO Uncomment this once you have libstdc++ -//#include +#include #include #include @@ -48,14 +47,10 @@ void __cxa_guard_abort (__guard *g) { void __cxa_pure_virtual(void) { // We might want to write some diagnostics to uart in this case - // TODO Uncomment this once you have libstdc++ - //std::terminate(); - abort(); + std::terminate(); } void __cxa_deleted_virtual(void) { // We might want to write some diagnostics to uart in this case - // TODO Uncomment this once you have libstdc++ - //std::terminate(); - abort(); + std::terminate(); } diff --git a/hardware/arduino/cores/arduino/new.cpp b/hardware/arduino/cores/arduino/new.cpp deleted file mode 100644 index 35d66a58c11..00000000000 --- a/hardware/arduino/cores/arduino/new.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include - -void * operator new(size_t size) -{ - return malloc(size); -} - -void operator delete(void * ptr) -{ - free(ptr); -} diff --git a/hardware/arduino/cores/arduino/new.h b/hardware/arduino/cores/arduino/new.h deleted file mode 100644 index bd2a1b0ce38..00000000000 --- a/hardware/arduino/cores/arduino/new.h +++ /dev/null @@ -1,14 +0,0 @@ -/* Header to define new/delete operators as they aren't provided by avr-gcc by default - Taken from http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453 - */ - -#ifndef NEW_H -#define NEW_H - -#include - -void * operator new(size_t size); -void operator delete(void * ptr); - -#endif -