У меня есть две функции, a()
и b()
, каждая из которых имеет определенные фиксированные адреса загрузки/времени выполнения. Я компилирую a()
сам, а b()
уже предоставлен (например, в ПЗУ).
Файл 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-битное пространство для цели перехода. Что не так с моим скриптом компоновщика?
b=0x2000
в скрипте? Это значение, которое компоновщик должен вставить в инструкциюJ
. - person markgz   schedule 10.05.2013