Using arm-none-eabi-gcc for Cortex-M4 (baremetal application), the code for malloc
is also emitted even though I never use malloc
in my code.
S
Probably you need -fno-use-cxa-atexit
argument for compiler.
Look on this simple example to get working C++ code on pure bare-metal: https://github.com/cortexm/baremetal
-nostartfiles
and -nostdlib
worked for me in a similar context.
So here's the workaround that I'm using. Not perfect, but good enough.
Using the --wrap option of ld
, I can provide my own definition for atexit
that doesn't do anything.
int __wrap_atexit(void __attribute__((unused)) (*function)(void)) {
return -1;
}
and then link with --wrap=atexit
option.
Now, atexit
does not call any other functions and the -ffunction-sections
and --gc-sections
options ensure that malloc
is not included in the output file.
Additionally, to enforce that malloc
isn't included, a --wrap=malloc
option can be passed while linking without defining __wrap_malloc
anywhere. This will fail with a link error if some other function happens to use malloc
.
In an environment with limited memory such as the Cortex M4, another option is to use newlib-nano. It provides a __register_exitproc()
that is weakly linked. Therefore it is easy to override with your own empty function that avoids calling malloc()
. This will have the additional benefit of removing __call_exitprocs()
from your binary as well.
--specs=nano.specs
to your compiler and linker options.void __register_exitproc(void) { }
Note that this will prevent destructors being called for static instances of classes. This seems appropriate in your example.
See the comments in the newlib source for more details.