assemblygccarmstm32ld

Why is the GCC Linker placing 8 bytes of space in-between these two sections?


My overall goal is to be able to calculate a checksum using the on chip CRC peripheral so that I can verify that the binary was correctly flashed to the board. I've got a working python script which just copies exactly what the CRC peripheral is doing, which I then feed the .bin file to get a checksum from.

In trying to get my script working I've noticed that there are 8 bytes of space in between the .isr_vector section and the .text section that is not matching up between the flashed memory and the binary itself. When debugging on the chip these 8 bytes are all 0xFF but in the binary they are 0x00. I know that the chip defaults to all 1s so I have a vague idea why the two are different (or at least I think I do), but I don't know why that space is even there to begin with.

I spent the better part of yesterday evening playing with the linker script, moving the alignment flags around and playing with the fill/padding values. Using "FILL(0xFF);" does not effect that space, neither does putting "=0xFF" at the end of the section. The alignment flags do move things around but they don't have any effect on the space. I was able to get it filled (and also to finally verify my script matches the CRC peripheral) by putting "BYTE(0xFF);" 8 times at the end of the section, but that just looks like a hacky work around to me.

What is this space, why is it there, how do I get rid of it gracefully, will there be consequences for doing so?

My linker script with my hacky fix in it. If you remove lines 29-38 the "space" appears. This was originally generated by CubeIDE but I've been poking at it quite a bit since. This is my first meaningful foray into liker scripts so I may be doing things terribly wrong.

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM);    /* end of RAM */

/* Usedd to generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;  /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */

_code_size = SIZEOF(.isr_vector) + SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.ARM);
vector_size = SIZEOF(.isr_vector);

/* Specify the memory areas */
MEMORY
{
    RAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 32K
    FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
}

