public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* linker script symbols to c source variables
@ 2007-07-06 14:34 Klaus Rudolph
  2007-07-06 14:54 ` Nick Clifton
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Klaus Rudolph @ 2007-07-06 14:34 UTC (permalink / raw)
  To: binutils

Hi all,

I am now confused how I can get values from linker script to csource.

What I want is very simple (I think).

I have a function in a section which should be copied from flash to ram.
So I defined a section which locate the code into flash and should be executed in ram. Before that I have to copy the code from flash to ram.

But how can I get the values from the linker to the csource???

I have the following linker script:

/* We have 96K internal RAM for data only */
MEMORY
{
    IntCodeFlash (rx) : ORIGIN = 0x00000000, LENGTH = 512K   /* this is flash */
    IntDataRAM   (rw) : ORIGIN = 0x40000000, LENGTH = 96k
}



/* Section Definitions */

SECTIONS
{
    /* first section is .text which is used for code in flash memory*/
  .text :
  {
        ./startup.o (.text)         /* Startup code, importatnt to be the first file, need the vectors in front of flash */
        *(.text)                /* all the other text segments follow... */
        *(.glue_7t)
        *(.glue_7)
  } >IntCodeFlash =0

  . = ALIGN(4);                     /* . means actual address. Align this address by 4 */

  startCodeInFlashForRam = . ;

  .linkToRam : AT (startCodeInFlashForRam )
  {
      startCodeInRam = . ;
      *(.linkToRam)
  } > IntDataRAM

  endCodeInFlashForRam = . ;


  . = ALIGN(4);

  /* .rodata section which is used for read-only data (constants) */
  .rodata startCodeInFlashForRam + SIZEOF (.linkToRam) : AT(startCodeInFlashForRam + SIZEOF (.linkToRam) )
  {
      *(.rodata)
  } >IntCodeFlash

  . = ALIGN(4);

  _etext = . ; 
  PROVIDE (etext = .); 

  /* .data section which is used for initialized data */

  /* .data : AT (_etext) */
  .data : AT (startCodeInFlashForRam + SIZEOF (.linkToRam) + SIZEOF( .rodata) )
  {
      _data = . ; 
      *(.data)
      SORT(CONSTRUCTORS)
  } >IntDataRAM
  . = ALIGN(4);

  _edata = . ; 
  PROVIDE (edata = .); 


....

some more sections will follow...

No I have 2 c files:

main.c:
olatile int a,b;

int c=99;
const int d=104;

void f1(void) __attribute__ ((long_call));


extern unsigned int* startCodeInFlashForRam;
extern unsigned int* endCodeInFlashForRam;
extern unsigned int* startCodeInRam;


int main() {
    unsigned int *src=startCodeInFlashForRam;
    unsigned int *dst=startCodeInRam;
    a=(unsigned int)startCodeInFlashForRam;

    while ( src != endCodeInFlashForRam) { *dst++=*src++; } 
    f1();
    b=a;
    b=c;
    b=d;
}



and f1.c
extern volatile int a,b;
void f1(void) __attribute__ ((section (".linkToRam")));
void f1(void) {
    a=9;
} 

-----

This will compile fine and the objdump shows correct (I think) output:


Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000284  00000000  00000000  00008000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .linkToRam    00000014  40000000  00000284  00010000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .rodata       00000004  00000298  00000298  00010298  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .data         00000004  40000014  0000029c  00018014  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  4 .bss          00000008  40000018  40000018  00018018  2**2
                  ALLOC


But the code will not be copied in the main loop :-(
I am wondering, because no error message occurs!


Anyway: I have not really understand how the "." value in linker script works. Is that the address of the execution or of the load view? (LMA/VMA)
What is it pointing to and how to get the source and target address (LMA/VMA) of a section?

Is there any good introduction to that point? As you can see my linker script is totally ugly and not really well to understand. 

Thanks
 Klaus

 


-- 
Psssst! Schon vom neuen GMX MultiMessenger gehört?
Der kanns mit allen: http://www.gmx.net/de/go/multimessenger

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: linker script symbols to c source variables
  2007-07-06 14:34 linker script symbols to c source variables Klaus Rudolph
  2007-07-06 14:54 ` Nick Clifton
@ 2007-07-06 14:54 ` Daniel Jacobowitz
  2007-07-06 17:33 ` Nick Clifton
  2 siblings, 0 replies; 6+ messages in thread
From: Daniel Jacobowitz @ 2007-07-06 14:54 UTC (permalink / raw)
  To: Klaus Rudolph; +Cc: binutils

On Fri, Jul 06, 2007 at 04:30:47PM +0200, Klaus Rudolph wrote:
> extern unsigned int* startCodeInFlashForRam;
> extern unsigned int* endCodeInFlashForRam;
> extern unsigned int* startCodeInRam;

Try extern unsigned int startCodeInFlashForRam[] instead.  When you
define a symbol in a linker script, that's the symbol's _address_, not
its value.

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: linker script symbols to c source variables
  2007-07-06 14:34 linker script symbols to c source variables Klaus Rudolph
@ 2007-07-06 14:54 ` Nick Clifton
  2007-07-29 18:23   ` linker script symbols syntax and other errors Klaus Rudolph
  2007-07-06 14:54 ` linker script symbols to c source variables Daniel Jacobowitz
  2007-07-06 17:33 ` Nick Clifton
  2 siblings, 1 reply; 6+ messages in thread
From: Nick Clifton @ 2007-07-06 14:54 UTC (permalink / raw)
  To: Klaus Rudolph; +Cc: binutils

Hi Klaus,

> I am now confused how I can get values from linker script to csource.

There is an entire section in the linker manual on this topic.  You 
really should read it.  To save you time however, I have reproduced it here:

   Source Code Reference

   Accessing a linker script defined variable from source code is
   not intuitive.  In particular a linker script symbol is not
   equivalent to a variable declaration in a high level language,
   it is instead a symbol that does not have a value.

   Before going further, it is important to note that compilers
   often transform names in the source code into different names
   when they are stored in the symbol table.  For example, Fortran
   compilers commonly prepend or append an underscore, and C++
   performs extensive name mangling.  Therefore there might be a
   discrepancy between the name of a variable as it is used in
   source code and the name of the same variable as it is defined
   in a linker script.  For example in C a linker script variable
   might be referred to as:

     extern int foo;

   But in the linker script it might be defined as:

       _foo = 1000;

   In the remaining examples however it is assumed that no name
   transformation has taken place.

   When a symbol is declared in a high level language such as C,
   two things happen.  The first is that the compiler reserves
   enough space in the program's memory to hold the *value* of
   the symbol.  The second is that the compiler creates an entry
   in the program's symbol table which holds the symbol's *address*.
   ie the symbol table contains the address of the block of memory
   holding the symbol's value.  So for example the following C
   declaration, at file scope:

     int foo = 1000;

   creates a entry called "foo" in the symbol table.  This entry
   holds the address of an int sized block of memory where the
   number 1000 is initially stored.

   When a program references a symbol the compiler generates code
   that first accesses the symbol table to find the address of the
   symbol's memory block and then code to read the value from that
   memory block.  So:

     foo = 1;

   looks up the symbol foo in the symbol table, gets the address
   associated with this symbol and then writes the value 1 into
   that address.  Whereas:

     int * a = & foo;

   looks up the symbol foo in the symbol table, gets it address
   and then copies this address into the block of memory associated
   with the variable "a".

   Linker scripts symbol declarations, by contrast, create an entry
   in the symbol table but do not assign any memory to them.  Thus
   they are an address without a value.  So for example the linker
   script definition:

     foo = 1000;

   creates an entry in the symbol table called @samp{foo} which holds
   the address of memory location 1000, but nothing special is stored
   at address 1000.  This means that you cannot access the *value* of
   a linker script defined symbol - it has no value - all you can do
   is use the *address* of a linker script defined symbol.

   Hence when you are using a linker script defined symbol in source
   code you should always take the address of the symbol, and never
   attempt to use its value.  For example suppose you want to copy
   the contents of a section of memory called .ROM into a section
   called .FLASH and the linker script contains these declarations:

     start_of_ROM   = .ROM;
     end_of_ROM     = .ROM + sizeof (.ROM) - 1;
     start_of_FLASH = .FLASH;

   Then the C source code to perform the copy would be:

     extern char start_of_ROM, end_of_ROM, start_of_FLASH;

     memcpy (& start_of_FLASH, & start_of_ROM,
             & end_of_ROM - & start_of_ROM);

   Note the use of the "&" operators.  They are correct.


