Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
.elf file - What contributes to the resulting .bin file size?
I have found this nice library for parsing/writing .elf files as output by e.g. the GCC toolchain: ELFIO
I have a bare metal embedded project with an ARM Cortex M target.
My goal is to overwrite a certain section within the .elf file generated by the build process. One of the values I want to write into the reserved section is the size of the resulting .bin file.
It is a firmware application, and the bootloader is to extract that part of the binary to know its size and checksum (when the app is residing in flash memory and is to be checked for validity).
Now I used the library to sum the section sizes to obtain the total size - of those whose addresses are within the flash region. But that number is different than the size of the bin file that the build also creates, e.g. 98268 (sum) instead of 98576 (app.bin) Bytes.
What am I doing wrong?
I have used a different scheme before, where I was just handling raw .bin files and glueing a header with the info before it - but to debug with the vendor-provided, modified-Eclipse IDE, and load everything onto the target in one go (bootloader, firmware with info section), I need to specify .elf files. I could of course additionally pass the .bin file, that's created anyway, to my info section generator program - but that seems silly, the info should be in the .elf file and I'd like to pass only that to the program.
Edit:
Below are the section headers of the elf file, ".buildinfo" is my custom section. I was searching & reading a bit about what the section types mean, and saw here that PROGBITS "is stored in the disk image". So instead of blindly summing up sizes of all sections which are in the flash range (0x8000000...0x8040000), I am now summing all PROGBITS sections' sizes, unless their address is 0x0 (I don't know why yet). I also found a description of ARM specific sections on page 22, 5.3.2. Section Types.
Now, if, additionally to the non-zero-address PROGBITS sections, also add the sizes of INIT_ARRAY, FINI_ARRAY and that SHT_ARM_EXIDX=0x70000001 (exception table index, below just ".ARM"), then the sum will match that of the .bin file which the tool chain creates. I don't check for flash range of address anymore, as the .data segment, see below, isn't in that range, for whatever reason. I guess I should also be adding PREINIT_ARRAY, which is currently 0.
While it looks like it sorta makes sense from my superficial idea I gathered so far, I don't understand it exactly and don't have confidence in the correctness of this.
Edit #2:
I have now written a file where I put all the sections I listed above after another, in the sequence they appeared, and compared it with the toolchain-generated .bin file in a hex editor. They match. So it looks good so far.
But I don't know that what I do is formally correct, and whether, maybe, if any part of the project setup ever changes, my process stops producing correct files because some case is not covered in my program.
Section Headers:
[ Nr ] Type Addr Size ES Flg Lk Inf Al Name
[ 0] NULL 00000000 00000000 00 00 000 00
[ 1] PROGBITS 08008080 000000bc 00 A 00 000 01 .isr_vector
[ 2] PROGBITS 0800813c 00000040 00 A 00 000 04 .buildinfo
[ 3] PROGBITS 0800817c 00013268 00 AX 00 000 04 .text
[ 4] PROGBITS 0801b3e4 00004c44 00 A 00 000 04 .rodata
[ 5] PROGBITS 08020028 00000000 00 W 00 000 01 .ARM.extab
[ 6] ? (0x70000001) 08020028 00000008 00 A 03 000 04 .ARM
[ 7] PREINIT_ARRAY 08020030 00000000 04 WA 00 000 01 .preinit_array
[ 8] INIT_ARRAY 08020030 00000020 04 WA 00 000 04 .init_array
[ 9] FINI_ARRAY 08020050 0000000c 04 WA 00 000 04 .fini_array
[ 10] PROGBITS 200000c0 00000134 00 WA 00 000 04 .data
[ 11] NOBITS 200001f8 000018e0 00 WA 00 000 08 .bss
[ 12] NOBITS 20001ad8 00000600 00 WA 00 000 01 ._user_heap_stack
[ 13] ? (0x70000003) 00000000 00000028 00 00 000 01 .ARM.attributes
[ 14] PROGBITS 00000000 0006e259 00 00 000 01 .debug_info
[ 15] PROGBITS 00000000 00011f5e 00 00 000 01 .debug_abbrev
[ 16] PROGBITS 00000000 00002ab8 00 00 000 08 .debug_aranges
[ 17] PROGBITS 00000000 000027d0 00 00 000 08 .debug_ranges
[ 18] PROGBITS 00000000 00023d0c 00 00 000 01 .debug_macro
[ 19] PROGBITS 00000000 00030c90 00 00 000 01 .debug_line
[ 20] PROGBITS 00000000 00094f6e 01 00 000 01 .debug_str
[ 21] PROGBITS 00000000 00000053 01 00 000 01 .comment
[ 22] PROGBITS 00000000 0000a680 00 00 000 04 .debug_frame
[ 23] SYMTAB 00000000 0000c5d0 10 18 970 04 .symtab
[ 24] STRTAB 00000000 0000bdca 00 00 000 01 .strtab
[ 25] STRTAB 00000000 00000115 00 00 000 01 .shstrtab
1 comment thread