Перемещение 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
со скрытой функцией и скрытым псевдонимом вызов всегда будет идти к одной и той же функции, т. е. больше невозможно вставить символ для этого конкретного сайта вызова.