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 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






[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