cancel
Showing results for 
Search instead for 
Did you mean: 

Which parts of an .ELF file go into the .bin file?

SKled.1
Senior II

(since I am getting "Error while parsing Rich Text Content" in the saved post all the time, even though in the EDITOR everything renders just fine, I dumped the text in there without nice formatting)

-------------------------------------------------------------

I have a bootloader and app project in one CubeIDE workspace, for a STM32F0 target.

I added a linker script section (see below, ".buildinfo") to put some info into, also including the CRC and size of the firmware app image, so that the bootloader can check it when it's in flash.

I am also trying to get this to flash all in one go (loader, app with info section) for debugging from CubeIDE, which is why I am now trying to go the .elf route and ditch my previous "tack header onto .bin file" approach.

So I would manipulate the ELF file as post build step, and re-generate the .bin, too, with a call to objcopy on the modified elf.

I am using a library (ELFIO) to parse the .elf file, and I see the sections further below.

While I looked for information about what parts of the .elf go into the .bin, I alas found no single document that describes exactly that. I found some scattered info, like that linked below, and drew some, possibly erroneous, conclusions.

Now, to determine the size of the wouldbe .bin file from only info out of the .elf file, I am summing this:

  •  sizes of all PROGBITS sections where address != 0x0
  • sizes of PREINIT_ARRAY, INIT_ARRAY, FINI_ARRAY
  • size of the ***_ARM_EXIDX=0x70000001 (below ".ARM") section

This results in the same size as the currently generated .bin has.

But: Is this correct?.

