Title: (arm-none-eabi-gcc) creating .elf binary from bootloader + 2 x firmware image
Tags: gcc;arm;clion;elf;openocd
Question: I'm developing for a STM32F429 with CLion and trying to create a merged .elf file from three .elf files.
The layout of the merged .elf file should look like this:
Bootloader.elf    (maximum 256K, but can vary in size)
FirmwareImage.elf (always 384K, fills up allotted space for 1st firmware image)
FirmwareImage.elf (always 384K, fills up allotted space for 2nd firmware image)
This makes 1M exactly in total.
I've tried to converting the .elf files to .bin (with arm-none-eabi-objcopy) and creating a 1M .bin file with a custom tool I wrote. I can confirm the layout of the .bin this creates is correct.
I then convert the generated .bin file back to .elf with:
arm-none-eabi-objcopy -I binary -O elf32-little --change-section-address .data=0x08000000 in.bin out.elf
The data section address change is to reflect the start of flash memory in the STM32F429.
When I try to flash this file using openocd, it fails with:
Error: invalid ELF file, no program headers
Is there a way of skipping the .elfs -> .bin -> .elf conversion and go directly from .elfs -> .elf? Or otherwise, insert the program headers? I doubt these are actually used during flashing.
I know I could tell openocd to use the generated .bin file directly by specifing the flash address. But CLion won't let openocd flash .bin files from its arm-embedded plugin, only .elf files.
At the moment I'm using these linker scripts, adapted from ST's official one. There is quite a bit going on in them.
I might just be able to use a single linker script to achieve this. I could have the following code:
extern "C" __attribute__((__section__(".bootloader"))) void runBootloader()
Platform platform;
DFUBootloader bootloader(platform);
extern "C" __attribute__((__section__(".image1"))) void runApplication1()
Platform platform;
Application application(platform);
extern "C" __attribute__((__section__(".image2"))) void runApplication2()
Platform platform;
Application application(platform);
If these linker places these symbols at the right locations, would the symbols used by them end up in the correct place as well? The firmware image has to be duplicated to fill up both firmware pages, so all the symbols used by the application as well have to be duplicated.
Comment: @old_timer, is this what you mean with "as designed"?

Comment: posted answer and updated question to make it more obvious CLion was part of the problem

Comment: are these objects or the output of a linker?   why not just use the linker as designed

Comment: the job of a linker is to place things in the output binary at designated addresses, can you not do this at link time rather than after linking separate items then bringing them back together to try to link them again.  also why does the result need to be elf this is an MCU.


Here is another answer: It looks like merging multiple .elf files in the way I described is not possible, or at least not very trivial.
I have found a workaround for my problem trough. Although CLion is incapable getting openocd to flash .bin files (its builtin openocd launch command uses .elf), It's easy to create a custom CMake target that flashes the merged .bin with the following command:
openocd -f board/stm32f429discovery.cfg -c "program merged_image.bin exit 0x08000000"

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 4, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2020:00:04/01/20', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<gcc><arm><clion><elf><openocd>', 'Title': '(arm-none-eabi-gcc) creating .elf binary from bootloader + 2 x firmware image', 'ViewCount': 962, 'id': 60975745, 'user_AboutMe': None, 'user_AccountId': 10856575.0, 'user_DisplayName': 'Tim Walther', 'user_Reputation': 33.0, 'user_Views': 5.0, 'user_id': 12886484.0}}