0
votes

I have an issue during the linkage of my project. I use the GCC linker script from the manufacturer.

In there, i define the code section as follows:

MEMORY
{
  // .. deleted other sections
  CODE  (rx ) : ORIGIN = 0x0000B000, LENGTH = 0x00074000   /* 116 page(s) */
  // .. deleted other sections
}

so the code section beginning is located at 0xB000 and has a length of 0x74000. The length is 116 x 4096 bytes => 475136 bytes code size

my binary builds with the following size:

   text    data     bss     dec     hex filename
 432372       0  112048  522420   7f8b4 project.elf

therefore, it should link OK since the used size of 432372 (text + data) is way smaller than the available space of 475136.

it links ok as long as the binary code size is < ~422kBytes, as soon as it gets bigger, the linker tells me CODE section overflow, cannot link.

can someone explain me why not? i cannot see a reason for the link to tell me my code is too big, because it is not!

LINKER SCRIPT

MEMORY
{
  // ... removed sections here .. irelevant for discussion ...
  CODE  (rx ) : ORIGIN = 0x0000B000, LENGTH = 0x00074000   /* 116 page(s) */
  // ... removed sections here .. irelevant for discussion ...
  RAM                    (xrw) : ORIGIN = 0x20000040, LENGTH = 20000
  MEMORY_B1              (rx ) : ORIGIN = 0x60000000, LENGTH = 0K
}

/* The '__stack' definition is required by crt0, do not remove it            */
__stack = ORIGIN(RAM) + LENGTH(RAM);
_estack = __stack; 

__Main_Stack_Size = 2048 ;

PROVIDE ( _Main_Stack_Size = __Main_Stack_Size ) ;

__Main_Stack_Limit = __stack  - __Main_Stack_Size ;

/*"PROVIDE" allows to easily override these values from an object file or the command line. */
PROVIDE ( _Main_Stack_Limit = __Main_Stack_Limit ) ;

/*
 * There will be a link error if there is not this amount of 
 * RAM free at the end. 
 */
_Minimum_Stack_Size = 2048 ;

/*
 * Default heap definitions.
 * The heap start immediately after the last statically allocated 
 * .sbss/.noinit section, and extends up to the main stack limit.
 */
/*PROVIDE ( _Heap_Begin = _end_noinit ) ;  */
/*PROVIDE ( _Heap_Limit = _end_noinit ) ;   */

_Min_Heap_Size  = 0x100; /* required amount of heap  (256 bytes) */
_Min_Stack_Size = 0x400; /* required amount of stack (1kByte)    */

ENTRY(Reset_Handler)

