Appending CRCs for STL flash test leads to broken ELF file
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-05-20 1:53 AM
Steps to reproduce
You can find the output files (ELF and bin) attached to this post. The steps to create them are as follows:
- Download and extract X-CUBE-CLASSB library for STM32H5, version 4.0.0
- Open the contained example project in STM32CubeIDE (we'll use the TrustZone one)
- Modify the secure application linker script to include a gap at the beginning (e.g. for MCUboot)
--- STM32CubeIDE/Secure/STM32H563ZITX_FLASH.ld.bak 2025-05-20 10:05:08.623676118 +0200
+++ STM32CubeIDE/Secure/STM32H563ZITX_FLASH.ld 2025-05-20 10:05:13.813692793 +0200
@@ -46,7 +46,7 @@
MEMORY
{
RAM (xrw) : ORIGIN = 0x30000000, LENGTH = 320K /* SRAM1 + SRAM2 */
- FLASH (rx) : ORIGIN = 0x0C000000, LENGTH = 1016K
+ FLASH (rx) : ORIGIN = 0x0C008400, LENGTH = 983K
FLASH_NSC (rx) : ORIGIN = 0x0C0FE000, LENGTH = 8K
}
- Change the post-build step to (STL_Single_Tests_Nucleo_H563ZI_Secure -> Properties -> C/C++ Build -> Setting -> Build Steps) make a backup copy and correctly call the programmer with the new address. Example below is for a Linux environment, change accordingly for Windows. Alternatively, remove the post-build step and run the commands manually from a terminal.
cp "${BuildArtifactFileBaseName}.elf" "${BuildArtifactFileBaseName}-nocrc.elf" && arm-none-eabi-size "${BuildArtifactFileName}" && STM32_Programmer_CLI -sl \"${CWD}/${BuildArtifactFileName}\" 0x0C008400 0x0C100000 0x400 && arm-none-eabi-objcopy -O binary "${BuildArtifactFileBaseName}.elf" "{BuildArtifactFileBaseName}.bin" && arm-none-eabi-objcopy -O binary "${BuildArtifactFileBaseName}-nocrc.elf" "{BuildArtifactFileBaseName}-nocrc.bin"
Expected behavior
Output ELF file is modified with new CRC section and is otherwise unmodified. Output bin file contains the new additional CRC section and is otherwise the same.
Actual behavior
New CRC section is present, but all offsets in the ELF are shifted which leads to objcopy not correctly producing the binary files. Especially the .data section gets prominently moved. The STM32CubeProgrammer seems to start all sections directly after the ELF header, even though a gap is required in this case. Probably the easiest way to compare the ELF files is to compare the output of "readelf --wide -e -l <elf file>".
If you compare the resulting bin files with and without CRCs, e.g. using a hex editor, you can clearly see the .data section not being at the expected 0x3ff8 offset, but at offset 0x43c4 (0x3cc bytes offset, which is exactly the shift that happened in the ELF file).
Running objcopy plainly on the new ELF file with CRCs (arm-none-eabi-objcopy STL_Single_Tests_Nucleo_H563ZI_Secure.elf STL_Single_Tests_Nucleo_H563ZI_Secure-new.elf) adjusts a lot of broken load addresses, but sadly not all of them, especially not .data.
arm-none-eabi-objcopy: STM32CubeIDE/Secure/Debug/STL_Single_Tests_Nucleo_H563ZI_Secure-new.elf: section .isr_vector lma 0xc008034 adjusted to 0xc008400
arm-none-eabi-objcopy: STM32CubeIDE/Secure/Debug/STL_Single_Tests_Nucleo_H563ZI_Secure-new.elf: section .text lma 0xc008284 adjusted to 0xc008650
arm-none-eabi-objcopy: STM32CubeIDE/Secure/Debug/STL_Single_Tests_Nucleo_H563ZI_Secure-new.elf: section .rodata lma 0xc00bab8 adjusted to 0xc00be84
arm-none-eabi-objcopy: STM32CubeIDE/Secure/Debug/STL_Single_Tests_Nucleo_H563ZI_Secure-new.elf: section mydata lma 0xc00c018 adjusted to 0xc00c3e4
arm-none-eabi-objcopy: STM32CubeIDE/Secure/Debug/STL_Single_Tests_Nucleo_H563ZI_Secure-new.elf: section .preinit_array lma 0xc00c024 adjusted to 0xc00c3f0
arm-none-eabi-objcopy: STM32CubeIDE/Secure/Debug/STL_Single_Tests_Nucleo_H563ZI_Secure-new.elf: section .init_array lma 0xc00c024 adjusted to 0xc00c3f0
arm-none-eabi-objcopy: STM32CubeIDE/Secure/Debug/STL_Single_Tests_Nucleo_H563ZI_Secure-new.elf: section .fini_array lma 0xc00c028 adjusted to 0xc00c3f4
Concerning objcopy, this is how the LMA gets calculated (see _bfd_elf_make_section_from_shdr function in bfd/elf.c in binutils-gdb):
newsect->lma = (phdr->p_paddr + hdr->sh_offset - phdr->p_offset) / opb;
Crucially, it uses the section header offset (offset of binary data in the ELF file itself) to calculate the LMA which is then used to place the section in the output bin file. It expects the sections to be placed in the ELF file in relation to the physical address stored in the program header.
Due to this issue, using the STM32CubeProgrammer to generate CRCs for the STL in ELF files is currently not viable in more complex environments.
- Labels:
-
Bug-report
-
STM32CubeProgrammer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-05-22 7:30 AM
Hello, thank you for your very detailed description and thorough analysis. This problem is currently known and is being worked on (ST internal bug tracker no. 205095).
