Используя GNU ld, как я могу принудительно указать адрес определенного (внешнего) символа, не получая усеченную ошибку перемещения?

У меня есть две функции, 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-битное пространство для цели перехода. Что не так с моим скриптом компоновщика?


person Vegard    schedule 09.05.2013    source источник
comment
Для справки, это кажется актуальным: sourceware.org/ml/binutils/2009-06. /msg00132.html   -  person Vegard    schedule 09.05.2013
comment
Я не могу помочь со сценарием компоновщика, но альтернативным решением было бы использование указателей на функции. Для всего лишь пары функций это было бы не слишком много работы.   -  person Michael    schedule 09.05.2013
comment
Вы пробовали использовать b=0x2000 в скрипте? Это значение, которое компоновщик должен вставить в инструкцию J.   -  person markgz    schedule 10.05.2013


Ответы (1)


Попробуйте использовать атрибут long_call:

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

Руководство по всем атрибутам MIPS находится здесь.

person Sauron    schedule 16.12.2018