clinkerarmlinker-errorsarmclang

Passing macro values to arm linker that places variable at a specific location


As per the following link : ARM compiler 6

ARM compiler 6 no longer supports the "attribute((at()))" but has replaced it instead with "attribute((section(".ARM._at")))"

If I want to place a variable at location 0x20000000 using arm compiler 6, i would do something like :

int var __attribute__((section(".ARM.__at_0x20000000")));

But i was to hide the address under a #define ADDR 0x20000000 and use it as:

#define ADDR 0x20000000

int var __attribute__((section(".ARM.__at_ADDR")));

i get an error from the linker as: L6974E: ADDR does not have a base address

Is there a way to use #defines to specify the address to place the variable at?


Solution

  • You can use 'stringify' and string concatenation.

    // Traditional stringify.
    #define xstr(s) str(s)
    #define str(s) #s
    
    #define ADDR 0x20000000
    
    int var attribute((section(".ARM.__at_" str(ADDR))));
    

    String concatenation is just that two adjacent string constants are concatenated.

    The 'str(ADDR)' converts to "0x20000000", so you end up with the string ".ARM.__at_0x20000000" which is what I believe you want.


    For an updated question, where the value is computed, there is no simple way to achieve this in 'C'. Technically it is possible, but requires a huge enumeration of conditionals, so it is not practical.

    For instance, #define ADDR (0x20000000 + (1024 * 16)) with the expectation to generate,

    int var attribute((section(".ARM.__at_0x20004000")));
    

    It is possible to define both ADDR and ADDR_fixed and then conditionally compare they are equal.

    #define ADDR (0x20000000 + (1024 * 16))
    #define ADDR_Fixed 0x20004000
    
    #if ADDR!=ADDR_Fixed
    #error "Miscalculation of ADDR."
    #endif
    

    Tools/scripts outside the compilation process can calculate the value and then pass it as a compiler argument, such as -DADDR_Fixed=0x20004000 and this maybe used to replace the ADDR define to satisfy the linker. Typically, you could add a comment or some other identifier to make parsing easier. Alternatively, if the can be collected in a single file; instead of distributed throughout the source, this aspect is easier. Python, perl, bc, etc can handle the mathematics after parsing.

    Questions on how to implement this script are quite out of scope of the original question and there are already many example on stack overflow, depending on the language chosen.