From 248fb1c6c08521bb2c1674b344c4ce8dde5197ab Mon Sep 17 00:00:00 2001 From: Joakim Gebart Date: Fri, 29 May 2015 02:37:35 +0200 Subject: [PATCH] sys/cpp11-compat: Add C++ runtime helpers cppsupport.cpp contains functions which are necessary in order to use some features of the C++ language, e.g. calling static constructors or virtual functions. TODO/Not implemented yet: - Test virtual functions - Handle exceptions (stack unwinding) - Run time type identification (RTTI) --- sys/Makefile.include | 3 + sys/cpp11-compat/cppsupport.cpp | 147 ++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 sys/cpp11-compat/cppsupport.cpp diff --git a/sys/Makefile.include b/sys/Makefile.include index 6ee00a8b96..cedc4c608a 100644 --- a/sys/Makefile.include +++ b/sys/Makefile.include @@ -30,6 +30,9 @@ endif ifneq (,$(filter cpp11-compat,$(USEMODULE))) USEMODULE_INCLUDES += $(RIOTBASE)/sys/cpp11-compat/include + # make sure cppsupport.o is linked explicitly because __dso_handle is not + # found if it is hidden away inside a static object. + export UNDEF += $(BINDIR)cpp11-compat/cppsupport.o endif ifneq (,$(filter ng_slip,$(USEMODULE))) diff --git a/sys/cpp11-compat/cppsupport.cpp b/sys/cpp11-compat/cppsupport.cpp new file mode 100644 index 0000000000..2274b7a305 --- /dev/null +++ b/sys/cpp11-compat/cppsupport.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2015 Eistec AB + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpp11-compat + * @{ + * + * @file + * @brief C++ runtime support functions + * + * Tested with GCC-4.9.2 and Clang-3.6 + * + * @author Joakim Gebart + */ + +#include +#include +#include + +extern "C" { +#include "panic.h" +} + +/** + * @brief DSO handle + * + * This symbol is used by dynamic shared objects to identify them, but it is + * somehow pulled in as a dependency by the compiler-generated global (static) + * constructor code. + */ +void *__dso_handle __attribute__((weak)) = NULL; + +/** + * @brief Definition of a pure virtual function + * + * Calling this function is an error. + */ +extern "C" void __cxa_pure_virtual () +{ + core_panic(123, "PURE VIRTUAL CALL"); +} + +/** + * @brief Register a function to be called by exit or when a shared library is unloaded. + * + * Not really used on an embedded system where you pull the power to shut down + * the program. + * + * This is only called by code automatically generated by the C++ compiler. + * + * @return 0 on success + * @return non-zero on failure. + */ +extern "C" int __cxa_atexit (void (*) (void *), void *, void *) +{ + /* We just pretend everything is dandy. */ + return 0; +} + +namespace __gnu_cxx { +/** + * @brief Override the G++ verbose termination handler + * + * The default implementation of __gnu_cxx::__verbose_terminate_handler comes + * with gcc and will print the name of unhandled exceptions to stderr before + * terminating the program. However, in order to get the name of the exceptions + * a large chunk of name demangling code is pulled in as well (several tens of + * kBytes!). + * + * @note Depending on the version of the compiler and what settings were used + * when building the toolchain __gnu_cxx::__verbose_terminate_handler may or may + * not be pulled in. std::abort may be used instead by default in some + * toolchains. + * + * @see http://www.webalice.it/fede.tft/cpp_on_microcontrollers_tricks/cpp_on_microcontrollers_tricks.html + */ +void __verbose_terminate_handler() +{ + core_panic(123, "UNHANDLED C++ EXCEPTION"); +} +} /* namespace __gnu_cxx */ + +/* Implementations of new and delete operators taken from public domain code + * at http://pastebin.com/7VKUuTJa (downloaded on Wed 24 Jun 2015 09:00:07 PM CEST) + * Author: Eric Agan + * The license text reads: + * > "Public domain, use however you wish. + * > "If you really need a license, consider it MIT." + */ + +/* tinynew.cpp + + Overrides operators new and delete + globally to reduce code size. + + Public domain, use however you wish. + If you really need a license, consider it MIT: + http://www.opensource.org/licenses/mit-license.php + + - Eric Agan + Elegant Invention + */ + +void* operator new(std::size_t size) { + return std::malloc(size); +} + +void* operator new[](std::size_t size) { + return std::malloc(size); +} + +void operator delete(void* ptr) noexcept { + std::free(ptr); +} + +void operator delete[](void* ptr) noexcept { + std::free(ptr); +} + +/* Optionally you can override the 'nothrow' versions as well. + This is useful if you want to catch failed allocs with your + own debug code, or keep track of heap usage for example, + rather than just eliminate exceptions. + */ + +void* operator new(std::size_t size, const std::nothrow_t&) noexcept { + return std::malloc(size); +} + +void* operator new[](std::size_t size, const std::nothrow_t&) noexcept { + return std::malloc(size); +} + +void operator delete(void* ptr, const std::nothrow_t&) noexcept { + std::free(ptr); +} + +void operator delete[](void* ptr, const std::nothrow_t&) noexcept { + std::free(ptr); +} + +/** @} */