0
votes

I'm building an embeeded software for STM32 microcontroller with the toolchain GNU Tools for STM32 and I need the binary output without gaps.

The linker produces a gap between sections .text and .rodata. The problem is the alignment of the section .rodata. The issue appears by using of the GNU Tools for STM32 version 9-2020-q2-update. The previous version I had used (7-2018-q2-update) did not produced that issue.

Excerpt from the linker script (it's the same for both GNU Tools versions):

SECTIONS
{
  .text :
  {
    . = ALIGN(4);
    *(.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(4); /* PaulV: change that to ALIGN(8) eliminates the gap */
  } >FLASH

  /* Constant data into "FLASH" Rom type memory */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH
}

More details:

The version 7-2018-q2-update produces the output without gap.

The .lst file (note that section .rodata is aligned to bound 4):

K4_G1.elf:     file format elf32-littlearm

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
          ....
  3 .text         0001a20c  08100800  08100800  00010800  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  4 .rodata       00009b54  0811aa0c  0811aa0c  0002aa0c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA

and .map file (no gap between the non-empty sections .fini and .rodata):

 .fini          0x000000000811aa04        0x8 c:/st/stm32cubeide_1.4.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.5.0.202011040924/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/fpv5/hard/crtn.o
                0x000000000811aa0c                . = ALIGN (0x4)
                0x000000000811aa0c                _etext = .

.vfp11_veneer   0x000000000811aa0c        0x0
 .vfp11_veneer  0x000000000811aa0c        0x0 linker stubs

.v4_bx          0x000000000811aa0c        0x0
 .v4_bx         0x000000000811aa0c        0x0 linker stubs

.iplt           0x000000000811aa0c        0x0
 .iplt          0x000000000811aa0c        0x0 c:/st/stm32cubeide_1.4.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.5.0.202011040924/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/fpv5/hard/crtbegin.o

.rodata         0x000000000811aa0c     0x9b54
                0x000000000811aa0c                . = ALIGN (0x4)
 *(.rodata)
 .rodata        0x000000000811aa0c       0x8c Src/app_composer/init.o

The version 9-2020-q2-update produces the output with gap.

The .lst file (note that section .rodata is aligned to bound 8, but why?):

K4_G1.elf:     file format elf32-littlearm

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
          ...
  3 .text         0001923c  08100800  08100800  00010800  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  4 .rodata       000061f0  08119a40  08119a40  00029a40  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA

and .map file (there is a gap between the non-empty sections .fini and .rodata):

 .fini          0x0000000008119a34        0x8 c:/st/stm32cubeide_1.4.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.9-2020-q2-update.win32_1.5.0.202011040924/tools/bin/../lib/gcc/arm-none-eabi/9.3.1/thumb/v7e-m+dp/hard/crtn.o

.vfp11_veneer   0x0000000008119a3c        0x0
 .vfp11_veneer  0x0000000008119a3c        0x0 linker stubs

.v4_bx          0x0000000008119a3c        0x0
 .v4_bx         0x0000000008119a3c        0x0 linker stubs

.iplt           0x0000000008119a3c        0x0
 .iplt          0x0000000008119a3c        0x0 c:/st/stm32cubeide_1.4.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.9-2020-q2-update.win32_1.5.0.202011040924/tools/bin/../lib/gcc/arm-none-eabi/9.3.1/thumb/v7e-m+dp/hard/crtbegin.o

.rodata         0x0000000008119a40     0x61f0
                0x0000000008119a40                . = ALIGN (0x4)
 *(.rodata)
 .rodata        0x0000000008119a40       0x96 Src/app_composer/init.o

Edit 03/16/2021

There are no sections *(.rodata) in the input object files having alignment on the boundary 8 or greater.

Changing the section name .rodata to the name .text eliminates the gap (The same result if I join the sections .text and .rodata content to a single .text section):

SECTIONS
{
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */

    /* ... */

    . = ALIGN(4);
  } >FLASH

  /* Constant data into "FLASH" Rom type memory */
  .text : /* <-- the same name as the previous section instead of .rodata */
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH
}

The source code and build settings are also the same for both variants.

What could be the reason for the problem and how could it be solved? Do I missing something?

P.S. Of cause I can change the alignment at the end of .text section to 8. That would be treating the symptoms, but I want to understand the cause.

Thanks in advance for your help!

1
the section names (before the colon) are arbitrary you can call them .bob and .ted instead of .text and .rodata, which also implies if you want this to be one chunk of stuff, then only have one section head. move the .rodata contents into the .text section get rid of all the other junk in there that you are not using (glue, etc...) - old_timer
what is the size of your .text now, what if you add or remove a few things, does the aligh 8 still "fix" it? - old_timer
@old_timer. You're right: if I "merge" the output sections .text and .rodata into the single .text output section, the gap disappers. I get the same result if I change the name.rodata to .text (having two "sections" .text in the linker script), That fix is still "treating the symptoms" for me, but is a good criteria to discriminate the reason: The input sections don't matter. - PaulV

1 Answers

0
votes

Run objdump -h on the input object files. I suspect that you will find that the compiler is putting a minimum alignment of 8 on one of the input .rodata sections. The linker then sets the output alignment to the maximum of the input sections.