Cheers
   Nick

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: linker script symbols to c source variables
  2007-07-06 14:34 linker script symbols to c source variables Klaus Rudolph
  2007-07-06 14:54 ` Nick Clifton
  2007-07-06 14:54 ` linker script symbols to c source variables Daniel Jacobowitz
@ 2007-07-06 17:33 ` Nick Clifton
  2 siblings, 0 replies; 6+ messages in thread
From: Nick Clifton @ 2007-07-06 17:33 UTC (permalink / raw)
  To: Klaus Rudolph; +Cc: binutils

Hi Klaus,

> I am now confused how I can get values from linker script to csource.

There is an entire section in the linker manual on this topic.  You 
really should read it.  To save you time however, I have reproduced it here:

   Source Code Reference

   Accessing a linker script defined variable from source code is
   not intuitive.  In particular a linker script symbol is not
   equivalent to a variable declaration in a high level language,
   it is instead a symbol that does not have a value.

   Before going further, it is important to note that compilers
   often transform names in the source code into different names
   when they are stored in the symbol table.  For example, Fortran
   compilers commonly prepend or append an underscore, and C++
   performs extensive name mangling.  Therefore there might be a
   discrepancy between the name of a variable as it is used in
   source code and the name of the same variable as it is defined
   in a linker script.  For example in C a linker script variable
   might be referred to as:

     extern int foo;

   But in the linker script it might be defined as:

       _foo = 1000;

   In the remaining examples however it is assumed that no name
   transformation has taken place.

   When a symbol is declared in a high level language such as C,
   two things happen.  The first is that the compiler reserves
   enough space in the program's memory to hold the *value* of
   the symbol.  The second is that the compiler creates an entry
   in the program's symbol table which holds the symbol's *address*.
   ie the symbol table contains the address of the block of memory
   holding the symbol's value.  So for example the following C
   declaration, at file scope:

     int foo = 1000;

   creates a entry called "foo" in the symbol table.  This entry
   holds the address of an int sized block of memory where the
   number 1000 is initially stored.

   When a program references a symbol the compiler generates code
   that first accesses the symbol table to find the address of the
   symbol's memory block and then code to read the value from that
   memory block.  So:

     foo = 1;

   looks up the symbol foo in the symbol table, gets the address
   associated with this symbol and then writes the value 1 into
   that address.  Whereas:

     int * a = & foo;

   looks up the symbol foo in the symbol table, gets it address
   and then copies this address into the block of memory associated
   with the variable "a".

   Linker scripts symbol declarations, by contrast, create an entry
   in the symbol table but do not assign any memory to them.  Thus
   they are an address without a value.  So for example the linker
   script definition:

     foo = 1000;

   creates an entry in the symbol table called foo which holds the
   address of memory location 1000, but nothing special is stored
   at address 1000.  This means that you cannot access the *value*
   of a linker script defined symbol - it has no value - all you
   can do is use the *address* of a linker script defined symbol.

   Hence when you are using a linker script defined symbol in source
   code you should always take the address of the symbol, and never
   attempt to use its value.  For example suppose you want to copy
   the contents of a section of memory called .ROM into a section
   called .FLASH and the linker script contains these declarations:

     start_of_ROM   = .ROM;
     end_of_ROM     = .ROM + sizeof (.ROM) - 1;
     start_of_FLASH = .FLASH;

   Then the C source code to perform the copy would be:

     extern char start_of_ROM, end_of_ROM, start_of_FLASH;

     memcpy (& start_of_FLASH, & start_of_ROM,
             & end_of_ROM - & start_of_ROM);

   Note the use of the "&" operators.  They are correct.


Cheers
   Nick

^ permalink raw reply	[flat|nested] 6+ messages in thread

* linker script symbols syntax and other errors
  2007-07-06 14:54 ` Nick Clifton