SECTIONS
{
  .text :
  {
    KEEP(*(.vectors))
    __Vectors_End = .;
    __Vectors_Size = __Vectors_End - __Vectors;
    __end__ = .;

    *(.text*)

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

    /* .ctors */
    *crtbegin.o(.ctors)
    *crtbegin?.o(.ctors)
    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
    *(SORT(.ctors.*))
    *(.ctors)

    /* .dtors */
    *crtbegin.o(.dtors)
    *crtbegin?.o(.dtors)
    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
    *(SORT(.dtors.*))
    *(.dtors)

    *(.rodata*)

    KEEP(*(.eh_frame*))
  } > CODE

  .ARM.extab :
  {
    *(.ARM.extab* .gnu.linkonce.armextab.*)
  } > CODE

  __exidx_start = .;
  .ARM.exidx :
  {
    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
  } > CODE
  __exidx_end = .;

  /* To copy multiple ROM to RAM sections,
   * uncomment .copy.table section and,
   * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
  /*
  .copy.table :
  {
    . = ALIGN(4);
    __copy_table_start__ = .;
    LONG (__etext)
    LONG (__data_start__)
    LONG (__data_end__ - __data_start__)
    LONG (__etext2)
    LONG (__data2_start__)
    LONG (__data2_end__ - __data2_start__)
    __copy_table_end__ = .;
  } > CODE
  */

  /* To clear multiple BSS sections,
   * uncomment .zero.table section and,
   * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
  /*
  .zero.table :
  {
    . = ALIGN(4);
    __zero_table_start__ = .;
    LONG (__bss_start__)
    LONG (__bss_end__ - __bss_start__)
    LONG (__bss2_start__)
    LONG (__bss2_end__ - __bss2_start__)
    __zero_table_end__ = .;
  } > CODE
  */

  __etext = .;

  .data : AT (__etext)
  {
    __data_start__ = .;
    *(vtable)
    *(.data*)
    . = ALIGN (4);
    *(.ram)

    . = ALIGN(4);
    /* preinit data */
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP(*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);

    . = ALIGN(4);
    /* init data */
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP(*(SORT(.init_array.*)))
    KEEP(*(.init_array))
    PROVIDE_HIDDEN (__init_array_end = .);

    . = ALIGN(4);
    /* finit data */
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP(*(SORT(.fini_array.*)))
    KEEP(*(.fini_array))
    PROVIDE_HIDDEN (__fini_array_end = .);

    KEEP(*(.jcr*))
    . = ALIGN(4);
    /* All data end */
    __data_end__ = .;

  } > RAM

  .bss :
  {
    . = ALIGN(4);
    __bss_start__ = .;
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
  } > RAM

  .heap (COPY):
  {
    __HeapBase = .;
    __end__ = .;
    end = __end__;
    _end = __end__;
    KEEP(*(.heap*))
    __HeapLimit = .;
  } > RAM

  /* .stack_dummy section doesn't contains any symbols. It is only
   * used for linker to calculate size of stack sections, and assign
   * values to stack symbols later */
  .stack_dummy (COPY):
  {
    KEEP(*(.stack*))
  } > RAM

  /* Set stack top to end of RAM, and stack limit move down by
   * size of stack_dummy section */
  __StackTop = ORIGIN(RAM) + LENGTH(RAM);
  __StackLimit = __StackTop - SIZEOF(.stack_dummy);
  PROVIDE(__stack = __StackTop);

  /* Check if data + heap + stack exceeds RAM limit */
  ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")

  /* Check if CODE usage exceeds CODE size */
  ASSERT( LENGTH(CODE) >= (__etext + SIZEOF(.data)), "CODE memory overflowed !")
}

at the last lines, i assert code size:

  /* Check if CODE usage exceeds CODE size */
  ASSERT( LENGTH(CODE) >= (__etext + SIZEOF(.data)), "CODE memory overflowed !")

__etext should be the actual size of text (code) usage, .data should be zero

1
you have not shown enough, how do you have a .bss in the binary? what does the entire linker script being used look like? what happens when you narrow it down to something that demonstrates the problem?old_timer
@old_timer (A) .bss is zero initialized ram section. therefore i have flash regions (text+data) and i have ram section (bss+data). data is value initialized ram. (B) what demonstation do you need? as i said, the issue occures when i add new code, and therefore the code size increases over approx. 422kBytes, then the linker "means" the code section does not fit into the flash section and aborts linkage. (C) linker script, see edited post aboveuser654789384
when I wrote that comment your linker script had no data nor bss definitions only code, but the question was going beyond what was mentioned. if you have a tools/linker script issue you could make it a 10 or 100 byte section and do the same demonstration with all the example code/data visible in the question.old_timer

1 Answers

2
votes

can someone explain me why not?

Just look into the linker script:

CODE (rx ) : ORIGIN = 0x0000B000, LENGTH = 0x00074000 /* 116 page(s) */

0x74000 hex is ‭475136‬ decimal, or 464KB.

__etext should be the actual size of text (code) usage, .data should be zero

Not according to the linker script. In the posted script, __etext is the end address of the code segment. Or simply the size of the code segment plus its start address (which is nonzero).

In other words, your last ASSERT() is coded wrong and bails out 0xB000 bytes too early. And 0x74000-0xB000 = 0x69000 (or ‭430080‬ decimal).