EmbDev.net

Forum: ARM programming with GCC/GNU tools Yagarto BUG: static vars are offset in memory by 4 bytes.


Author: (unknown) (Guest)
Posted on:

Rate this post
0 useful
not useful
I'm using:
yagarto-bu-2.23.1_gcc-4.7.2-c-c++_nl-1.20.0_gdb-7.5.1_eabi_20121222
and it is working well with a project containing dozens of source files.

Then I add the following source files:
FooClass.h
class FooClass {
public:
  FooClass(){};
  static FooFrame m_fooFrame;
};
FooClass.cpp
#include "FooClass.h"
FooFrame FooClass::m_fooFrame;

Here's the file for the static member:
FooFrame.h
class FooFrame {
public:
  FooFrame(){};
};
No need for FooFrame.cpp

Trivial right? Well, the result is that static vars are erroneously 
shifted in memory by 4 bytes.

Here's the map file. These vars reside at __data_start and are copied 
there from ROM by the startup code. Adding FooClass doesn't alter these 
vars at the beginning. That's all fine and dandy.
                0x40000200        0x1 src\UserIO.o
                0x40000200                UserIO::m_dummySystemStatus
 *fill*         0x40000201        0x3 
 .data._ZN3SAL15m_uart0BaudRateE
                0x40000204        0x4 src\SAL.o
                0x40000204                SAL::m_uart0BaudRate
 .data._ZN3SAL15m_uart1BaudRateE
                0x40000208        0x4 src\SAL.o
                0x40000208                SAL::m_uart1BaudRate


This is the happy memory of the ARM7 before adding FooClass:
40000200 01000000 80250000 80250000 01010100
This is correct. You can see m_dummySystemStatus, and the two baud rates 
(9600 baud becomes 0x80250000 :-). Great!

Now lets add FooClass to the project and look at memory:
40000200 FFFFFFFF 01000000 80250000 80250000

What the heck? You can see that the static members have been moved by 1 
word (4 bytes) and any code that uses them crashes in a pile.

I'm using James P. Lynch's linker script (modified for the LPC2148):
/*  Author:  James P. Lynch   */                                                                            /* identify the Entry Point  */

ENTRY(_startup)
/* specify the LPC2148 memory areas  */

MEMORY 
{
  flash           : ORIGIN = 0,          LENGTH = 512K  /* FLASH ROM                              */  
  ram_isp_low(A)    : ORIGIN = 0x40000120, LENGTH = 223    /* variables used by Philips ISP bootloader  */     
  ram           : ORIGIN = 0x40000200, LENGTH = 32224  /* free RAM area              */
  ram_isp_high(A)    : ORIGIN = 0x40007FE0, LENGTH = 32    /* variables used by Philips ISP bootloader  */
}


/* define a global symbol _stack_end  */

_stack_end = 0x40007EDC;

/* now define the output sections  */

