This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CLANG memory allocation for global variables

Hi,

I have declared 'global variables in below way:

In my main.c file, I have following:

__attribute__((section(".TEST"))) unsigned short global1;
__attribute__((section(".TEST"))) unsigned short global2;

void main(void)
{
unsigned short local1;
unsigned short local2;

local1 = global1;
local2 = global2;
}

In my lnker command file, I have following:
.TEST : {} > MSRAMTEST
MSRAMTEST : ORIGIN = 0x70180000 , LENGTH = 0x40000

With these settings, I see the memory allocation for my global variables as following:
70180000 global1
70180002 global2

However, when my code changes the order of the global variables read, as shown below

void main(void)
{
unsigned short local1;
unsigned short local2;

local2 = global2;
local1 = global1;
}

the addresses in the memory got changed too.
70180002 global1
70180000 global2

Is there any flag which I can set to make sure the address of global variables remain the same, irrespective of the order of usage. 

Regards,
Vishwanath Reddy.


  • Is there any flag which I can set to make sure the address of global variables remain the same, irrespective of the order of usage. 

    Unfortunately, no.  

    Here are two alternatives to consider.  One, put the global variables in a structure.  Two, define them in hand-coded assembly.

    Thanks and regards,

    -George

  • Hello George,

    Can you explain on why this is happening? Also, seems like this issue was not observed when ARM-CGT-19 v20.2.5.LTS was used.
    Also, can you provide an example of defining the variables in hand-coded assembly?

    Regards,
    Vishwanath Reddy.

  • Can you explain on why this is happening?

    Because many compilers just happen to allocate variables in the same order as they appear in the source, many users mistakenly think that is a requirement.  But there is no such requirement.

    seems like this issue was not observed when ARM-CGT-19 v20.2.5.LTS was used

    If you build with --opt_level=3 or higher, an optimization is enabled which may (or may not) change the order of some of the global variables.

    can you provide an example of defining the variables in hand-coded assembly?

    Unfortunately, no.  I lack confidence in my understanding of the GNU-style assembler syntax used by tiarmclang.  That said, here are some thoughts.

    Build a C source file with the option -S, and the compiler stops compilation after creating the assembly source.  The file has the same name as the source file, with the extension changed to .s.  Inspect that file to see the assembler directives the compiler uses to create the variables.  To understand those directives, see the documentation on the integrated GNU-Syntax Arm assembler.  

    Perhaps you are more comfortable writing the assembly with the syntax accepted by the legacy TI Arm assembler.  Such files can be built with tiarmclang.  For the details, please see the documentation on the TI-syntax Arm assembler.

    Thanks and regards,

    -George

  • Hello George,

    If the global variables are initialized with zero during declaration as shown below, then the memory allocation for variables is not getting changed. 

    __attribute__((section(".TEST"))) unsigned short global1=0;
    __attribute__((section(".TEST"))) unsigned short global2=0;

    Does compiler guarantee this is always the case?

    Thanks and Regards,
    Vishwanath Reddy.

  • Hi Vishwanath,

    The section attributes as you have them specified will put both globals in the same input section, but will not guarantee that they are placed in order.

    It is possible to control the address where a global variable will be placed using the "location" attribute.

    For example,

    __attribute__((location(0x1000))) unsigned short global1;

    __attribute__((location(0x1002))) unsigned short global2;

    will instruct the linker to place global1 at 0x1000 and global2 at 0x1002.

    One condition that must be met at link time is that the addresses specified in the location attributes must be accounted for in the MEMORY configuration that is specified in the linker command file. For example, in the following MEMORY directive:

    MEMORY {

       GMEM: org = 0x00001000, len = 0x1000

       ...

    }

    The addresses specified in the location attributes are accounted for in the GMEM memory region.

    When a location attribute is specified on a data object, it will be defined in its own input section. The linker will then apply a specific address placement to that input section. Such placement instructions are processed first by the linker to ensure that the location attribute is honored.

    Hope this helps

    Todd Snider

    TI Arm Clang Compiler Tools Team