Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics

Dashboard
Notifications
Mark all as read
Q&A

.elf file - What contributes to the resulting .bin file size?

+7
−0

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
Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

4 comments

It's hard to tell and guess without actually being able to take a closer look at the bin and elf file. But i guess the sections in the elf file don't form a continuous block of memory, and there could be unused memory "gaps" between some sections in memory. Your bin file (whose actual file format i also don't know, so remember it is just guesswork) might represent a single continuous memory region containing the data of the sections as well as the unused bytes in the "gaps". elgonzo‭ 11 days ago

It would probably be easier to generate a S-record or Intel hex file (text file formats). Then just search for the highest address, add this address to the size of the data stored at that address, then subtract the offset for where the flash starts from there. Lundin‭ 10 days ago

I added a section header table and some more info. sktpin‭ 10 days ago

can you have GCC generate both ELF and another format side by side? I found intel .hex easy to work with Pete W‭ 8 days ago

0 answers

Sign up to answer this question »