2

我有两个函数,a()b(),它们都有特定的、固定的加载/运行时地址。我正在编译a()自己,而b()已经提供(例如在 ROM 中)。

该文件a.c如下:

extern void b(void);

void a(void) {
    b();
}

这将生成以下汇编代码:

00000000 <a>:
   0:   08000000       j 0 <a>
                       0: R_MIPS_26 b
   4:   00000000       nop

所以它在那里放置了一个 26 位的重定位b()(调用的目标是从调用指令本身的地址开始的 26 位偏移量)。假设 和 的具体地址a分别b为 0x80001000 和 0x80002000。那应该没问题;b很容易触手可及a

所以在我的链接器脚本中,我有这样的东西:

SECTIONS {
    a = 0x80001000;
    b = 0x80002000;

    .text : AT(0x80000000) {
        *(.text)
    }
}

但是,a.o与此脚本链接会给我以下错误:

a.o: In function 'a':
(.text+0x0): relocation truncated to fit: R_MIPS_26 against `b`

据推测,这是因为链接器试图将完整的 32 位值 ( 0x80002000) 放入 26 位空间中以供跳转目标使用。我的链接器脚本有什么问题?

4

1 回答 1

1

尝试使用long_call属性:

__attribute__((long_call))
extern void b(void);

所有 MIPS 属性的手册都在这里

于 2018-12-16T18:08:15.987 回答