@ 2007-07-29 18:23   ` Klaus Rudolph
  2007-08-06 15:47     ` Nick Clifton
  0 siblings, 1 reply; 6+ messages in thread
From: Klaus Rudolph @ 2007-07-29 18:23 UTC (permalink / raw)
  To: Nick Clifton, binutils

Hi,

thanks for your help, but I could get your example not to run:

if I have a linkerscript like:
----

SECTIONS
{

  /* first section is .text which is used for code */

  .text :
  {
    ./startup.o (.text)         /* Startup code */
     *(.text)
    *(.glue_7t) *(.glue_7)
  } >IntCodeRAM =0


  .ROM :
  {
      *(.linkToRam)
  }

1->    start_of_ROM   = .ROM;
2->  /* end_of_ROM     = .ROM + sizeof (.ROM) - 1;
 
}
----
The line 1 give a
test2.ld:134: undefined symbol `.ROM' referenced in expression
:test2.ld:50: syntax error



and if not commented the line 2 gives

can you give me a hint what is going on here and what is the meaning of 
a PROVIDE statement? I read the manual 2 times, but it only confuses me. 
Maybe if I understand it, I will write some examples and put them into 
the manual for others. Sorry that I ask again.

Klaus


> Hi Klaus,
>
>> I am now confused how I can get values from linker script to csource.
>
>
> There is an entire section in the linker manual on this topic.  You 
> really should read it.  To save you time however, I have reproduced it 
> here:
>
>   Source Code Reference
>
>   Accessing a linker script defined variable from source code is
>   not intuitive.  In particular a linker script symbol is not
>   equivalent to a variable declaration in a high level language,
>   it is instead a symbol that does not have a value.
>
>   Before going further, it is important to note that compilers
>   often transform names in the source code into different names
>   when they are stored in the symbol table.  For example, Fortran
>   compilers commonly prepend or append an underscore, and C++
>   performs extensive name mangling.  Therefore there might be a
>   discrepancy between the name of a variable as it is used in
>   source code and the name of the same variable as it is defined
>   in a linker script.  For example in C a linker script variable
>   might be referred to as:
>
>     extern int foo;
>
>   But in the linker script it might be defined as:
>
>       _foo = 1000;
>
>   In the remaining examples however it is assumed that no name
>   transformation has taken place.
>
>   When a symbol is declared in a high level language such as C,
>   two things happen.  The first is that the compiler reserves
>   enough space in the program's memory to hold the *value* of
>   the symbol.  The second is that the compiler creates an entry
>   in the program's symbol table which holds the symbol's *address*.
>   ie the symbol table contains the address of the block of memory
>   holding the symbol's value.  So for example the following C
>   declaration, at file scope:
>
>     int foo = 1000;
>
>   creates a entry called "foo" in the symbol table.  This entry
>   holds the address of an int sized block of memory where the
>   number 1000 is initially stored.
>
>   When a program references a symbol the compiler generates code
>   that first accesses the symbol table to find the address of the
>   symbol's memory block and then code to read the value from that
>   memory block.  So:
>
>     foo = 1;
>
>   looks up the symbol foo in the symbol table, gets the address
>   associated with this symbol and then writes the value 1 into
>   that address.  Whereas:
>
>     int * a = & foo;
>
>   looks up the symbol foo in the symbol table, gets it address
>   and then copies this address into the block of memory associated
>   with the variable "a".
>
>   Linker scripts symbol declarations, by contrast, create an entry
>   in the symbol table but do not assign any memory to them.  Thus
>   they are an address without a value.  So for example the linker
>   script definition:
>
>     foo = 1000;
>
>   creates an entry in the symbol table called @samp{foo} which holds
>   the address of memory location 1000, but nothing special is stored
>   at address 1000.  This means that you cannot access the *value* of
>   a linker script defined symbol - it has no value - all you can do
>   is use the *address* of a linker script defined symbol.
>
>   Hence when you are using a linker script defined symbol in source
>   code you should always take the address of the symbol, and never
>   attempt to use its value.  For example suppose you want to copy
>   the contents of a section of memory called .ROM into a section
>   called .FLASH and the linker script contains these declarations:
>
>     start_of_ROM   = .ROM;
>     end_of_ROM     = .ROM + sizeof (.ROM) - 1;
>     start_of_FLASH = .FLASH;
>
>   Then the C source code to perform the copy would be:
>
>     extern char start_of_ROM, end_of_ROM, start_of_FLASH;
>
>     memcpy (& start_of_FLASH, & start_of_ROM,
>             & end_of_ROM - & start_of_ROM);
>
>   Note the use of the "&" operators.  They are correct.
>
>
> Cheers
>   Nick
>
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: linker script symbols syntax and other errors
  2007-07-29 18:23   ` linker script symbols syntax and other errors Klaus Rudolph
@ 2007-08-06 15:47     ` Nick Clifton
  0 siblings, 0 replies; 6+ messages in thread
From: Nick Clifton @ 2007-08-06 15:47 UTC (permalink / raw)
  To: Klaus Rudolph; +Cc: binutils

Hi Klaus,

> SECTIONS
> {
>  .text :
>  {
>    ./startup.o (.text)         /* Startup code */
>     *(.text)
>    *(.glue_7t) *(.glue_7)
>  } >IntCodeRAM =0
>  .ROM :
>  {
>      *(.linkToRam)
>  }
> 
> 1->    start_of_ROM   = .ROM;
> 2->  /* end_of_ROM     = .ROM + sizeof (.ROM) - 1;
> }
> ----
> The line 1 give a
> test2.ld:134: undefined symbol `.ROM' referenced in expression

This is correct.  .ROM is not a symbol defined in the symbol table of the 
executable, but rather a symbol in the SECTION directive's namespace.  You can 
fix this by assigning the value of "." to start_of_ROM at the start of the .ROM 
section, like this:

    } >IntCodeRAM =0

    . = .;                 /* <=== NEW */
    start_of_ROM = .;      /* <=== NEW */

    .ROM :
    {

Note, for an explanation of the ". = .;" line in the above snippet see the 
"Location Counter" section of the linker manual.


> :test2.ld:50: syntax error

Also correct and for the same reason.  You can fix this one as well, like this:

     *(linkToRam);
   }
   end_of_ROM = . - 1;

Assuming that you want end_of_ROM to be the address of the last byte in the 
.ROM section and not the address of the first byte after the end of the .ROM 
section.

> what is the meaning of 
> a PROVIDE statement? I read the manual 2 times, but it only confuses me. 

OK, so basically what the PROVIDE statement does is to create a symbol and 
assign it a value, but only if the symbol has not appeared in any of the input 
files.  So for example, suppose that you have this in your linker script:

   PROVIDE (foo = 1);

Then if none of the input files define a symbol called "foo", the linker will 
create one and assign it the value of 1.  If an input file does define a symbol 
called "foo" then the linker will use that version instead and ignore the value 
defined in the PROVIDE statement.

Essentially the PROVIDE statement allows the linker script to define a default 
value for a symbol which can be overridden by any of the input files.

Cheers
   Nick







^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2007-08-06 15:47 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-07-06 14:34 linker script symbols to c source variables Klaus Rudolph
2007-07-06 14:54 ` Nick Clifton
2007-07-29 18:23   ` linker script symbols syntax and other errors Klaus Rudolph
2007-08-06 15:47     ` Nick Clifton
2007-07-06 14:54 ` linker script symbols to c source variables Daniel Jacobowitz
2007-07-06 17:33 ` Nick Clifton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).