GNU LD:如何覆盖使用-T指定的链接描述文件定义的符号值(地址) [英] GNU LD: How to override a symbol value (an address) defined by the linker script specified using -T

查看:485
本文介绍了GNU LD:如何覆盖使用-T指定的链接描述文件定义的符号值(地址)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的用例如下:


  • 我使用基于Makefile的项目的典型SDK
  • 我相信链接器已修补gcc。 gcc --version给我4.3.4

  • SDK定义链接器脚本(可称为Linker.ld)
  • Linker.ld包含LinkerMemMap。 cfg,它为链接的ELF图像中的各个部分定义绝对地址。
  • SDK提供基于Makefiles(GNU Make 3.81)的应用程序模板并使其自己

  • 在SDK提供的Makefile模板中,当调用 gcc 时,Linker.ld提供了-T命令行选项,如下所示:


$ gc $(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)

    我的要求如下:我想使用Linker.ld中定义的部分,并根据LinkerMemMap.cfg使用内存映射,但是可以调整LinkerMemMap中定义的特定符号(让它称为SYMBOL_RAM_START)。 cfg


有什么作用:


  • 在连接最终的ELF映像之前尝试了makefile,将LinkerMemMap.cfg(包含在Linker.ld中)复制到build目录并修补它以重新定义SYMBOL_RAM_START。这个确实有效,因为链接器首先搜索链接描述文件和链接描述文件包含的文件。



什么不是:


  • 不幸的是,我们的利益相关者认为上述方法风险太大且难以理解。我想重写链接器命令行上的符号值,如下所示:


    1. gcc $(OBJS)-l $(Lib1)-l $(Lib2)-nostdlib -lgcc -L $(library_path)-g -msmall -m -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) 。$ gcc $(OBJS)-l $(Lib1)-l $(Lib2)。

    2. -nostdlib -lgcc -L $(library_path)-g -msmall -m -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


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





这些都不会对由链接器。


  • --defsym是否可以覆盖由使用-T指定的linkerscript定义的符号?

  • 你们中的任何人都能看到我在这里做错了什么吗?


解决方案

在等待某人回复时,我确实解决了这个问题。这里的问题几乎没有问题,我想为可能犯同样错误的人解释我的发现。

首先任何要传递给链接器的选项必须用-Xlinker或-Wl指定。因此,在上述情况下,2和3都不起作用。更正后的2和3将如下所示:


  1. 已经正确


  2. gcc $(OBJS)-l $(Lib1)-l $(Lib2)-nostdlib -lgcc -L $(library_path)-g -ms -mama-mode -mconst-switch- table -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


  3. 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


现在选择1&在上面的图2中,--defsym在链接器脚本之后,并且 SYMBOL_RAM_START 已由链接器脚本定义。它覆盖它。但是重写值不会被使用,因为这些部分已经被定义为链接描述文件已经被使用了。



对于上述选项3的情况, b> SYMBOL_RAM_START 是在链接器脚本被链接器读取之前定义的。因此,当链接器脚本被解析时,脚本中指定的值将覆盖它。

解决方案:

为了达到这个目的,链接器脚本需要有条件地初始化符号 SYMBOL_RAM_START ,如下所示:



SYMBOL_RAM_START = DEFINED( SYMBOL_RAM_START )? SYMBOL_RAM_START :DEFAULT_VALUE;



在定义了 SYMBOL_RAM_START 的情况下,在包含链接器脚本之前(如上面的选项3所示)它确实有效。但最终我不得不修补链接器脚本。



这个解决方案并没有真正覆盖这个符号,但提供了一种方式来定义一个符号,以便它可以被覆盖。


My usecase is as follows:

  • I am using a typical SDK that comes with Makefile based projects
  • I belive the linker is patched gcc. gcc --version gives me 4.3.4
  • SDK defines the linker script (lets call it Linker.ld)
  • Linker.ld includes LinkerMemMap.cfg, which defines the absolute addresses for various sections in the linked ELF image
  • SDK provides application templates based on Makefiles (GNU Make 3.81) and make itself
  • In the SDK provided Makefile template, when gcc is invoked the Linker.ld is provided with -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 the sections as defined in Linker.ld and use the memory map as per LinkerMemMap.cfg however tweak a particular symbol(lets call it SYMBOL_RAM_START) defined in LinkerMemMap.cfg

What works:

  • I have tried in the makefile, prior to linking the final ELF image, copy the LinkerMemMap.cfg (which is included by Linker.ld) to the build directory and patch it to redefine SYMBOL_RAM_START. This does work as the linker searches for the linker scripts and the files included by the linker scripts in the current folder first.

What doesn't:

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

    1. 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

    2. 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

    3. 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 these seem to have any effect on the linked image created by the linker.

  • Can --defsym override the symbols defined by linkerscript specified using -T?
  • Could any of you please see what am I doing wrong here?

解决方案

While waiting for someone to respond, I did resolve the issue. There are few issues with the problem here and I thought of explaining my findings for someone who might do the same mistake.

First of all Any options to be passed to the linker must be specified with -Xlinker or with -Wl. Hence both 2 and 3 won't work in the above case. The corrected 2 and 3 would be as follows:

  1. Is correct already

  2. 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

  3. 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 & 2 above, --defsym comes after linker script and SYMBOL_RAM_START was already defined by the linker script. It does override it. But the overriden value will not be used, because the sections have already been defined as the linker script has already been used.

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

Solution:

In order for this to work, the linker script will need to conditionally initialize the symbol SYMBOL_RAM_START, something like below:

SYMBOL_RAM_START = DEFINED( SYMBOL_RAM_START ) ? SYMBOL_RAM_START : DEFAULT_VALUE ;

Given the above in the linker script, when the SYMBOL_RAM_START was defined before the linker script is included (as shows in option 3 above) it did work. But in the end I had to patch the linker script.

This solution doesn't really override the symbol, but provides a way in which a symbol can be defined so that it can be overridden.

这篇关于GNU LD:如何覆盖使用-T指定的链接描述文件定义的符号值(地址)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