Search code examples
clinkerheader-fileslinker-scripts

Utilizing same header file for linker script and C program, is it possible?


For example I want to place a special data in 0x100000000, 0x100100000, 0x100200000, ... and for this I want to do in a header file,

#define DATA_START 0x100000000
#define DATA_GAP 0x100000
#define DATA0_START DATA_START + 0*DATA_GAP
#define DATA1_START DATA_START + 1*DATA_GAP
#define DATA2_START DATA_START + 2*DATA_GAP

Now I want to have a linker script and define sections there and want to do something like this. (so that the C program and linker script match).

. = DATA_START;
.mydata : {
  *(.data0)
   . = ALIGN(DATA_GAP);
  *(.data1)
   . = ALIGN(DATA_GAP);
...
}

of course with enough value for DATA_GAP so that data don't overlap.
But in linker script, the define statement is not "#define DATA_START 0x100000000" but "DATA_START = 0x100000000;". So if I want to use a single file to be used in C and linker script, how can I do it?? (I read somewhere that in programs there should be single point of truth, without having to fix data in multiple places..)
I know how to declare a variable in linker script and use it C program (using "var = ." in linker sciprt and using &var in C program..), but this time I want to statically allocate some data.


Solution

  • Marco Bonelli's answer can be a solution but I though this method is simpler.
    In Makefile, I added this command in the recipe before the actual compilation.

    sed -e 's/#define ([A-Z0-9_][A-Z0-9_]) (.)/\1 = \2;/' sections.h > linkadd.h

    and the actual linker script now has this line at the start.

    INCLUDE linkadd.h
    

    So before the compilation, the C header file looks like

    #define DATA_START 0x82000000
    #define DATA_GAP 0x100000
    #define ARGBUF0 DATA_START
    #define ARGBUF1 DATA_START + DATA_GAP
    #define ARGBUF2 DATA_START + 2*DATA_GAP
    

    and the linker script looks like

    INCLUDE linkadd.h
    
      . = DATA_START;
      .mydata : {
        _mydata_start = .;
            . = ARGBUF0;
            *(.data_args0)
            . = ARGBUF1;
            *(.data_args1)
            . = ARGBUF2;
            *(.data_args2)
    

    I think this looks better.