2

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 ビットのオフセットです)。と の特定のアドレスがそれぞれ 0x80001000 と 0x80002000 であるとしますabそれでいいはずです。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