Overwriting Symbols in the GNU Linker File

I start liking the GNU linker (ld) more and more. Yes, that linker command file syntax needs some time to learn, but it is very powerful. I stumbled over an interesting way how to define linker symbols:

/* Linker file for GNU C Compiler */

/* Entry Point */
ENTRY(Reset_Handler)

HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x00000400;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x00000400;

The interesting part is how the HEAP_SIZE and STACK_SIZE symbols are defined.

It checks if e.g. __heap_size__ is DEFINED, and if so, it uses that symbol, otherwise it is using 0x400. Very similar to the C/C++ ‘?’ operator. So I can overwrite the default of 0x400 with my value or symbol. The questions is: from where does the symbol come from?

I checked http://www.math.utah.edu/docs/info/ld_3.html which explains DEFINED as

DEFINED(symbol)

Return 1 if symbol is in the linker global symbol table and is defined, otherwise return 0. You can use this function to provide default values for symbols. For example, the following command-file fragment shows how to set a global symbol begin to the first location in the .text section–but if a symbol called begin already existed, its value is preserved:

SECTIONS{ ...
  .text : {
    begin = DEFINED(begin) ? begin : . ;
    ...
  }
... }

So this is really a cool way to overwrite a symbol in the linker file, without touching the linker file itself. After some digging, I have found a way how this can be done: with options in passed to the linker: It requires the -Xlinker option and the –defsym option:

-Xlinker --defsym=

So to set the __heap_size__ to 0x600, I use

-Xlinker --defsym=__heap_size__=0x600

If using the GNU ARM Eclipse plugins (e.g. Kinetis Design Studio or my DIY Eclipse IDE), the options is added to the ‘other linker flags’ of the Cross ARM C++ Linker settings:

GNU Linker Option to define symbol

GNU Linker Option to define symbol

An easy way to verify if things are working as intended is to check the linker map file, and search for that symbol. For my case above I get:

LOAD c:/freescale/kds_1.1.0/toolchain/bin/../lib/gcc/arm-none-eabi/4.8.0/m4/fp/v4-sp-d16/crti.o
LOAD c:/freescale/kds_1.1.0/toolchain/bin/../lib/gcc/arm-none-eabi/4.8.0/m4/fp/v4-sp-d16/crtbegin.o
LOAD c:/freescale/kds_1.1.0/toolchain/bin/../lib/gcc/arm-none-eabi/4.8.0/../../../../arm-none-eabi/lib/m4/fp/v4-sp-d16/crt0.o
                0x00000600                __heap_size__ = 0x600

So that worked as expected 🙂

Summary

If symbols are defined in the GNU linker file with

newSymbol  = DEFINED(symbol)  ? symbol  : default ;

Then I can overwrite it using a linker command:

-Xlinker --defsym=symbol=value

Happy Defining 🙂

Useful link:http://stackoverflow.com/questions/10032598/gnu-ld-how-to-override-a-symbol-value-an-address-defined-by-the-linker-script

Advertisements

4 thoughts on “Overwriting Symbols in the GNU Linker File

  1. Please forgive my ignorance (I’m not really an engineer, I just play one in my mind), but under what conditions would one want to do this? How does it change the resulting process or program?

    Thank you.

    Like

What do you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s