Order of variables in specific sections when enabling optimization in gcc
David Brown
david.brown@hesbynett.no
Thu Mar 7 21:05:00 GMT 2019
On 07/03/2019 14:50, Freddie Chopin wrote:
> On Thu, 2019-03-07 at 07:00 -0600, Segher Boessenkool wrote:
>> On Thu, Mar 07, 2019 at 01:15:47PM +0100, Freddie Chopin wrote:
>>> 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
>>
>> You can refer to separate variables in the linker script, you don't
>> have
>> to put them each in their own section.
>
> How should I do that? Do you think of giving absolute addresses to
> individual symbols? This is not very convenient, as then I would also
> have to think about their size. This will also not play so well with
> name-mangling (the project is in C++).
You can avoid the name-mangling by declaring symbols as extern "C". I
don't think variable names are mangled anyway - only function names.
(Unless you are using C++14 template variables, anyway.)
>
>>> 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.
>>
>> You could try putting all those vars in a struct. In principle the
>> compiler is free to mess that up, too, though, but this is less
>> fragile,
>> and easier to work around should it break.
>
> Yes, this is also an option, but this is not very convenient for me, as
> then each user of each variable would get all the headers required for
> completely unrelated variables (like definitions of classes and so on).
> Not an issue now, but this also won't work if one variable needs to be
> used from a C file and another one is a C++ class. This just does not
> scale well..
>
How about:
battery_ram.h
-------------
#include <stdint.h>
struct raw_battery_ram_t {
uint32_t programKey; // Constant for type of program
uint32_t structVersion; // To allow transparent upgrades
uint64_t paramsBlock[10];
uint64_t scratchpad[20];
uint64_t log[20];
};
extern raw_battery_ram_t raw_battery_ram;
battery_ram.c
-------------
#include "battery_ram.h"
raw_battery_ram_t raw_battery_ram __attribute__((section("battery_ram")));
params.h
--------
#include "battery_ram.h"
struct params_t {
uint32_t noOfWoozles;
uint16_t sizeOfThingies;
uint16_t countOfThingies;
uint64_t secretKey;
};
static params_t& params = *(reinterpret_cast<params_t*>
(&(raw_battery_ram.paramsBlock)));
static_assert(sizeof(params) <= sizeof(raw_battery_ram.paramsBlock));
othercode.c
-----------
#include "params.h"
void processWoozles(void) {
for (uint32_t i = 0; i < params.noOfWoozles; i++) {
toogleWozzle(i);
}
}
This means that the information in the common "battery_ram.h" header is
restricted to basic blocks, not type details. Any types needed for the
parameter block are only visible in "params.h", while any types needed
for the scratchpad block are only visible in the "scratchpad.h". A
slightly ugly reinterpret_cast is used to map the logic type structure
onto the actual storage space (a placement new would be an alternative
option). Static asserts are used to spot overruns (the size of the
spaces allocated in the raw struct have to be entered manually).
>> If you use LTO or some other whole-program optimisation, that won't
>> save you. Hiding things from the compiler so it cannot assume
>> anything
>> about it breaks as soon as the compiler gets more smarts (if it ever
>> worked). Telling the compiler that something *is* accessed some way
>> that it cannot see: that is fool-proof and future-proof.
>
> But these variables are used. I'm not hiding anything, they are used,
> usually their address is embedded withing other objects, so they are
> used "as much as possible" (;
>
> Regards,
> FCh
>
>
More information about the Gcc-help
mailing list