bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/10774] Bogus documentation


From: nickc at redhat dot com
Subject: [Bug ld/10774] Bogus documentation
Date: Wed, 16 Sep 2015 08:54:39 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=10774

--- Comment #3 from Nick Clifton <nickc at redhat dot com> ---
Hi Konrad,

   Thank you very much for your prompt response, and for persisting with this
issue.

> I believe ELF reserves section names beginning with a dot for its own use,
> so technically you shouldn't name your sections .FLASH or .ROM.

Actually the ELF spec says:

  Section names with a dot (.) prefix are reserved for the system, 
  although applications may use these sections if their existing 
  meanings are satisfactory.  Applications may use names without 
  the prefix to avoid conflicts with system sections.

In the case of the .ROM and .FLASH examples, I think that it is fair to assume
that they are system specified sections, rather than application created
sections.  IE that they refer to ROM and flash regions of the target hardware's
address space.

> The compiler will issue a diagnostic for a write to a const-qualified object.
> In your example, the symbols are not const qualified.  You would make more
> use of the type-checking facilities of the compiler with
> 
> extern char const start_of_FLASH [];

A good point.

> I prefer `&start_of_FLASH' to `& start_of_FLASH'; as I leave a space around
> binary operators `a & b', it makes it easier to distinguish between the
> unary and binary meanings of `&'.

Personally I like the spaces, but most people agree with you, so I will make
this change.

> In the final section, I would write "transformations".  There is one
> transformation from C++ symbol to C symbol names (mangling), and possibly a
> second transformation from C to assember/linker names (e.g., underscore
> prepending).  Mangling is dealt with `extern "C"'.  You could add that from
> C++, you need to declare `foo' as `extern "C" int foo [];'

Fair enough.  What do you think of this revised wording ?

Cheers
  Nick
------------------------------------------------------------------------
3.5.5 Source Code Reference
---------------------------

The value of a symbol is its address.  Thus to access a symbol's value
from a high level language it should be declared as an external variable
and its address used.

   Note that in most cases, symbols defined by linker scripts do _not_
have any associated storage assigned to them, so it is typically an
error to read from or write to such an external variable.  For example,
suppose that a linker script defines some symbols like this:

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

   The the following code to copy data from ROM to FLASH will fail:

       extern char start_of_ROM, end_of_ROM, start_of_FLASH;
       memcpy (start_of_FLASH, start_of_ROM, end_of_ROM - start_of_ROM); /*
FAIL */

   This is because it is reading from and writing to the symbols.
Instead the copy should be written as:

       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 - these are correct.  Or the copy
could be written as:

       extern const char start_of_ROM[], end_of_ROM[], start_of_FLASH[];
       memcpy (start_of_FLASH, start_of_ROM, end_of_ROM - start_of_ROM);

   Which is easier to read and enables the C compiler to diagnose
writes, reads (without array dereference) and use of the sizeof operator
as errors.

   Type checking is not performed on linker symbols, so any type can be
used to reference them.  Note however that using the wrong type could
lead to runtime problems.  For example:

       extern const int start_of_FLASH[];
       * start_of_FLASH = 1;

   This could result in a runtime failure if the start_of_FLASH symbol
is not assigned to an address that meets the alignment requirements of
the int data type.

   Finally, note that some systems perform transformations between
variable names as used in high-level languages and symbol names as seen
by the linker.  The transformations can be an artefact of the high level
language - for example name mangling in C++, but they can also be part
of the architecture's ABI - for example prepending an underscore to
variable names.  If a linker script symbol is to be accessed from a high
level language then this transformation must be taken into account.  For
example in C++ a linker script symbol might be referred to as:

      extern "C" const int foo[];

   (Note the use of '"C"' to prevent the C++ name mangling).  In the
linker script however the same symbol might have to be declared as:

       _foo = 1000;

   With a '_' prefix in order to match the ABI requirements.

-- 
You are receiving this mail because:
You are on the CC list for the bug.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]