/* Define output sections */
SECTIONS
{
    /* The startup code goes first into FLASH */
    .isr_vector :
    {
        KEEP(*(.isr_vector)) /* Startup code */

        /* These are the 8 bytes that "fix" the problem, without these the space is filled with zeros */
        BYTE(0xFF);
        BYTE(0xFF);
        BYTE(0xFF);
        BYTE(0xFF);
        BYTE(0xFF);
        BYTE(0xFF);
        BYTE(0xFF);
        BYTE(0xFF);
    } >FLASH =0xEE

    /* The program code and other data goes into FLASH */
    .text : ALIGN(4)
    {
        BYTE(vector_size);
        *(.text)           /* .text sections (code) */
        *(.text*)          /* .text* sections (code) */

        KEEP (*(.init))
        KEEP (*(.fini))

        . = ALIGN(4);
        _etext = .;        /* define a global symbols at end of code */
    } >FLASH =0xEE

    /* Constant data goes into FLASH */
    .rodata : ALIGN(4)
    {
        *(.rodata)         /* .rodata sections (constants, strings, etc.) */
        *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    } >FLASH =0xEE

    .ARM (READONLY) : ALIGN(4)
    {
        __exidx_start = .;
        *(.ARM.exidx*)
        __exidx_end = .;
    } >FLASH =0xEE

    /* used by the startup to initialize data */
    _sidata = LOADADDR(.data);

    /* Initialized data sections goes into RAM, load LMA copy after code */
    .data : 
    {
        . = ALIGN(4);
        _sdata = .;        /* create a global symbol at data start */
        *(.data)           /* .data sections */
        *(.data*)          /* .data* sections */

        . = ALIGN(4);
        _edata = .;        /* define a global symbol at data end */
    } >RAM AT> FLASH

    
    /* 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 = . );
        PROVIDE ( _end = . );
        . = . + _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)
    }
}

Here is the start of my code, It's also mostly generated by CubeIDE with some minor modifications.

  .syntax unified
    .cpu cortex-m4
    .fpu softvfp
    .thumb

.global g_pfnVectors
.global Default_Handler

/* start address for the initialization values of the .data section.
defined in linker script */
.word   _sidata
/* start address for the .data section. defined in linker script */
.word   _sdata
/* end address for the .data section. defined in linker script */
.word   _edata
/* start address for the .bss section. defined in linker script */
.word   _sbss
/* end address for the .bss section. defined in linker script */
.word   _ebss

.equ  BootRAM,        0xF1E0F85F
/**
 * @brief  This is the code that gets called when the processor first
 *          starts execution following a reset event. Only the absolutely
 *          necessary set is performed, after which the application
 *          supplied main() routine is called.
 * @param  None
 * @retval : None
*/

    .section    .text.Reset_Handler
    .weak   Reset_Handler
    .type   Reset_Handler, %function
Reset_Handler:
  ldr   r0, =_estack
  mov   sp, r0          /* set stack pointer */
  
/* Call the clock system initialization function.*/
  bl  SystemInit

/* Copy the data segment initializers from flash to SRAM */
  ldr r0, =_sdata
  ldr r1, =_edata
  ldr r2, =_sidata
  movs r3, #0
  b LoopCopyDataInit

CopyDataInit:
  ldr r4, [r2, r3]
  str r4, [r0, r3]
  adds r3, r3, #4

LoopCopyDataInit:
  adds r4, r0, r3
  cmp r4, r1
  bcc CopyDataInit
  
/* Zero fill the bss segment. */
  ldr r2, =_sbss
  ldr r4, =_ebss
  movs r3, #0
  b LoopFillZerobss

FillZerobss:
  str  r3, [r2]
  adds r2, r2, #4

LoopFillZerobss:
  cmp r2, r4
  bcc FillZerobss
/* Call static constructors */
  bl __libc_init_array
/* Call the application's entry point.*/
  bl    main

LoopForever:
  b LoopForever

.size   Reset_Handler, .-Reset_Handler

/**
 * @brief  This is the code that gets called when the processor receives an
 *         unexpected interrupt.  This simply enters an infinite loop, preserving
 *         the system state for examination by a debugger.
 *
 * @param  None
 * @retval : None
*/
    .section    .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
    b   Infinite_Loop
    .size   Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex-M4.  Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
    .section    .isr_vector,"a",%progbits
    .type   g_pfnVectors, %object


g_pfnVectors:
    .word   _estack
    .word   Reset_Handler
    .word   NMI_Handler
    .word   HardFault_Handler
    .word   MemManage_Handler
    .word   BusFault_Handler
    .word   UsageFault_Handler
    .word   0
    .word   0
    .word   0
    .word   0
    .word   SVC_Handler
    .word   DebugMon_Handler
    .word   0
    .word   PendSV_Handler
    .word   SysTick_Handler
    .word   WWDG_IRQHandler
    .word   PVD_PVM_IRQHandler
    .word   RTC_TAMP_LSECSS_IRQHandler
    .word   RTC_WKUP_IRQHandler
    .word   FLASH_IRQHandler
    .word   RCC_IRQHandler
    .word   EXTI0_IRQHandler
    .word   EXTI1_IRQHandler
    .word   EXTI2_IRQHandler
    .word   EXTI3_IRQHandler
    .word   EXTI4_IRQHandler
    .word   DMA1_Channel1_IRQHandler
    .word   DMA1_Channel2_IRQHandler
    .word   DMA1_Channel3_IRQHandler
    .word   DMA1_Channel4_IRQHandler
    .word   DMA1_Channel5_IRQHandler
    .word   DMA1_Channel6_IRQHandler
    .word   0
    .word   ADC1_2_IRQHandler
    .word   USB_HP_IRQHandler
    .word   USB_LP_IRQHandler
    .word   can_isr
    .word   can_isr
    .word   EXTI9_5_IRQHandler
    .word   TIM1_BRK_TIM15_IRQHandler
    .word   TIM1_UP_TIM16_IRQHandler
    .word   TIM1_TRG_COM_TIM17_IRQHandler
    .word   TIM1_CC_IRQHandler
    .word   TIM2_IRQHandler
    .word   TIM3_IRQHandler
    .word   TIM4_IRQHandler
    .word   I2C1_EV_IRQHandler
    .word   I2C1_ER_IRQHandler
    .word   I2C2_EV_IRQHandler
    .word   I2C2_ER_IRQHandler
    .word   SPI1_IRQHandler
    .word   SPI2_IRQHandler
    .word   USART1_IRQHandler
    .word   USART2_IRQHandler
    .word   USART3_IRQHandler
    .word   EXTI15_10_IRQHandler
    .word   RTC_Alarm_IRQHandler
    .word   USBWakeUp_IRQHandler
    .word   TIM8_BRK_IRQHandler
    .word   TIM8_UP_IRQHandler
    .word   TIM8_TRG_COM_IRQHandler
    .word   TIM8_CC_IRQHandler
    .word   0
    .word   0
    .word   LPTIM1_IRQHandler
    .word   0
    .word   SPI3_IRQHandler
    .word   UART4_IRQHandler
    .word   0
    .word   TIM6_DAC_IRQHandler
    .word   TIM7_IRQHandler
    .word   DMA2_Channel1_IRQHandler
    .word   DMA2_Channel2_IRQHandler
    .word   DMA2_Channel3_IRQHandler
    .word   DMA2_Channel4_IRQHandler
    .word   DMA2_Channel5_IRQHandler
    .word   0
    .word   0
    .word   UCPD1_IRQHandler
    .word   COMP1_2_3_IRQHandler
    .word   COMP4_IRQHandler
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   CRS_IRQHandler
    .word   SAI1_IRQHandler
    .word   0
    .word   0
    .word   0
    .word   0
    .word   FPU_IRQHandler
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   RNG_IRQHandler
    .word   LPUART1_IRQHandler
    .word   I2C3_EV_IRQHandler
    .word   I2C3_ER_IRQHandler
    .word   DMAMUX_OVR_IRQHandler
    .word   0
    .word   0
    .word   DMA2_Channel6_IRQHandler
    .word   0
    .word   0
    .word   CORDIC_IRQHandler
    .word   FMAC_IRQHandler

    .size   g_pfnVectors, .-g_pfnVectors

/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/

    .weak   NMI_Handler
    .thumb_set NMI_Handler,Default_Handler

    .weak   HardFault_Handler
    .thumb_set HardFault_Handler,Default_Handler

    .weak   MemManage_Handler
    .thumb_set MemManage_Handler,Default_Handler

    .weak   BusFault_Handler
    .thumb_set BusFault_Handler,Default_Handler

    .weak   UsageFault_Handler
    .thumb_set UsageFault_Handler,Default_Handler

    .weak   SVC_Handler
    .thumb_set SVC_Handler,Default_Handler

    .weak   DebugMon_Handler
    .thumb_set DebugMon_Handler,Default_Handler

    .weak   PendSV_Handler
    .thumb_set PendSV_Handler,Default_Handler

    .weak   SysTick_Handler
    .thumb_set SysTick_Handler,Default_Handler

    .weak   WWDG_IRQHandler
    .thumb_set WWDG_IRQHandler,Default_Handler

    .weak   PVD_PVM_IRQHandler
    .thumb_set PVD_PVM_IRQHandler,Default_Handler

    .weak   RTC_TAMP_LSECSS_IRQHandler
    .thumb_set RTC_TAMP_LSECSS_IRQHandler,Default_Handler

    .weak   RTC_WKUP_IRQHandler
    .thumb_set RTC_WKUP_IRQHandler,Default_Handler

    .weak   FLASH_IRQHandler
    .thumb_set FLASH_IRQHandler,Default_Handler

    .weak   RCC_IRQHandler
    .thumb_set RCC_IRQHandler,Default_Handler

    .weak   EXTI0_IRQHandler
    .thumb_set EXTI0_IRQHandler,Default_Handler

    .weak   EXTI1_IRQHandler
    .thumb_set EXTI1_IRQHandler,Default_Handler

    .weak   EXTI2_IRQHandler
    .thumb_set EXTI2_IRQHandler,Default_Handler

    .weak   EXTI3_IRQHandler
    .thumb_set EXTI3_IRQHandler,Default_Handler

    .weak   EXTI4_IRQHandler
    .thumb_set EXTI4_IRQHandler,Default_Handler

    .weak   DMA1_Channel1_IRQHandler
    .thumb_set DMA1_Channel1_IRQHandler,Default_Handler

    .weak   DMA1_Channel2_IRQHandler
    .thumb_set DMA1_Channel2_IRQHandler,Default_Handler

    .weak   DMA1_Channel3_IRQHandler
    .thumb_set DMA1_Channel3_IRQHandler,Default_Handler

    .weak   DMA1_Channel4_IRQHandler
    .thumb_set DMA1_Channel4_IRQHandler,Default_Handler

    .weak   DMA1_Channel5_IRQHandler
    .thumb_set DMA1_Channel5_IRQHandler,Default_Handler

    .weak   DMA1_Channel6_IRQHandler
    .thumb_set DMA1_Channel6_IRQHandler,Default_Handler

    .weak   ADC1_2_IRQHandler
    .thumb_set ADC1_2_IRQHandler,Default_Handler

    .weak   USB_HP_IRQHandler
    .thumb_set USB_HP_IRQHandler,Default_Handler

    .weak   USB_LP_IRQHandler
    .thumb_set USB_LP_IRQHandler,Default_Handler

    .weak   can_isr
    .thumb_set can_isr,Default_Handler

    .weak   EXTI9_5_IRQHandler
    .thumb_set EXTI9_5_IRQHandler,Default_Handler

    .weak   TIM1_BRK_TIM15_IRQHandler
    .thumb_set TIM1_BRK_TIM15_IRQHandler,Default_Handler

    .weak   TIM1_UP_TIM16_IRQHandler
    .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler

    .weak   TIM1_TRG_COM_TIM17_IRQHandler
    .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler

    .weak   TIM1_CC_IRQHandler
    .thumb_set TIM1_CC_IRQHandler,Default_Handler

    .weak   TIM2_IRQHandler
    .thumb_set TIM2_IRQHandler,Default_Handler

    .weak   TIM3_IRQHandler
    .thumb_set TIM3_IRQHandler,Default_Handler

    .weak   TIM4_IRQHandler
    .thumb_set TIM4_IRQHandler,Default_Handler

    .weak   I2C1_EV_IRQHandler
    .thumb_set I2C1_EV_IRQHandler,Default_Handler

    .weak   I2C1_ER_IRQHandler
    .thumb_set I2C1_ER_IRQHandler,Default_Handler

    .weak   I2C2_EV_IRQHandler
    .thumb_set I2C2_EV_IRQHandler,Default_Handler

    .weak   I2C2_ER_IRQHandler
    .thumb_set I2C2_ER_IRQHandler,Default_Handler

    .weak   SPI1_IRQHandler
    .thumb_set SPI1_IRQHandler,Default_Handler

    .weak   SPI2_IRQHandler
    .thumb_set SPI2_IRQHandler,Default_Handler

    .weak   USART1_IRQHandler
    .thumb_set USART1_IRQHandler,Default_Handler

    .weak   USART2_IRQHandler
    .thumb_set USART2_IRQHandler,Default_Handler

    .weak   USART3_IRQHandler
    .thumb_set USART3_IRQHandler,Default_Handler

    .weak   EXTI15_10_IRQHandler
    .thumb_set EXTI15_10_IRQHandler,Default_Handler

    .weak   RTC_Alarm_IRQHandler
    .thumb_set RTC_Alarm_IRQHandler,Default_Handler

    .weak   USBWakeUp_IRQHandler
    .thumb_set USBWakeUp_IRQHandler,Default_Handler

    .weak   TIM8_BRK_IRQHandler
    .thumb_set TIM8_BRK_IRQHandler,Default_Handler

    .weak   TIM8_UP_IRQHandler
    .thumb_set TIM8_UP_IRQHandler,Default_Handler

    .weak   TIM8_TRG_COM_IRQHandler
    .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler

    .weak   TIM8_CC_IRQHandler
    .thumb_set TIM8_CC_IRQHandler,Default_Handler

    .weak   LPTIM1_IRQHandler
    .thumb_set LPTIM1_IRQHandler,Default_Handler

    .weak   SPI3_IRQHandler
    .thumb_set SPI3_IRQHandler,Default_Handler

    .weak   UART4_IRQHandler
    .thumb_set UART4_IRQHandler,Default_Handler

    .weak   TIM6_DAC_IRQHandler
    .thumb_set TIM6_DAC_IRQHandler,Default_Handler

    .weak   TIM7_IRQHandler
    .thumb_set TIM7_IRQHandler,Default_Handler

    .weak   DMA2_Channel1_IRQHandler
    .thumb_set DMA2_Channel1_IRQHandler,Default_Handler

    .weak   DMA2_Channel2_IRQHandler
    .thumb_set DMA2_Channel2_IRQHandler,Default_Handler

    .weak   DMA2_Channel3_IRQHandler
    .thumb_set DMA2_Channel3_IRQHandler,Default_Handler

    .weak   DMA2_Channel4_IRQHandler
    .thumb_set DMA2_Channel4_IRQHandler,Default_Handler

    .weak   DMA2_Channel5_IRQHandler
    .thumb_set DMA2_Channel5_IRQHandler,Default_Handler

    .weak   UCPD1_IRQHandler
    .thumb_set UCPD1_IRQHandler,Default_Handler

    .weak   COMP1_2_3_IRQHandler
    .thumb_set COMP1_2_3_IRQHandler,Default_Handler

    .weak   COMP4_IRQHandler
    .thumb_set COMP4_IRQHandler,Default_Handler

    .weak   CRS_IRQHandler
    .thumb_set CRS_IRQHandler,Default_Handler

    .weak   SAI1_IRQHandler
    .thumb_set SAI1_IRQHandler,Default_Handler

    .weak   FPU_IRQHandler
    .thumb_set FPU_IRQHandler,Default_Handler

    .weak   RNG_IRQHandler
    .thumb_set RNG_IRQHandler,Default_Handler

    .weak   LPUART1_IRQHandler
    .thumb_set LPUART1_IRQHandler,Default_Handler

    .weak   I2C3_EV_IRQHandler
    .thumb_set I2C3_EV_IRQHandler,Default_Handler

    .weak   I2C3_ER_IRQHandler
    .thumb_set I2C3_ER_IRQHandler,Default_Handler

    .weak   DMAMUX_OVR_IRQHandler
    .thumb_set DMAMUX_OVR_IRQHandler,Default_Handler

    .weak   DMA2_Channel6_IRQHandler
    .thumb_set DMA2_Channel6_IRQHandler,Default_Handler

    .weak   CORDIC_IRQHandler
    .thumb_set CORDIC_IRQHandler,Default_Handler

    .weak   FMAC_IRQHandler
    .thumb_set FMAC_IRQHandler,Default_Handler

A screencap of the binary opened in hex view. Line 1D8 contains the space that I'm complaining about. Without the 8 "BYTE(0xFF)" instructions this appears as all zeros.

I'm using MSYS2 GCC version 14.1.0 to compile and link for an STMG4 MCU.

I'm using make to build, the command make is running to link is:

gcc -O0 -g3 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -Wall -MMD -fdata-sections -ffunction-sections ${INCLUDE_FLAGS} -DSTM32G431xx -DUSE_HAL_DRIVER -T "${LINKER_SCRIPT}" --specs=nano.specs -Wl,-Map=${OUTPUT_DIR}${SOFTWARE_VERSION}.map -Wl,--gc-sections -Wl,--start-group -lc -lm -Wl,--end-group -Wl,-static ${addprefix ${OBJECT_DIR}, ${OBJECTS}} -o ${OUTPUT_DIR}${SOFTWARE_VERSION}.elf

This is the map file after removing practically all of the code aside from the startup assembly shown earlier, an empty main function, and an empty SystemInit function (called at line 40 of the startup assembly file). Something I did while removing all the other code seems to have fixed my problem, I still haven't figured out why quite yet though.

                0x20008000                        _estack = (ORIGIN (RAM) + LENGTH (RAM))
                0x00000200                        _Min_Heap_Size = 0x200
                0x00000400                        _Min_Stack_Size = 0x400
                0x000002ac                        _code_size = (((SIZEOF (.isr_vector) + SIZEOF (.text)) + SIZEOF (.rodata)) + SIZEOF (.ARM))
                0x000001d8                        vector_size = SIZEOF (.isr_vector)

.isr_vector     0x08000000      0x1d8
 *(.isr_vector)
 .isr_vector    0x08000000      0x1d8 build/obj/startup_stm32g431kbtx.o
                0x08000000                g_pfnVectors

.text           0x080001d8       0xd4
 *(.text)
 *(.text*)
 .text.__libc_init_array
                0x080001d8       0x48 C:\...d\libc_nano.a(libc_a-init.o)
                0x080001d8                __libc_init_array
 .text.main     0x08000220       0x10 build/obj/main.o
                0x08000220                main
 .text.SystemInit
                0x08000230        0xe build/obj/main.o
                0x08000230                SystemInit
 *fill*         0x0800023e        0x2 ee
 .text.Reset_Handler
                0x08000240       0x50 build/obj/startup_stm32g431kbtx.o
                0x08000240                Reset_Handler
 .text.Default_Handler
                0x08000290        0x2 build/obj/startup_stm32g431kbtx.o
                0x08000290                RTC_Alarm_IRQHandler
                0x08000290                EXTI2_IRQHandler
                0x08000290                TIM8_TRG_COM_IRQHandler
                0x08000290                TIM8_CC_IRQHandler
                0x08000290                DebugMon_Handler
                0x08000290                TIM1_CC_IRQHandler
                0x08000290                HardFault_Handler
                0x08000290                USB_HP_IRQHandler
                0x08000290                CORDIC_IRQHandler
                0x08000290                SysTick_Handler
                0x08000290                PendSV_Handler
                0x08000290                NMI_Handler
                0x08000290                EXTI3_IRQHandler
                0x08000290                I2C3_ER_IRQHandler
                0x08000290                EXTI0_IRQHandler
                0x08000290                I2C2_EV_IRQHandler
                0x08000290                FPU_IRQHandler
                0x08000290                TIM1_UP_TIM16_IRQHandler
                0x08000290                UsageFault_Handler
                0x08000290                ADC1_2_IRQHandler
                0x08000290                SPI1_IRQHandler
                0x08000290                TIM6_DAC_IRQHandler
                0x08000290                TIM8_UP_IRQHandler
                0x08000290                DMA2_Channel2_IRQHandler
                0x08000290                DMA1_Channel4_IRQHandler
                0x08000290                USART3_IRQHandler
                0x08000290                TIM4_IRQHandler
                0x08000290                DMA2_Channel1_IRQHandler
                0x08000290                I2C1_EV_IRQHandler
                0x08000290                DMA1_Channel6_IRQHandler
                0x08000290                UART4_IRQHandler
                0x08000290                DMA2_Channel4_IRQHandler
                0x08000290                TIM3_IRQHandler
                0x08000290                RCC_IRQHandler
                0x08000290                DMA1_Channel1_IRQHandler
                0x08000290                Default_Handler
                0x08000290                RTC_TAMP_LSECSS_IRQHandler
                0x08000290                FMAC_IRQHandler
                0x08000290                EXTI15_10_IRQHandler
                0x08000290                TIM7_IRQHandler
                0x08000290                UCPD1_IRQHandler
                0x08000290                I2C3_EV_IRQHandler
                0x08000290                EXTI9_5_IRQHandler
                0x08000290                RTC_WKUP_IRQHandler
                0x08000290                PVD_PVM_IRQHandler
                0x08000290                SPI2_IRQHandler
                0x08000290                MemManage_Handler
                0x08000290                can_isr
                0x08000290                SVC_Handler
                0x08000290                DMA2_Channel5_IRQHandler
                0x08000290                CRS_IRQHandler
                0x08000290                DMA1_Channel5_IRQHandler
                0x08000290                USB_LP_IRQHandler
                0x08000290                EXTI4_IRQHandler
                0x08000290                RNG_IRQHandler
                0x08000290                TIM1_TRG_COM_TIM17_IRQHandler
                0x08000290                DMA1_Channel3_IRQHandler
                0x08000290                WWDG_IRQHandler
                0x08000290                LPUART1_IRQHandler
                0x08000290                DMA2_Channel6_IRQHandler
                0x08000290                TIM2_IRQHandler
                0x08000290                COMP1_2_3_IRQHandler
                0x08000290                EXTI1_IRQHandler
                0x08000290                USART2_IRQHandler
                0x08000290                I2C2_ER_IRQHandler
                0x08000290                DMA1_Channel2_IRQHandler
                0x08000290                TIM8_BRK_IRQHandler
                0x08000290                FLASH_IRQHandler
                0x08000290                BusFault_Handler
                0x08000290                USART1_IRQHandler
                0x08000290                SPI3_IRQHandler
                0x08000290                I2C1_ER_IRQHandler
                0x08000290                LPTIM1_IRQHandler
                0x08000290                DMAMUX_OVR_IRQHandler
                0x08000290                USBWakeUp_IRQHandler
                0x08000290                SAI1_IRQHandler
                0x08000290                DMA2_Channel3_IRQHandler
                0x08000290                COMP4_IRQHandler
                0x08000290                TIM1_BRK_TIM15_IRQHandler
 *(.init)
 *fill*         0x08000292        0x2 ee
 .init          0x08000294        0x4 C:/.../crti.o
                0x08000294                _init
 .init          0x08000298        0x8 C:/.../crtn.o
 *(.fini)
 .fini          0x080002a0        0x4 C:/.../crti.o
                0x080002a0                _fini
 .fini          0x080002a4        0x8 C:/.../crtn.o
                0x080002ac                        . = ALIGN (0x4)
                0x080002ac                        _etext = .

.glue_7         0x080002ac        0x0
 .glue_7        0x080002ac        0x0 linker stubs

.glue_7t        0x080002ac        0x0
 .glue_7t       0x080002ac        0x0 linker stubs

.vfp11_veneer   0x080002ac        0x0
 .vfp11_veneer  0x080002ac        0x0 linker stubs

.v4_bx          0x080002ac        0x0
 .v4_bx         0x080002ac        0x0 linker stubs

.iplt           0x080002ac        0x0
 .iplt          0x080002ac        0x0 C:/...\libc_nano.a(libc_a-init.o)

.rel.dyn        0x080002ac        0x0
 .rel.iplt      0x080002ac        0x0 C:/...\libc_nano.a(libc_a-init.o)

.rodata
 *(.rodata)
 *(.rodata*)

.ARM            0x080002ac        0x0
                0x080002ac                        __exidx_start = .
 *(.ARM.exidx*)
                0x080002ac                        __exidx_end = .
                0x080002ac                        _sidata = LOADADDR (.data)

.data           0x20000000        0x0 load address 0x080002ac
                0x20000000                        . = ALIGN (0x4)
                0x20000000                        _sdata = .
 *(.data)
 *(.data*)
                0x20000000                        . = ALIGN (0x4)
                0x20000000                        _edata = .

.igot.plt       0x20000000        0x0 load address 0x080002ac
 .igot.plt      0x20000000        0x0 C:/...\libc_nano.a(libc_a-init.o)
                0x20000000                        . = ALIGN (0x4)

.bss            0x20000000        0x0 load address 0x080002ac
                0x20000000                        _sbss = .
                0x20000000                        __bss_start__ = _sbss
 *(.bss)
 *(.bss*)
 *(COMMON)
                0x20000000                        . = ALIGN (0x4)
                0x20000000                        _ebss = .
                0x20000000                        __bss_end__ = _ebss

._user_heap_stack
                0x20000000      0x600 load address 0x080002ac
                0x20000000                        . = ALIGN (0x8)
                [!provide]                        PROVIDE (end = .)
                [!provide]                        PROVIDE (_end = .)
                0x20000200                        . = (. + _Min_Heap_Size)
 *fill*         0x20000000      0x200 
                0x20000600                        . = (. + _Min_Stack_Size)
 *fill*         0x20000200      0x400 
                0x20000600                        . = ALIGN (0x8)

/DISCARD/
 libc.a(*)
 libm.a(*)
 libgcc.a(*)

.ARM.attributes
                0x00000000       0x30
 *(.ARM.attributes)
 .ARM.attributes
                0x00000000       0x22 C:/.../crti.o
 .ARM.attributes
                0x00000022       0x34 C:/...\libc_nano.a(libc_a-init.o)
 .ARM.attributes
                0x00000056       0x34 build/obj/main.o
 .ARM.attributes
                0x0000008a       0x21 build/obj/startup_stm32g431kbtx.o
 .ARM.attributes
                0x000000ab       0x22 C:/.../crtn.o
OUTPUT(build/VERSION0/VERSION0.elf elf32-littlearm)
LOAD linker stubs
LOAD C:/...\libc.a
LOAD C:/...\libm.a
LOAD C:/...\libgcc.a

.debug_frame    0x00000000       0x7c
 .debug_frame   0x00000000       0x2c C:/...\libc_nano.a(libc_a-init.o)
 .debug_frame   0x0000002c       0x50 build/obj/main.o

.debug_info     0x00000000       0x8a
 .debug_info    0x00000000       0x5a build/obj/main.o
 .debug_info    0x0000005a       0x30 build/obj/startup_stm32g431kbtx.o

.debug_abbrev   0x00000000       0x79
 .debug_abbrev  0x00000000       0x55 build/obj/main.o
 .debug_abbrev  0x00000055       0x24 build/obj/startup_stm32g431kbtx.o

.debug_aranges  0x00000000       0x50
 .debug_aranges
                0x00000000       0x28 build/obj/main.o
 .debug_aranges
                0x00000028       0x28 build/obj/startup_stm32g431kbtx.o

.debug_rnglists
                0x00000000       0x32
 .debug_rnglists
                0x00000000       0x19 build/obj/main.o
 .debug_rnglists
                0x00000019       0x19 build/obj/startup_stm32g431kbtx.o

.debug_macro    0x00000000      0xac9
 .debug_macro   0x00000000       0x1b build/obj/main.o
 .debug_macro   0x0000001b      0xaae build/obj/main.o

.debug_line     0x00000000       0xce
 .debug_line    0x00000000       0x53 build/obj/main.o
 .debug_line    0x00000053       0x7b build/obj/startup_stm32g431kbtx.o

.debug_str      0x00000000     0x2e0b
 .debug_str     0x00000000     0x2dcf build/obj/main.o
 .debug_str     0x00002dcf       0x3c build/obj/startup_stm32g431kbtx.o
                                 0x7c (size before relaxing)

.comment        0x00000000       0x43
 .comment       0x00000000       0x43 build/obj/main.o
                                 0x44 (size before relaxing)

.debug_line_str
                0x00000000       0x60
 .debug_line_str
                0x00000000       0x60 build/obj/startup_stm32g431kbtx.o

Solution

  • What is this space, why is it there, how do I get rid of it gracefully, will there be consequences for doing so?

    .text : ALIGN(4)

    This sets the section at a new address ALIGN(4). There is no data defined in between. When you output to a binary the fill of undefined space is 0x00 by default. If you created an 'ihex' or other output format, it would just skip the space.

    Something I did while removing all the other code seems to have fixed my problem, I still haven't figured out why quite yet though.

    If you alter the code so that isr_vector is aligned to 4, then there is no effective gap.

    There are multiple solutions.

    1. Ensure that the isr_vector is padded to the alignment of the following text section. You can use ALIGN (or FILL, but ALIGN does the math for you).
    2. Explicitly order the isr_vector code to be at the start of text and remove the isr_vector section. Functions should already have alignment by the compiler. Section alignment is another level.

    Bonus: The _user_heap_stack and _data have an . = ALIGN(8) and . = ALIGN(4) at the beginning. These do nothing. The linker file ._user_heap_stack:ALIGN(8) and .data:ALIGN(4) would accomplish the intent here.

    Related: