1

I'm trying to force a global variable to a specific address without modifying the source code. I'm well aware of solution such as:

// C source code
MyStruct globalVariable __attribute__((section(".myLinkerSection")));
  // Linker script
  . = 0x400000;
  .myLinkerSection: 
  {
      *(.myLinkerSection)
  }

But in my case I would like to do the same thing without the __attribute__((section(".myLinkerSection"))) keyword.

Is it doable ?

EDIT: I cannot modify the source code at all. The variable is defined as follow:

file.h:

extern MyStruct globalVariable;

file.c:

MyStruct globalVariable;
Lucas
  • 65
  • 9
  • 1
    Why not just create a pointer: `MyStruct *globalVariable = (MyStruct *)0x400000;` – dbush Jul 29 '22 at 12:48
  • 1
    Why must the variable reside at a specific address? What problem does it solve? – dbush Jul 29 '22 at 16:46
  • Unfortunatly I cannot modify the source code (see my edit). – Lucas Jul 29 '22 at 16:46
  • Does the defining source file have more than this variable? – the busybee Jul 29 '22 at 16:46
  • Yes there are a lot of variables defined in the source file. – Lucas Jul 29 '22 at 16:48
  • @dbush I'm developping an embedded software, the data are loaded at this specific address by another process during software init. Having this variable at a specific address allows to get rid of a memcpy (and it helps my with some other functionnalities specific to my software that I won't explain here). – Lucas Jul 29 '22 at 16:58
  • You should add tags for the compiler / platform you are using. – Nate Eldredge Jul 30 '22 at 15:33
  • You can force the variable to a specific address, but that is probably insufficient to read data previously stored at that address by a different process. C semantics specify the initial values of external variables. – John Bollinger Jul 31 '22 at 14:34
  • You probably want a global pointer to the fixed address instead of a global variable pinned to that address, as was already suggested. That would be reasonably natural on the C side, but it would require multiple changes in the program. – John Bollinger Jul 31 '22 at 14:37

2 Answers2

2

I assume from the mentions of __attribute__ that you are using gcc / clang or something compatible. You can use the -fdata-sections option to make the compiler put every variable into its own section. With that option, your globalVariable, assuming it would otherwise go in .bss, will be placed in a section called .bss.globalVariable (the exact name might be platform-dependent). Then you can use your linker script to place this section at the desired address.

Note that this option will inhibit certain compiler optimizations. There is a guarantee that objects defined in the same section within the same assembler module are assembled in strict order, and that their addresses do not change after that. In some cases the compiler can take advantage of this; e.g. if it defines int variables foo and bar consecutively in the same section, then it knows their addresses are consecutive, and it can safely generate code that "hardcodes" their relative position. For instance, on some platforms such as ARM64, it takes multiple instructions to materialize the address of a global or static object. So if some function accesses both foo and bar, the compiler can materialize the address of foo, then add the fixed constant 4 to get the address of bar. But if foo and bar are in different sections, this can't be done, and you will pay the (small but nonzero) cost of materializing both addresses separately.

As such, you may want to use -fdata-sections only on the particular source files that define the particular variables of concern.

This also illustrates why you have to get the variable in its own section in order to set its address; you can't move just one variable from a section, since the compiler may have been relying on its relative position to some other variable in that section.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
0

You can define this variable in a separate translation unit. Then list its object file in the appropriate section.

the busybee
  • 10,755
  • 3
  • 13
  • 30
  • This would work. But I require to modify the existing source code to move the definition of the variable. Unfortunatly I can't modify the code at all. – Lucas Jul 29 '22 at 16:42
  • 1
    Well, you forgot to mention this in your question. Please add it. – the busybee Jul 29 '22 at 16:43