Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Relocation R_X86_64_PC32 against symbol when calling function from inline assembly

Tags:

c

gcc

assembly

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?

like image 748
Mateusz Drost Avatar asked Jan 21 '18 17:01

Mateusz Drost


1 Answers

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.

like image 99
Florian Weimer Avatar answered Oct 20 '22 23:10

Florian Weimer