Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 22032

(Cortex M4) Bad section alignment in ELF file

$
0
0

we have a strange issue on a Cortex M4 MCU. The compiled Firmware works if the binary is loaded with ST-LINK in the correct section, but using C-Lion and OpenOcd, The FW load operation, load also the ELF header in FLASH and corrupt a Flags Area used by a bootloader.

The MCU Flash is 512 kB - 256 pages total (2kB for page), with the following layout:

+-------- 0x0800 0000 - FLASH_BASE -------------------------+| Bootloader partition                                      ||                                                           |+-------- FLAGS_ADDR  0x0800 5000 --------------------------+| 1 page Flags page                                         |+-------- APP_ADDR 0x0800 5800 -----------------------------+|                                                           || (APP_NUMPAGES) Application partition                      ||                                                           |+-------- BAK_ADDR -----------------------------------------+|                                                           || (APP_NUMPAGES) Application backup                         ||                                                           |+-------- NEW_ADDR -----------------------------------------+|                                                           || (APP_NUMPAGES) Update partition                           ||                                                           |+-----------------------------------------------------------+

The App FW has to be loaded starting from 0x0800 8500, that's true loading the .bin with ST-LINK, but loading the FW in C-Lion the code is correctly loaded starting from 0x0800 8500, but also incorrectly the header of ELF file is loaded at 0x0800 5000.

Analyzing the ELF file with readelf, shown the following information:

Section Headers:  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al  [ 0]                   NULL            00000000 000000 000000 00      0   0  0  [ 1] .isr_vector       PROGBITS        08005800 000800 000194 00   A  0   0  1  [ 2] .build_info       PROGBITS        08005994 000994 0000a4 00   A  0   0  4  [ 3] .text             PROGBITS        08005a40 000a40 01f698 00  AX  0   0 16  [ 4] .rodata           PROGBITS        080250d8 0200d8 002540 00   A  0   0  4  [ 5] .ARM.extab        PROGBITS        08027618 024398 000000 00   W  0   0  1  [ 6] .ARM              ARM_EXIDX       08027618 022618 000008 00  AL  3   0  4  [ 7] .preinit_array    PREINIT_ARRAY   08027620 024398 000000 04  WA  0   0  1  [ 8] .init_array       INIT_ARRAY      08027620 022620 000038 04  WA  0   0  4  [ 9] .fini_array       FINI_ARRAY      08027658 022658 000008 04  WA  0   0  4  [10] .data             PROGBITS        20000000 023000 001398 00  WA  0   0  8  [11] .bss              NOBITS          20001398 024398 00f740 00  WA  0   0  8  [12] ._user_heap_stack NOBITS          20010ad8 024398 002000 00  WA  0   0  1  [13] .ARM.attributes   ARM_ATTRIBUTES  00000000 024398 000030 00      0   0  1  [14] .comment          PROGBITS        00000000 0243c8 000039 01  MS  0   0  1  [15] .debug_info       PROGBITS        00000000 024401 1f27e9 00      0   0  1  [16] .debug_abbrev     PROGBITS        00000000 216bea 020d3e 00      0   0  1  [17] .debug_aranges    PROGBITS        00000000 237928 00cc90 00      0   0  8  [18] .debug_rnglists   PROGBITS        00000000 2445b8 009c3c 00      0   0  1  [19] .debug_line       PROGBITS        00000000 24e1f4 06ef95 00      0   0  1  [20] .debug_str        PROGBITS        00000000 2bd189 1d4157 01  MS  0   0  1  [21] .debug_frame      PROGBITS        00000000 4912e0 03a014 00      0   0  4  [22] .debug_line_str   PROGBITS        00000000 4cb2f4 0001bc 01  MS  0   0  1  [23] .debug_loclists   PROGBITS        00000000 4cb4b0 001e9b 00      0   0  1  [24] .symtab           SYMTAB          00000000 4cd34c 00f260 10     25 2637  4  [25] .strtab           STRTAB          00000000 4dc5ac 01f90f 00      0   0  1  [26] .shstrtab         STRTAB          00000000 4fbebb 00012b 00      0   0  1Key to Flags:  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),  L (link order), O (extra OS processing required), G (group), T (TLS),  C (compressed), x (unknown), o (OS specific), E (exclude),  D (mbind), y (purecode), p (processor specific)There are no section groups in this file.Program Headers:  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align  LOAD           0x000000 0x08005000 0x08005000 0x22660 0x22660 RWE 0x1000  LOAD           0x023000 0x20000000 0x08027660 0x01398 0x01398 RW  0x1000  LOAD           0x000398 0x20001398 0x20001398 0x00000 0x11740 RW  0x1000 Section to Segment mapping:  Segment Sections...   00     .isr_vector .build_info .text .rodata .ARM .init_array .fini_array   01     .data   02     .bss ._user_heap_stackThere is no dynamic section in this file.

It seams that the linker try to align the code to 4kB and not to 2kB.There is a way to force the linker to align the code to 2kB?

