Unfortunately calculating function size is not as easy of finding variable size using sizeof() compile-time operator. There are numerous ways to calculate the size in run-time but to keep things simple, it’s better to check that information from linker, as for sure must knows it.
Let’s talk about what things we are going to use:
1- “.map” file generated by GCC/G++ linker:
This file has the symbols we have in the code/firmware either in flash, RAM or any other defined memory section. The following snippet is taken from compiling one of the examples of nRF52 SDK. If you want to try just run make default inside the following directory examples\peripheral\gpiote\pca10040\blank\armgcc. The first column is the symbol start address, the second column is the function size in HEX and the third one is the object file name containing that symbol.
.text.bsp_board_led_invert 0x00000380 0x24 _build/nrf52832_xxaa/boards.c.o 0x00000380 bsp_board_led_invert .text.bsp_board_init 0x000003a4 0x5c _build/nrf52832_xxaa/boards.c.o 0x000003a4 bsp_board_init
You can scan this file until you find the function you’re looking for and find its length and start address. For instance bsp_board_led_invert takes 36 bytes in Flash.
2- “.out” file generated by GCC/G++ and NM GNU tool
Sometimes it’s hard to search a symbol in the .map file here comes nm tool found with GCC tool-chain to list all symbols in an object file. To list all your code symbols then use the .out file with nm or .elf file should also do the job too. This tool can list the symbols and also sort the symbols according to the size. I have the .out file from the first step, so simply to list the symbols by size run the following command (make sure you’re using the right command as I’m using ARM GCC here)
arm-none-eabi-nm -S --size-sort -t d nrf52832_xxaa.out
And here is a snippet from output
00001024 00000030 T app_error_handler_bare 00000896 00000036 T bsp_board_led_invert 00003460 00000040 T exit 00000720 00000040 T Reset_Handler 00001056 00000052 W app_error_fault_handler 00000780 00000052 t gpioIntHandler 00000832 00000064 T main 00003500 00000076 T __libc_init_array 536871056 00000076 b m_cb 00000932 00000090 T bsp_board_init 536870916 00000096 d impure_data 00001108 00000136 T nrfx_gpiote_init 00001568 00000196 T nrfx_gpiote_in_event_enable 00002448 00000200 T TIMER0_IRQHandler 00001244 00000324 T nrfx_gpiote_in_init 00000000 00000512 T __isr_vector 00001764 00000684 T GPIOTE_IRQHandler 00002648 00000812 T SystemInit 536871144 00008192 N __HeapBase
The first column is the start address in decimal, then the length and the symbol name.
Weird Symbols Names ?
If you found strange names as symbols, and mostly strange characters added as suffix and prefix to a function or variable name you know, then this comes from what is called name mangling. For example, get_event function could become something like that:
__ZN2os9get_eventENS_17enum_task_id_typeE
Why? This is because the compiler needs unique names for variables, functions, …etc and while we can have static variables or functions with same names in different source files, then the compiler need to distinguish between them. The same thing is applicable to c++ for overloading also.
To de-mangle the name, C++filt is the tool used to produce the original name, for example running the following to de-mangle the past example:
arm-none-eabi-c++filt __ZN2os9get_eventENS_17enum_task_id_typeE