title: Linker script .relocate section's first symbol, _srelocate, is incorrect (GCC Bug?)
body: <p><strong>Problem</strong></p>
  
  <p>My problem is that when I use the following script which is intended to place the Code into RAM the relocate section gets filled with bogus data.</p>
  
  <p><strong>My question is:</strong></p>
  
  <ol>
  <li><p>Why is the <code>_srelocate</code> symbol 4 bytes greater than the <code>_etext</code> symbol? Shouldn't they be the same?</p></li>
  <li><p>Also, if the answer to 1. is NO, shouldn't I be copying from <code>_etext + 4</code> to <code>_srelocate</code>?</p></li>
  </ol>
  
  <p><strong>Background and relevant code</strong></p>
  
  <p>I'm working with an Atmel ATSAM3N4X series processor (an ARM Cortex M3) and would like a little help with my linker script and <code>.relocate</code> section initialization.</p>
  
  <p>The reason for this is that the <code>_etext</code> symbol is 4 bytes less than the <code>_srelocate</code> symbol.</p>
  
  <p>The following linker script is the default script generated by Atmel Studio 6 (if you want the <code>ram</code>/<code>rom</code> symbol locations see the <strong>Apendix</strong> to the question).</p>
  
  <pre><code>/* ----------------------------------------------------------------------------
   *         SAM Software Package License
   * ----------------------------------------------------------------------------
   * Copyright (c) 2012, Atmel Corporation
   *
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are met:
   *
   * - Redistributions of source code must retain the above copyright notice,
   * this list of conditions and the disclaimer below.
   *
   * Atmel's name may not be used to endorse or promote products derived from
   * this software without specific prior written permission.
   *
   * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
   * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
   * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   * ----------------------------------------------------------------------------
   */
  
  /* Section Definitions */
  SECTIONS
  {
      .text :
      {
          . = ALIGN(4);
          _sfixed = .;
          KEEP(*(.vectors .vectors.*))
          *(.text .text.* .gnu.linkonce.t.*)
          *(.glue_7t) *(.glue_7)
          *(.rodata .rodata* .gnu.linkonce.r.*)
          *(.ARM.extab* .gnu.linkonce.armextab.*)
  
          /* Support C constructors, and C destructors in both user code
             and the C library. This also provides support for C++ code. */
          . = ALIGN(4);
          KEEP(*(.init))
          . = ALIGN(4);
          __preinit_array_start = .;
          KEEP (*(.preinit_array))
          __preinit_array_end = .;
  
          . = ALIGN(4);
          __init_array_start = .;
          KEEP (*(SORT(.init_array.*)))
          KEEP (*(.init_array))
          __init_array_end = .;
  
          . = ALIGN(0x4);
          KEEP (*crtbegin.o(.ctors))
          KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
          KEEP (*(SORT(.ctors.*)))
          KEEP (*crtend.o(.ctors))
  
          . = ALIGN(4);
          KEEP(*(.fini))
  
          . = ALIGN(4);
          __fini_array_start = .;
          KEEP (*(.fini_array))
          KEEP (*(SORT(.fini_array.*)))
          __fini_array_end = .;
  
          KEEP (*crtbegin.o(.dtors))
          KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
          KEEP (*(SORT(.dtors.*)))
          KEEP (*crtend.o(.dtors))
  
          . = ALIGN(4);
          _efixed = .;            /* End of text section */
      } &gt; ram
  
      . = ALIGN(4);
      _etext = .;
  
      .relocate : AT (_etext)
      {
          . = ALIGN(4);
          _srelocate = .;
          *(.ramfunc .ramfunc.*);
          *(.data .data.*);
          . = ALIGN(4);
          _erelocate = .;
      } &gt; ram
  
      /* .bss section which is used for uninitialized data */
      .bss (NOLOAD) :
      {
          . = ALIGN(4);
          _sbss = . ;
          _szero = .;
          *(.bss .bss.*)
          *(COMMON)
          . = ALIGN(4);
          _ebss = . ;
          _ezero = .;
      } &gt; ram
  
      /* stack section */
      .stack (NOLOAD):
      {
          . = ALIGN(8);
          _sstack = .;
          . = . + STACK_SIZE;
          . = ALIGN(8);
          _estack = .;
      } &gt; ram
  
      /* .ARM.exidx is sorted, so has to go in its own output section.  */
      PROVIDE_HIDDEN (__exidx_start = .);
      .ARM.exidx :
      {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
      } &gt; ram
      PROVIDE_HIDDEN (__exidx_end = .);
  
      . = ALIGN(4);
      _end = . ;
  }
  </code></pre>
  
  <p>I used <code>nm</code> to see what the symbol values were and I've included them below:</p>
  
  <pre><code>2000115c A _etext
  20001160 D _srelocate
  200015c8 D _erelocate
  </code></pre>
  
  <p>Now, Atmel Studio 6 auto-generated my project and gave me a <code>Reset_Handler()</code> that copies the <code>.relocate</code> section from <code>_etext</code> to <code>_srelocate</code> and clears the <code>.bss</code> section. The project came with two linker scripts, one for FLASH based execution and one for RAM based code. The default is the FLASH based code but I changed that to the RAM based linker script (provided above), and ran into the problem.</p>
  
  <p>The initialization code that copies the <code>.relocate</code> section from FLASH to RAM is also auto-generated and I haven't changed it when I changed linker scripts. It looks like this:</p>
  
  <pre><code>void Reset_Handler(void)
  {
      uint32_t *pSrc, *pDest, Size;
  
      /* Initialize the relocate segment */
      pSrc = &amp;_etext;
      pDest = &amp;_srelocate;
  
      if (pSrc != pDest) {
          for (; pDest &lt; &amp;_erelocate;) {
              *pDest++ = *pSrc++;
          }
      }
  
      /* Clear the zero segment */
      for (pDest = &amp;_szero; pDest &lt; &amp;_ezero;) {
          *pDest++ = 0;
      }
  
      /* Set the vector table base address */
      pSrc = (uint32_t *) &amp; _sfixed;
      SCB-&gt;VTOR = ((uint32_t) pSrc &amp; SCB_VTOR_TBLOFF_Msk);
  
      if (((uint32_t) pSrc &gt;= IRAM_ADDR) &amp;&amp; ((uint32_t) pSrc &lt; IRAM_ADDR + IRAM_SIZE)) {
          SCB-&gt;VTOR |= (1UL) &lt;&lt; SCB_VTOR_TBLBASE_Pos;
      }
  
      /* Initialize the C library */
      __libc_init_array();
  
      /* Branch to main function */
      main();
  
      /* Infinite loop */
      while (1);
  }
  </code></pre>
  
  <p><strong>Edit 1:</strong></p>
  
  <p>Using <code>objdump -t CodeFile.elf &gt; CodeFile.symbols</code>, I have found this symbol at the start of my <code>.relocate</code> section which seems to suggest that <code>_srelocate</code> doesn't truly point to the beginning of <code>.relocate</code>.</p>
  
  <pre><code>    2000115c g     O .relocate  00000000 .hidden __TMC_END__
  </code></pre>
  
  <p>What is this symbol?</p>
  
  <p>I've looked it up and found <a href="http://sourceware.org/bugzilla/show_bug.cgi?id=13621" rel="nofollow noreferrer">this bug</a> in GCC 4.7 but can't figure out if it is fixed or not in my version.</p>
  
  <p>My compiler is <code>arm-none-eabi-gcc</code> and states its version as <code>4.7.0</code>...
  The linker is <code>arm-none-eabi-ld</code> and its version is <code>2.22</code>.</p>
  
  <p><strong>Edit 2:</strong></p>
  
  <p>I have done some research about this and it is recorded in <a href="https://stackoverflow.com/questions/17605794/what-are-linker-symbols-tmc-end-and-tmc-list-for">this related SO question</a> that I asked. Please look at it as well, as it explains that the problem is a <a href="https://sourceware.org/bugzilla/show_bug.cgi?id=13621" rel="nofollow noreferrer">GCC bug</a>.</p>
  
  <p><strong>Apendix</strong></p>
  
  <p><em>Memory Layout for Linker Scripts</em></p>
  
  <pre><code>OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
  OUTPUT_ARCH(arm)
  SEARCH_DIR(.)
  
  /* Memory Spaces Definitions */
  MEMORY
  {
      rom (rx)  : ORIGIN = 0x00400000, LENGTH = 0x00040000 /* flash, 256K */
      ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00006000 /* sram, 24K */
  }
  
  /* The stack size used by the application. NOTE: you need to adjust  */
  STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x800 ;
  </code></pre>