The same linkerscript is used to compile FW for a CortexM7 processor, with 2MB of Flash and a different Flash partition, in this case the Flash partition is compatible with 4kB alignment.

Section Headers:  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al  [ 0]                   NULL            00000000 000000 000000 00      0   0  0  [ 1] .isr_vector       PROGBITS        08040000 001000 0001f8 00   A  0   0  1  [ 2] .build_info       PROGBITS        080401f8 0011f8 000098 00   A  0   0  4  [ 3] .text             PROGBITS        08040290 001290 0939d8 00  AX  0   0 16  [ 4] .rodata           PROGBITS        080d3c68 094c68 025f18 00   A  0   0  8  [ 5] .ARM.extab        PROGBITS        080f9b80 0beea0 000000 00   W  0   0  1  [ 6] .ARM              ARM_EXIDX       080f9b80 0bab80 000008 00  AL  3   0  4  [ 7] .preinit_array    PREINIT_ARRAY   080f9b88 0beea0 000000 04  WA  0   0  1  [ 8] .init_array       INIT_ARRAY      080f9b88 0bab88 000070 04  WA  0   0  4  [ 9] .fini_array       FINI_ARRAY      080f9bf8 0babf8 000008 04  WA  0   0  4  [10] .data             PROGBITS        20000000 0bb000 003ea0 00  WA  0   0  8  [11] .dma              NOBITS          20078000 0bf000 0030a0 00  WA  0   0  4  [12] .bss              NOBITS          20003ea0 0beea0 03fca0 00  WA  0   0  8  [13] ._user_heap_stack NOBITS          20043b40 0beea0 004800 00  WA  0   0  1  [14] .ARM.attributes   ARM_ATTRIBUTES  00000000 0beea0 00002e 00      0   0  1  [15] .comment          PROGBITS        00000000 0beece 0000a9 01  MS  0   0  1  [16] .debug_info       PROGBITS        00000000 0bef77 b262bd 00      0   0  1  [17] .debug_abbrev     PROGBITS        00000000 be5234 063c2c 00      0   0  1  [18] .debug_aranges    PROGBITS        00000000 c48e60 02be48 00      0   0  8  [19] .debug_rnglists   PROGBITS        00000000 c74ca8 025d1f 00      0   0  1  [20] .debug_line       PROGBITS        00000000 c9a9c7 168d5a 00      0   0  1  [21] .debug_str        PROGBITS        00000000 e03721 1d9a755 01  MS  0   0  1  [22] .debug_frame      PROGBITS        00000000 2b9de78 0ca8ac 00      0   0  4  [23] .debug_line_str   PROGBITS        00000000 2c68724 0001c9 01  MS  0   0  1  [24] .debug_loclists   PROGBITS        00000000 2c688ed 05e172 00      0   0  1  [25] .debug_loc        PROGBITS        00000000 2cc6a5f 0002dd 00      0   0  1  [26] .debug_ranges     PROGBITS        00000000 2cc6d3c 000030 00      0   0  1  [27] .symtab           SYMTAB          00000000 2cc6d6c 05bbf0 10     28 15989  4  [28] .strtab           STRTAB          00000000 2d2295c 240e77 00      0   0  1  [29] .shstrtab         STRTAB          00000000 2f637d3 000149 00      0   0  1Key to Flags:  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),  L (link order), O (extra OS processing required), G (group), T (TLS),  C (compressed), x (unknown), o (OS specific), E (exclude),  D (mbind), y (purecode), p (processor specific)There are no section groups in this file.Program Headers:  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align  LOAD           0x001000 0x08040000 0x08040000 0xb9c00 0xb9c00 RWE 0x1000  LOAD           0x0bb000 0x20000000 0x080f9c00 0x03ea0 0x03ea0 RW  0x1000  LOAD           0x000ea0 0x20003ea0 0x20003ea0 0x00000 0x444a0 RW  0x1000  LOAD           0x000000 0x20078000 0x20078000 0x00000 0x030a0 RW  0x1000 Section to Segment mapping:  Segment Sections...   00     .isr_vector .build_info .text .rodata .ARM .init_array .fini_array   01     .data   02     .bss ._user_heap_stack   03     .dmaThere is no dynamic section in this file.

The linker script is the following, with a different definition for Cortex M4 or Cortex M7:

