This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: linker script symbols to c source variables


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]