I am trying to build shared libraries that has some functions in assembly that call other functions. When I build liba.so
with code
void aFunc1()
{
}
asm(
".globl aFunc2\n\t"
".type aFunc2, @function\n\t"
"aFunc2:\n\t"
".cfi_startproc\n\t"
"call aFunc1\n\t" /* note here*/
"ret\n\t"
".cfi_endproc\n\t"
);
and command
gcc -o liba.so a.c -shared -fPIC
I got error
/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
It tells me to use option -fPIC
but I just already use that option! However I find out that with option -Wl,-Bsymbolic
it compiles fine.
gcc -o liba.so a.c -shared -fPIC -Wl,-Bsymbolic
Unfortunately problem comes back when I try build second library libb.so
also with assembly functions that try call functions from first library. Compiling code
#include <a.h>
asm(
".globl bFunc2\n\t"
".type bFunc2, @function\n\t"
"bFunc2:\n\t"
".cfi_startproc\n\t"
"call aFunc1\n\t" /* note here*/
"ret\n\t"
".cfi_endproc\n\t"
);
with command
gcc -o libb.so b.c liba.so -shared -fPIC -Wl,-Bsymbolic
gives error
/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
and as you can see option -Wl,Bsymbolic
doesn't help.
I want to know how to build second library and why first library needs -Wl,Bsymbolic
option. I am not assembly master so I don't know if it is correct — I'm trying to build someone else library. Maybe I should use other options?
You need to call either the PLT stub because the function could have been interposed (making the call no longer direct, with a fixed offset):
call aFunc1@plt
With -Bsymbolic
, the linker will turn this into a call to aFunc1
(without the double indirection).
You can also call the function via the GOT, similar to what the PLT stub does:
jmp *aFunc1@GOTPCREL(%rip)
Or you can make the function hidden:
.hidden aFunc1
jmp aFunc1
Note that his will make the definition hidden as well, so the function is no longer exported. To emulate the behavior of -Bsymbolic
for a single symbol, you can use a hidden alias:
.set aFunc1Alias, aFunc1
.hidden aFunc1Alias
jmp aFunc1Alias
With the hidden function and the hidden alias, the call will always go to the same function, i.e., it is no longer possible to interpose the symbol for this particular call site.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With