Re: Order of variables in specific sections when enabling optimization in gcc

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

 



On 07/03/2019 13:16, Freddie Chopin wrote:
> Hello Segher!
> 
> On Thu, 2019-03-07 at 06:08 -0600, Segher Boessenkool wrote:
>> You probably should use a linker script for this.
> 
> You think of anything better than placing each variable in its own
> section and placing them manually in the linker script in the order I
> like? I would like to avoid any messing with linker script if that's
> possible... If there's nothing better I may end up using suffixes
> ("section.1", "section.2", "section.3", ...) and sort the sections in
> the linker script (`*(SORT(.section.*));`), but I would still prefer to
> solve that in the source file only.

The -fno-toplevel-reorder switch can be handy too - it will stop
re-ordering within a translation unit.

> 
>> The compiler can optimise away (some of) those variables even, or not
>> always keep them in memory, etc., unless you use volatile on the
>> vars.
> 
> No worries, it won't optimize them away, there's also a header where
> these variables are declared with `extern ...` (omitted that in the
> example, as this doesn't change anything) and all of them will be used
> in the project. I'm just concerned about their order.
> 

"extern" does not affect whether they are optimised away or not - if the
variables are declared at the file / namespace level without "static",
they will have external linkage and be created within the translation
unit.  However, if you are using LTO or -fdata-sections and the
--gc-sections linker option, variables that are not needed get
eliminated.  (Note that this could happen even if they are actually
used, if the compiler can figure out that the storage is not needed.)


I have seen people try to use section attributes and careful linker
setups to get consistent memory layouts between program versions.
(Usually it is eeprom, rather than battery backed ram, but the principle
is the same.)  It is often possible to get a reasonable solution - it is
rarely possible to get a good and reliable solution that caters for all
possibilities.  Typically things break down when you want to add a new
variable.

My personal preference is to make a struct definition that holds /all/
the variables in the special area.  This makes it easy to track, and
easy to be sure that you have everything where you expect it.  My struct
here starts with some metadata - an indicator of the program type (if
you have more than one program for the same card), a struct version
number (so that a new program version can re-use old data while knowing
that new data might not be properly initialised), and typically stamps
and CRC's for allowing multiple versions of the data.  (That is relevant
for eeproms that take some time to store the data, when you might have a
power fail during write - it is less relevant for battery backed ram.)

This means you don't get to define your data neatly in the modules that
use the data, but it does mean you have no problem with layouts or
consistency.






[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux