Cha*_*ohr 2 c assembly gcc relocation
我在嵌入式系统(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“将代码放在您想要的任何地方,但是,相信我,它实际上会从{这里}执行”
虽然我的代码位于 0x40101388(GCC 决定),但它最终将从 0x40100050 驻留并执行。如何通过告诉 GCC“将代码放在此处”来欺骗 GCC,但假装它位于“此处”
编辑:我能够解决这个问题,事实证明,我需要修改的函数单独保存在链接器脚本中。我可以在链接器脚本中将其切换出来。虽然我仍然很想知道答案,但我现在有一个解决方法。
在链接描述文件中,每个输出节都有两个关联的地址:VMA 和 LMA——代码链接的地址和代码加载的地址。
将需要重新定位的代码放入单独的部分中,使用所需的 VMA 和 LMA 将输出部分添加到链接器脚本中,并放置与其中代码部分的名称相匹配的输入部分。
例如下面的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);
}
Run Code Online (Sandbox Code Playgroud)
与以下 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) ;
...
}
Run Code Online (Sandbox Code Playgroud)
应该做你想做的事。
| 归档时间: |
|
| 查看次数: |
4048 次 |
| 最近记录: |