I'm compiling code for an ARM Cortex-M0 mcu with GCC arm-none-eabi-g++ (4.8.3).
All is fine, but I noticed that when I include and use any function from cstdlib, all functions from that file are included as well. How to get rid of them?
I'm calling malloc() and free() only, but the resulting ELF has system() and isatty() machine code as well.
The mcu has only 32kB flash, so ~0.7kB ballast matters, especially if this keeps happening for other headers.
Right now I use -ffunction-sections -fdata-sections for compiling and -Wl,--gc-sections -Wl,--static while linking, as follows:
arm-none-eabi-g++ -c --std=c++11 -Os -I. -Ilpc1xxx -Idrivers -Wall -mthumb \
-ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=cortex-m0 \
-DTARGET=LPC11xx -fno-builtin -flto -fno-exceptions -o main.o main.cpp
arm-none-eabi-gcc -c --std=c11 -Os -I. -Ilpc1xxx -Idrivers -Wall -mthumb \
-ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=cortex-m0 \
-DTARGET=LPC11xx -fno-builtin -flto -o core_cm0.o lpc1xxx/nxp/core_cm0.c
arm-none-eabi-gcc -nostartfiles -mcpu=cortex-m0 -mthumb -Wl,--gc-sections -flto \
-Os -Wl,--static -T lpc1xxx/memory.ld -o firmware.elf main.o core_cm0.o \
libaeabi-cortexm0/libaeabi-cortexm0.a LPC11xx_handlers.o LPC1xxx_startup.o
Edit: Warning: The -flto flag in my example is wrong – somehow it discards interrupt routines.
The result is that when I do arm-none-eabi-objdump -t firmware.elf, I get among others:
00000fbc g F .text 0000002c _isatty
00001798 g F .text 00000018 fclose
00000e4c g F .text 00000030 _kill
00000e7c g F .text 00000018 _exit
00000fe8 g F .text 00000050 _system
These functions are clearly redundant (and quite useless on mcu at all), yet GCC keeps them in the executable. There are no calls to them, these symbols are not referenced anywhere. It's effectively dead code.
How to get rid of them? Some extra compiler/linker flags?
Edit:
Minimal code to reproduce my problem:
#include <cstdlib>
int main(){
[[gnu::unused]] volatile void * x = malloc(1);
return 0;
}
Command used to compile that:
arm-none-eabi-g++ --std=c++11 -Os -Wall -mthumb -ffunction-sections
-fdata-sections -fmessage-length=0 -mcpu=cortex-m0 -fno-builtin -flto
-fno-exceptions -Wl,--static -Wl,--gc-sections -o main.elf main.cpp
And the main.elf file still has all stdlib bloat.
Using -ffunction-sections is the right thing here, but the issue is that the object file that provides malloc and free is built without it (either LPC11xx_handlers.o, LPC1xxx_startup.o or some of the object files within libaeabi-cortexm0.a). In that case, the linker can only include the whole object file (or with -Wl,--gc-sections, the whole section) that contain functions you need.
The layout of functions in object files and sections is the only thing that actually matters, not which function is defined in the same header as another function.
So to fix your issue, rebuild your standard library files with -ffunction-sections -fdata-sections.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With