This was all a bit of guesswork, and I especially don't know why e.g. the .data section's address is given as out of the flash range (that's why I check for addr!=0 instead of "outside flash range"). Oh, and I also don't know why there are even sections with address=0.

References:

ELF sections

https://www.tortall.net/projects/yasm/manual/html/objfmt-elf-section.html

ARM specific sectrions, p. 22, s. 5.3.2

https://static.docs.arm.com/ihi0044/g/aaelf32.pdf

  

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

5 REPLIES 5
SKled.1
Senior II

TEST:

List:

  • sizes of all PROGBITS sections where address != 0x0
  • sizes of PREINIT_ARRAY, INIT_ARRAY, FINI_ARRAY
  • size of the ***_ARM_EXIDX=0x70000001 (below ".ARM") section

Okay.

Why is the letter combination of S, H, T replaced with asterisks?

Are we a bit over zealous with language policing, ST?

But that's apparently not what caused the parsing error.

I also tried to improve the formatting again and it is similar to where I started from, but now it works. Funny.

You can extract explicitly sections from .elf into .bin in that particular step, ie. using -j switch. Read objcopy/binutils manual. You may need to extract the "usual" parts, then the additional ones, and then merge them. It's better to work with .hex rather than .bit; the former can then be post-processed e.g. using srecord.

JW

SKled.1
Senior II

Since I need to put a CRC of the image into the .elf file, which is required to use also for upload/debug, it seems to make sense to modify my program that calculates the CRC to now do it on the .elf instead on the .bin, and insert that info back into the .elf.

I just wasn't sure which sections exactly, and how, go into the .bin file (the naked file that e.g. also the STLink util writes as-is to the flash).

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.

Pavel A.
Evangelist III

@Community member​ Bin files are very easy to patch and hack. It is easier to add your CRC and stuff to .bin files after conversion than to .elf files.

You probably wish the latter so that you can debug in the IDE.

My solution for this is having a "debug" version of bootloader that allows "raw" images, right as the debugger loads them.

With this approach I don't care about structure of elf files at all, and do not need extra post-build steps which can go wrong.

> I especially don't know why e.g. the .data section's address is given as out of the flash range

Ah. The GNU link script and startup code are cleverly designed so that a typical program image is one continuous chunk in ROM (flash),

This results in small .bin files even if .data is in RAM and its address is far away from code address.

Initialized data is stored next to code in the image. The startup routine copies it from flash to its runtime address in RAM.

Other compiles (Keil, IAR...) do a similar thing.

-- pa

I use the Program Header PT_LOAD records to determine what's loaded, ie real PROGBITS rather than assorted noise.

If you have multiple memory regions you'll need/want to sum or sign them separately.

ELFArm Copyright (C) C Turvey 1997-2011
 
N25Q128A_STM32F746G-DISCO.stldr
 
e_type                                  0002     (ET_EXEC)
e_machine                               0028     (EM_ARM)
e_version                               00000001
e_entry                                 200012B5
e_phoff                                 00025C20
e_shoff                                 00025C60
e_flags                                 05000016 (EF_ARM_EABI_VER5)
e_ehsize                                0034
e_phentsize                             0020
e_phnum                                 0002
e_shentsize                             0028
e_shnum                                 0011
e_shstrndx                              0001
 
Program Header #0
 
p_type                                  00000001 (PT_LOAD)
p_offset                                00000034
p_vaddr                                 20000004
p_paddr                                 20000004
p_filesz                                00001C51
p_memsz                                 00001C51
p_flags                                 00000007 (RWX)
p_align                                 00000004
 
Program Header #1
 
p_type                                  00000001 (PT_LOAD)
p_offset                                00001C88
p_vaddr                                 20001C58
p_paddr                                 20001C58
p_filesz                                000000C8
p_memsz                                 000000C8
p_flags                                 00000004 (R--)
p_align                                 00000004
 
Section Header #0
 
sh_name                                 00000000 ()
sh_type                                 00000000 (***_NULL)
sh_flags                                00000000 (---)
sh_addr                                 00000000
sh_offset                               00020E2C
sh_size                                 00000000
sh_link                                 00000000
sh_info                                 00000000
sh_addralign                            00000004
sh_entsize                              00000000
 
Section Header #1
 
sh_name                                 00000001 (.shstrtab)
sh_type                                 00000003 (***_STRTAB)
sh_flags                                00000000 (---)
sh_addr                                 00000000
sh_offset                               00020E2C
sh_size                                 000000BB
sh_link                                 00000000
sh_info                                 00000000
sh_addralign                            00000004
sh_entsize                              00000000
 
Section Header #2
 
sh_name                                 0000000B (.strtab)
sh_type                                 00000003 (***_STRTAB)
sh_flags                                00000000 (---)
sh_addr                                 00000000
sh_offset                               00020EE8
sh_size                                 00002898
sh_link                                 00000000
sh_info                                 00000000
sh_addralign                            00000004
sh_entsize                              00000000
 
Section Header #3
 
sh_name                                 00000013 (.symtab)
sh_type                                 00000002 (***_SYMTAB)
sh_flags                                00000000 (---)
sh_addr                                 00000000
sh_offset                               00023780
sh_size                                 000024A0
sh_link                                 00000002
sh_info                                 000001C1
sh_addralign                            00000004
sh_entsize                              00000010
 
Section Header #4
 
sh_name                                 0000001B (P1 ro)
sh_type                                 00000001 (***_PROGBITS)
sh_flags                                00000007 (WAX)
sh_addr                                 20000004
sh_offset                               00000034
sh_size                                 00001C51
sh_link                                 00000000
sh_info                                 00000000
sh_addralign                            00000004
sh_entsize                              00000001
 
Section Header #5
 
sh_name                                 00000021 (P2 ro)
sh_type                                 00000001 (***_PROGBITS)
sh_flags                                00000002 (-A-)
sh_addr                                 20001C58
sh_offset                               00001C88
sh_size                                 000000C8
sh_link                                 00000000
sh_info                                 00000000
sh_addralign                            00000004
sh_entsize                              00000001
 
Section Header #6
 
sh_name                                 00000027 (.debug_abbrev)
sh_type                                 00000001 (***_PROGBITS)
sh_flags                                00000000 (---)
sh_addr                                 00000000
sh_offset                               00001D50
sh_size                                 000005F0
sh_link                                 00000000
sh_info                                 00000000
sh_addralign                            00000000
sh_entsize                              00000001
...