[arm-gnu] Link problem with new bare-metal EABI release
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[arm-gnu] Link problem with new bare-metal EABI release



Recently I've downloaded and installed new ARM EABI toolchain for Windows.

Now I've come across an unusual problem. In my linker script I define a section for stacks. There are 3 sections placed in RAM and they are defined as:

=======================================================================
   .data :
   {
      _data_start = .;
      PROVIDE(_data_start = _data_start);
      *(.data);
      . = ALIGN(4);
      *(.data.*);
      . = ALIGN(4);
      _data_end = .;
      PROVIDE(_data_end = _data_end);
   } > ram AT > rom

   .bss :
   {
      _bss_start = .;
      PROVIDE(_bss_start = _bss_start);
      *(.bss)
      . = ALIGN(4);
      *(.bss.*)
      . = ALIGN(4);
      *(COMMON)
      . = ALIGN(4);
      _bss_end = .;
      PROVIDE(_bss_end = _bss_end);
   } > ram

   .stack :
   {
      _stack_start = .;
      PROVIDE(_stack_start = _stack_start);

      _user_stack_start = .;
      PROVIDE(_user_stack_start = _user_stack_start);
      . += _user_stack_size;
      . = ALIGN(4);
      _user_stack_end = .;
      PROVIDE(_user_stack_end = _user_stack_end);

      _fiq_stack_start = .;
      PROVIDE(_fiq_stack_start = _fiq_stack_start);
      . += _fiq_stack_size;
      . = ALIGN(4);
      _fiq_stack_end = .;
      PROVIDE(_fiq_stack_end = _fiq_stack_end);

      _irq_stack_start = .;
      PROVIDE(_irq_stack_start = _irq_stack_start);
      . += _irq_stack_size;
      . = ALIGN(4);
      _irq_stack_end = .;
      PROVIDE(_irq_stack_end = _irq_stack_end);

      _supervisor_stack_start = .;
      PROVIDE(_supervisor_stack_start = _supervisor_stack_start);
      . += _supervisor_stack_size;
      . = ALIGN(4);
      _supervisor_stack_end = .;
      PROVIDE(_supervisor_stack_end = _supervisor_stack_end);

      _abort_stack_start = .;
      PROVIDE(_abort_stack_start = _abort_stack_start);
      . += _abort_stack_size;
      . = ALIGN(4);
      _abort_stack_end = .;
      PROVIDE(_abort_stack_end = _abort_stack_end);

      _undefined_stack_start = .;
      PROVIDE(_undefined_stack_start = _undefined_stack_start);
      . += _undefined_stack_size;
      . = ALIGN(4);
      _undefined_stack_end = .;
      PROVIDE(_undefined_stack_end = _undefined_stack_end);

      _system_stack_start = .;
      PROVIDE(_system_stack_start = _system_stack_start);
      . += _system_stack_size;
      . = ALIGN(4);
      _system_stack_end = .;
      PROVIDE(_system_stack_end = _system_stack_end);

      _stack_end = .;
      PROVIDE(_stack_end = _stack_end);
   } > ram

   _end = .;
   PROVIDE(_end = _end);
=======================================================================

Everything works fine until I try to use malloc() or free(). I add a small part of code to the existing test application (just blinking the led in main loop):

=======================================================================
 uint32_t *ptr;
   uint32_t i;

   ptr=malloc(32*sizeof(uint32_t));

   for(i=0;i<32;i++)
      ptr[i]=i*17;

   free(ptr);
=======================================================================

(of course I also add _sbrk [pretty much identical to the one presented in manual] and required headers)

With malloc and free when I try to link I get:

=======================================================================
c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.3.3/../../../../arm-none-eabi/bin/ld.exe: section .stack [000015fc -> 00001613] overlaps section .bss [000015fc -> 00001637]
collect2: ld returned 1 exit status
=======================================================================

If I increase RAM size to 1M - still the same. If I try to move the "pointer" between .bss and .stack with ". += 0x100" - still the same. If I decrease the sizes of stacks to 1 (so 4 including alignment) byte - still the same.

Now here's the funny part. When I mix the sections in the linker file a bit everything works fine. Generally (.data .bss .stack) - fails, other combinations work, for example (.bss .data .stack).

During investigation I've found that the section .stack has its VMA different than LMA.

=======================================================================
Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000dbc  00000000  00000000  00008000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .bss          0000003c  40000000  40000000  00018000  2**2
                  ALLOC
  2 .data         00000840  40000040  00000dbc  00010040  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  3 .stack        00000280  40000880  000015fc  00010880  2**0
                  ALLOC
=======================================================================

So when I locate sections .bss and .stack with

   } > ram AT > ram

it also works. But this is rather a hack, not a clean solution...

Also when I compile the exactly same code with the initial order of sections (.data .bss .stack) - the one which fails in new CodeSourcery - with another toolchain, which is an older version of Yagarto (gcc 4.3.2, ld 2.18) it compiles fine, and LMA of .stack equals its VMA.

What am I doing wrong? What am I missing?

Thanks in advance for any help!

Regards!