linker script symbols to c source variables

Nick Clifton nickc@redhat.com
Fri Jul 6 17:33:00 GMT 2007


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



More information about the Binutils mailing list