I need to be able to compile C++ code (using dynamic memory allocation with new/delete) on a LPC2378 (and LPC2478) with several different GNU-flavoured toolchains (yagarto, ride, hitex…). I’ve been trying to solve this on my own, with a little help from google, for about a week now without success. It’s working great using C++ without dynamic memory allocation, but I really do need it. Has anybody here done anything similar? Got any tips or pointers? Maybe even an example?
You don’t really need libstdc++ if you don’t use RTTI or exceptions. You can disable them by compiling with -fno-rtii -fno-exceptions. You can define your own new/delete to wrap malloc; you’ll probably want this anyway since if you compile without exceptions new will return NULL on allocation failures, while you’d probably prefer to stop in an assert waiting for a debugger (via JTAG) or flash a LED, or possibly reset, depending on what you’re building for (dev or deployment). There are very few ABI functions, and none of them likely do anything you’ll need so you can easily stub them out. Compile and link using ld (as opposed to the frontend) and see what you get undefined. Google the functions to see what they do. It’ll be things like atexit() registrations and termination code. Given that embedded code rarely has any need to cleanup at exit since it’s not intended to ever exit, you can just stub things like this it out to satisfy the linker. Once you get that working, go over the default ld script and remove what you don’t need, like global/static destructors, and provide your own startup that runs global constructors and sets up a top-level C frame. (Some of the common ones on the net don’t do this.)
Just to give a sense of what’s needed, here’s what I stubbed for a recent project:
#undef abort
void abort() { panic("ABORT"); }
// ABI stuff
extern "C" {
int __cxa_atexit(void (*func) (void*), void* arg, void* dso_handle);
int __cxa_pure_virtual();
}
int __cxa_atexit(void (*func) (void*), void* arg, void* dso_handle)
{
return 0;
}
int __cxa_pure_virtual() { abort(); return 0; }
void* __dso_handle = (void*) &__dso_handle;
This problem has been solved, C++ code with dynamic memory allocation and exception handling is running smoothly. The crucial thing was that the link script which has been in use for C code only projects lacked parts describing the location of memory to be used for constructors/destructors.
This problem has been solved, C++ code with dynamic memory allocation and exception handling is running smoothly. The crucial thing was that the link script which has been in use for C code only projects lacked parts describing the location of memory to be used for constructors/destructors.
So, thanks again for your help!
–j.l.
indeed, if there's delete and free() and some randomness, as time goes by, the heap gets fragmented and the garbage collector (if there is one), on a small micro, struggles. If you don't do delete/free much, you can sneak by. Or preclude irregular-sized objects from delete/free.