SECTIONS 
{
  . = 0;                /* set location counter to address zero  */
  
  startup : {
    *(.startup)
    . = ALIGN(0x4);
    } >flash    /* the startup code goes into FLASH */
  
  

    .text : {
        CREATE_OBJECT_SYMBOLS
        *(.text .text.* .gnu.linkonce.t.*)
        *(.plt)
        *(.gnu.warning)
        *(.glue_7t) *(.glue_7)

        . = ALIGN (4);
        /* These are for static constructors and destructors under ELF */
        KEEP (*crtbegin.o(.ctors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
        KEEP (*(SORT(.ctors.*)))
        KEEP (*crtend.o(.ctors))
        KEEP (*crtbegin.o(.dtors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
        KEEP (*(SORT(.dtors.*)))
        KEEP (*crtend.o(.dtors))

        *(.rodata .rodata.* .gnu.linkonce.r.*)

        *(.ARM.extab* .gnu.linkonce.armextab.*)
        *(.gcc_except_table)
        *(.eh_frame_hdr)
        *(.eh_frame)

        *(.init)
        *(.fini)

        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP (*(.preinit_array))
        PROVIDE_HIDDEN (__preinit_array_end = .);
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array))
        PROVIDE_HIDDEN (__init_array_end = .);
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP (*(.fini_array))
        KEEP (*(SORT(.fini_array.*)))
        PROVIDE_HIDDEN (__fini_array_end = .);
    } >flash

    /* .ARM.exidx is sorted, so has to go in its own output section.  */
    .ARM.exidx : {
        __exidx_start = .;
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
        __exidx_end = .;
    } >flash
    _etext = .;


  
    .data : {
        __data_load = LOADADDR (.data);
        __data_start = .;
        KEEP(*(.jcr))
        *(.got.plt) *(.got)
        *(.shdata)
        *(.data .data.* .gnu.linkonce.d.*)
        . = ALIGN (4);
        _edata = .;
    } >ram AT >flash

    .bss : {
        __bss_start__ = . ;
        *(.shbss)
        *(.bss .bss.* .gnu.linkonce.b.*)
        *(COMMON)
        . = ALIGN (4);
        __bss_end__ = .;
    } >ram

}
  _end = .;              /* define a global symbol marking the end of application RAM */
  


So my question is, can you help me identify where I'm going wrong?
Thank you!
David

Author: A. K. (prx)
Posted on:

Rate this post
0 useful
not useful
Build a minimzed testcase which allows others to reproduce the problem.

Author: Jörg Wunsch (dl8dtl) (Moderator)
Posted on:

Rate this post
0 useful
not useful
David Lee wrote:
> _stack_end = 0x40007EDC;

Make this either 0x40007ed8, or 0x40007ee0.  It's not immediately
obvious to me whether your problem might fall into this, but I've once
stumbled across that one myself (on a Cortex-M3 though).

Author: (unknown) (Guest)
Posted on:

Rate this post
0 useful
not useful
Thank you for the reply. I've tried both addresses and it did not fix 
the problem. Were you thinking that the address should be on a word 
boundary?

I am also working to reduce this problem to a small size test case so 
that I can post the entire project.

In the mean time I am using static pointers to classes and initializing 
them through constructors. It is distasteful, but so is most of my work 
recently.

Cheers,
David

Author: Dr. Sommer (Guest)
Posted on:

Rate this post
0 useful
not useful
David Lee wrote:
> __data_load = LOADADDR (.data);
>         __data_start = .;
Can you verify that those addresses are correctly set?

Author: Jörg Wunsch (dl8dtl) (Moderator)
Posted on:

Rate this post
0 useful
not useful
David Lee wrote:
> Were you thinking that the address should be on a word boundary?

On a 64-bit boundary.  This is the maximum alignment requirement in ARM
cores (for “double” values).

Author: Uwe Bonnes (Guest)
Posted on:

Rate this post
0 useful
not useful
Can you try with a recent arm gcc from 
https://launchpad.net/gcc-arm-embedded?

Author: (unknown) (Guest)
Posted on:

Rate this post
0 useful
not useful
I will work on this today. Thanks!

Author: (unknown) (Guest)
Posted on:

Rate this post
0 useful
not useful
Hi Uwe,
Thank you for the suggestion (and implicit encouragement).
I upgraded from Yagarto's gcc-4.7.2 to launchpad's 4.8-2013-q4-major.

The offset problem is gone. My code runs fine now.

I have a question for all. Do new version of cross gcc for ARM introduce 
as many bugs as they fix? Is successful development a matter of just 
finding the version that compiles "your code" correctly?

Cheers to all,
David

Author: MarcVonWindscooting (Guest)
Posted on:

Rate this post
0 useful
not useful
(unknown) wrote:
> Do new version of cross gcc for ARM introduce
> as many bugs as they fix?

A "cross gcc" is not that much different from a "normal" gcc for your 
host system.

My experience is: gcc is much more reliable than the programs I write 
myself. MEANING: errors that show up are almost always MY errors.

Switching to another gcc does not necessarily mean your problem is gone. 
It might as well have gone because the conditions have changed a bit: 
new segments/removed segments/different code size/different arrangement 
of segments/alignment/...(a million other possibilities)...

Have you searched a bug tracker for something that sounds like your 
problem?
If your problem is a gcc problem and it shows up only rarely then the 
gcc developer would definitely appreciate you reporting that bug. 
Because one thing is true about bugs: they persist and show up at the 
most inappropriate moment in a project...

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.