Перемещение R X86 64 PC32 против символа при вызове функции из встроенной сборки

Я пытаюсь создать общие библиотеки, которые имеют некоторые функции в сборке, которые вызывают другие функции. Когда я строю liba.so С кодом

void aFunc1()
{
}

asm(
    ".globl aFunc2nt"
    ".type aFunc2, @functionnt"
    "aFunc2:nt"
    ".cfi_startprocnt"
    "call aFunc1nt" /* note here*/
    "retnt"
    ".cfi_endprocnt"
);

и команды

gcc -o liba.so a.c -shared -fPIC

я получил ошибку

/usr/bin/ld: /tmp/ccdGBiQv.o: relocation R_X86_64_PC32 against symbol `aFunc1' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status

он говорит мне, чтобы использовать опцию -fPIC но я уже использую эту опцию! Однако я узнаю, что с опцией -Wl,-Bsymbolic он компилирует нормально.

gcc -o liba.so a.c -shared -fPIC -Wl,-Bsymbolic

к сожалению, проблема возвращается, когда я пытаюсь построить второй библиотека libb.so также с функциями сборки, которые пытаются вызвать функции из первой библиотеки. Компиляция кода

#include <a.h>

asm(
    ".globl bFunc2nt"
    ".type bFunc2, @functionnt"
    "bFunc2:nt"
    ".cfi_startprocnt"
    "call aFunc1nt" /* note here*/
    "retnt"
    ".cfi_endprocnt"
);

С помощью

gcc -o libb.so b.c liba.so -shared -fPIC -Wl,-Bsymbolic

выдает ошибку

/usr/bin/ld: /tmp/ccaGvn5d.o: relocation R_X86_64_PC32 against symbol `aFunc1' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status

и как вы можете видеть вариант -Wl,Bsymbolic не помогает.

Я хочу знать, как построить вторую библиотеку и почему первая библиотека нуждается . Я не мастер сборки, поэтому я не знаю, правильно ли это - я пытаюсь создать чужую библиотеку. Возможно, мне стоит использовать другие варианты?

1 ответов


вам нужно вызвать либо заглушку PLT, потому что функция могла быть вставлена (делая вызов больше не прямым, с фиксированным смещением):

call aFunc1@plt

С -Bsymbolic, компоновщик превратит это в вызов aFunc1 (без двойной косвенности).

вы также можете вызвать функцию через GOT, аналогично тому, что делает заглушка PLT:

jmp *aFunc1@GOTPCREL(%rip)

или вы можете сделать функцию скрытой:

.hidden aFunc1
jmp aFunc1

обратите внимание, что его сделает определение скрыто, поэтому функция больше не экспортируется. Подражать поведению -Bsymbolic для одного символа можно использовать скрытый псевдоним:

.set aFunc1Alias, aFunc1
.hidden aFunc1Alias
jmp aFunc1Alias

со скрытой функцией и скрытым псевдонимом вызов всегда будет идти к одной и той же функции, т. е. больше невозможно вставить символ для этого конкретного сайта вызова.