GNU LD: how to override the character value (address) specified by the script builder using -T

My account is as follows:

  • I use the typical SDK that comes with Makefile-based projects.
  • I believe the linker is fixed by gcc. gcc --version gives me 4.3.4
  • The SDK defines the linker script (lets call it Linker.ld)
  • Linker.ld includes LinkerMemMap.cfg, which defines the absolute addresses for the various sections in the associated ELF image.
  • The SDK provides Makefiles-based application templates (GNU Make 3.81) and does it yourself
  • In the Makefile provided by the SDK, when gcc is called, Linker.ld is provided with the -T command-line option as follows:

gcc $(OBJS) -l$(Lib1) -l$(Lib2) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections -o$(OUTPUT).elf

My requirement is as follows:

  • I would like to use partitions, as defined in Linker.ld, and use a memory card according to LinkerMemMap.cfg, however, configure a special character (lets call it SYMBOL_RAM_START) defined in LinkerMemMap.cfg

What works:

  • I tried in the makefile before linking the final ELF image, copy LinkerMemMap.cfg (which is included by Linker.ld) into the build directory and correct it to override SYMBOL_RAM_START. This one works because the linker first looks for linker scripts and files included by linker scripts in the current folder.

What not:

  • Unfortunately, our stakeholders believe that the above method is too risky and difficult to understand. I would like to override the symbol value on the linker command line with something like below:

    • gcc $(OBJS) -l$(Lib1) -l$(Lib2) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections, --defsym=SYMBOL_RAM_START=$(VALUE_TO_OVERRIDE) -o$(OUTPUT).elf

    • gcc $(OBJS) -l$(Lib1) -l$(Lib2) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections --defsym=SYMBOL_RAM_START=$(VALUE_TO_OVERRIDE) -o$(OUTPUT).elf

    • gcc $(OBJS) -l$(Lib1) -l$(Lib2) --defsym=SYMBOL_RAM_START=$(VALUE_TO_OVERRIDE) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections -o$(OUTPUT).elf

None of them seem to affect the linked image created by the linker.

  • Can --defsym override characters defined by a reference sheet specified with -T?
  • Can any of you see what I'm doing wrong here?
+8
gcc ld linker-scripts
source share
1 answer

Waiting for someone to answer, I solved the problem. There are several problems with this problem, and I thought about explaining my findings to those who might make the same mistake.

First of all, any options that must be passed to the linker must be specified with -Xlinker or with -Wl. Therefore, both 2 and 3 will not work in the above case. Corrected 2 and 3 will be as follows:

  • Right already

  • gcc $(OBJS) -l$(Lib1) -l$(Lib2) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections -Xlinker --defsym=SYMBOL_RAM_START=$(VALUE_TO_OVERRIDE) -o$(OUTPUT).elf

  • gcc $(OBJS) -l$(Lib1) -l$(Lib2) -Xlinker --defsym=SYMBOL_RAM_START=$(VALUE_TO_OVERRIDE) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections -o$(OUTPUT).elf

Now for the case of options 1 and 2 above, --defsym appears after the script linker and SYMBOL_RAM_START has already been defined by the linker script. He cancels it. But an overridden value will not be used, since sections are already defined as the script builder has already been used.

In case of option 3 above, SYMBOL_RAM_START was defined before the linker script was read by the linker. Therefore, when the script linker is parsed, the value specified in the script overrides it.

Decision:

For this to work, the script linker must conditionally initialize the SYMBOL_RAM_START symbol, something like below:

SYMBOL_RAM_START = DEFINED ( SYMBOL_RAM_START )? SYMBOL_RAM_START : DEFAULT_VALUE;

Given the script in the linker above, when SYMBOL_RAM_START was defined before the script linker was enabled (as shown in option 3 above), it really worked. But in the end I had to fix the linker script.

This solution does not actually override the character, but provides a way in which the character can be defined so that it can be redefined.

+12
source share

All Articles