INCLUDE "hw_linkerdefs.ld"/* Entry Point */ENTRY(Reset_Handler)/* Highest address of the user mode stack */_estack = _LINKER_StartStack;    /* end of RAM *//* Generate a link error if heap and stack don't fit into RAM */_Min_Heap_Size = _LINKER_Min_Heap_Size;      /* required amount of heap  */_Min_Stack_Size = _LINKER_Min_Stack_Size; /* required amount of stack */_heap_upper_limit = _estack - _LINKER_Min_Stack_Size;_dmaAreaStart     = _LINKER_DMA_AREASTART;/* Specify the memory areas *//* ensure consistency to SCB->VTOR defined in system_stm32l4xx.c *//* IMAGETYPE is replaced by cmake into either APP or BOOT*/MEMORY{RAM (xrw)      : ORIGIN = _LINKER_RAM_BASEADDR,            LENGTH = _LINKER_RAM_SIZEFLASH (rx)     : ORIGIN = _LINKER_APP_FLASHSTART, LENGTH = _LINKER_APP_FLASHSIZEFLAGSAREA (r)  : ORIGIN = FLAGS_ADDR,                      LENGTH = 1024 DMARAM (rw)    : ORIGIN = _LINKER_DMA_AREASTART,           LENGTH = _LINKER_DMA_AREASIZE}/* Define output sections */SECTIONS{  /* The startup code goes first into FLASH */  .isr_vector :  {    . = ALIGN(8);    KEEP(*(.isr_vector)) /* Startup code */    . = ALIGN(8);  } >FLASH  /* This is the area reserved for build info */  .build_info :  {    . = ALIGN(8);    KEEP(*(.build_info_index))    *(.build_info_area)    . = ALIGN(8);  } > FLASH  /* The program code and other data goes into FLASH */  .text :  {    . = ALIGN(8);    *(.text)           /* .text sections (code) */    *(.text*)          /* .text* sections (code) */    *(.glue_7)         /* glue arm to thumb code */    *(.glue_7t)        /* glue thumb to arm code */    *(.eh_frame)    KEEP (*(.init))    KEEP (*(.fini))    . = ALIGN(8);    _etext = .;        /* define a global symbols at end of code */  } >FLASH  /* Constant data goes into FLASH */  .rodata :  {    . = ALIGN(8);    KEEP(*(*.uxTopUsedPriority))    *(.rodata)         /* .rodata sections (constants, strings, etc.) */    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */    . = ALIGN(8);  } >FLASH  .ARM.extab   :   {   . = ALIGN(8);  *(.ARM.extab* .gnu.linkonce.armextab.*)  . = ALIGN(8);  } >FLASH  .ARM : {    . = ALIGN(8);    __exidx_start = .;    *(.ARM.exidx*)    __exidx_end = .;    . = ALIGN(8);  } >FLASH  .preinit_array     :  {    . = ALIGN(8);    PROVIDE_HIDDEN (__preinit_array_start = .);    KEEP (*(.preinit_array*))    PROVIDE_HIDDEN (__preinit_array_end = .);    . = ALIGN(8);  } >FLASH  .init_array :  {    . = ALIGN(8);    PROVIDE_HIDDEN (__init_array_start = .);    KEEP (*(SORT(.init_array.*)))    KEEP (*(.init_array*))    PROVIDE_HIDDEN (__init_array_end = .);    . = ALIGN(8);  } >FLASH  .fini_array :  {    . = ALIGN(8);    PROVIDE_HIDDEN (__fini_array_start = .);    KEEP (*(SORT(.fini_array.*)))    KEEP (*(.fini_array*))    PROVIDE_HIDDEN (__fini_array_end = .);    . = ALIGN(8);  } >FLASH  /* used by the startup to initialize data */  _sidata = LOADADDR(.data);  /* Initialized data sections goes into RAM, load LMA copy after code */  .data :   {    . = ALIGN(8);    _sdata = .;        /* create a global symbol at data start */    *(.data)           /* .data sections */    *(.data*)          /* .data* sections */    . = ALIGN(8);    _edata = .;        /* define a global symbol at data end */  } >RAM AT> FLASH  /* This is only useful for the bootloader build in case it includes the default flags area */  .bootloader_default_flags :  {    KEEP(*(.bootloader_default_flags))  } > FLAGSAREA  /* this rule places the .dma buffers into the DMA area of RAM */  .dma (NOLOAD):  {    *(.dma)  } > DMARAM  /* Uninitialized data section */  . = ALIGN(4);  .bss :  {    /* This is used by the startup in order to initialize the .bss secion */    _sbss = .;         /* define a global symbol at bss start */    __bss_start__ = _sbss;    *(.bss)    *(.bss*)    *(COMMON)    . = ALIGN(4);    _ebss = .;         /* define a global symbol at bss end */    __bss_end__ = _ebss;  } >RAM  /* User_heap_stack section, used to check that there is enough RAM left */  ._user_heap_stack :  {    . = ALIGN(8);    PROVIDE ( _end_static_memory = . );    . = . + _Min_Heap_Size;    . = . + _Min_Stack_Size;    . = ALIGN(8);  } >RAM  /* Remove information from the standard libraries */  /DISCARD/ :  {    libc.a ( * )    libm.a ( * )    libgcc.a ( * )  }  .ARM.attributes 0 : { *(.ARM.attributes) }}

the code is copiled with xpack-arm-none-eabi-gcc-13.3.1-1.1 toolchanin.


Viewing all articles
Browse latest Browse all 22032

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>