如何为 GCC 代码指定手动重定位?

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,但假装它位于“此处”

编辑:我能够解决这个问题,事实证明,我需要修改的函数单独保存在链接器脚本中。我可以在链接器脚本中将其切换出来。虽然我仍然很想知道答案,但我现在有一个解决方法。

jcm*_*kbc 5

在链接描述文件中,每个输出节都有两个关联的地址: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)

应该做你想做的事。