我处于嵌入式系统(xtensa处理器)中的情况,我需要手动覆盖符号,但符号恰好位于另一个符号的中间。当我尝试使用-Wl,--wrap=symbol
时,它将无效,因为符号不是它自己的东西。
我需要做的是指定代码最终会指定(最好在GCC .S中,但.c没问题)。虽然编译器会将实际符号放在某处,但我会memcpy
将代码放到正确的位置。
40101388 <replacement_user_vect>:
40101388: 13d100 wsr.excsave1 a0
4010138b: 002020 esync
4010138e: 011fc5 call0 4010258c <_UserExceptionVector_1>
我的问题是GCC创建具有相对跳转的程序集,假设代码将位于闪存中,而最终位置将在中断向量中修复。我如何告诉GCC / GNU“将代码放在任何你想要的地方,但相信我它实际上会从{here}执行”
虽然我的代码是0x40101388(GCC决定)但它最终会驻留并执行0x40100050。如何通过告诉它“将代码放在这里”来欺骗GCC,但假装它位于“HERE”
编辑:我能够解决这个问题,因为事实证明,我需要修改的函数分别保存在链接描述文件中。我能够在链接器脚本中将其切换出来。虽然我仍然想知道答案,但我现在有一个解决办法。
答案 0 :(得分:3)
在链接描述文件中,每个输出部分都有两个相关的地址:VMA和LMA - 代码链接的地址和代码加载的地址。
将需要重新定位的代码放入单独的部分,使用所需的VMA和LMA将输出部分添加到链接描述文件中,并将输入部分与其中的代码部分名称相匹配。
E.g。以下C代码
void f(void) __attribute__((section(".relocatable1.text")))
{
...
}
extern char _relocatable1_lma[];
extern char _relocatable1_vma_start[];
extern char _relocatable1_vma_end[];
void relocatable1_copy(void)
{
memcpy(_relocatable1_vma_start, _relocatable1_lma,
_relocatable1_vma_end - _relocatable1_vma_start);
}
与下面的ld脚本一起使用VMA替换为所需的目标代码位置
SECTIONS {
...
.some_section : { ... }
.relocatable1 VMA : AT(LOADADDR(.some_section) + SIZEOF(.some_section)) {
_relocatable1_vma_start = . ;
*(.relocatable1.literal .relocatable1.text) ;
_relocatable1_vma_end = . ;
}
_relocatable1_lma = LOADADDR(.relocatable1) ;
...
}
应该做你想做的事。