Comment 19 for bug 1403758

Revision history for this message
In , V-thomas-i (v-thomas-i) wrote :

Attached a C-only testcase (forgot to rename the files from .cpp to .c, but I don't think that matters). The testcase simply outputs the function pointer of a function in a shared library, and one can see that the address is not the same.

Compile with:
gcc -fPIC -shared -Wall -o libshared.so -Wl,-Bsymbolic shared.cpp
gcc -fPIE -Wall -o main main.cpp -L. -lshared

The output on my machine is:
# ./main
0x8518
0x2ac595cc

The root of the problem seems to be that main gets the following undefined symbol:
   Num: Value Size Type Bind Vis Ndx Name
    14: 0000853c 0 FUNC GLOBAL DEFAULT UND testFunction()

This is a special hack - an undefined symbol that nevertheless has a value! See http://www.airs.com/blog/archives/42 for details on how that hack is supposed to work.
The idea is to use a different symbol value depending on the relocation type - a relocation for R_ARM_JUMP_SLOT should always resolve to the local PLT, but a relocation of type R_ARM_GLOB_DAT should use the symbol value defined in main. The problem is that libshared.so doesn't contain a R_ARM_GLOB_DAT relocation when taking the address of the function, but a R_ARM_RELATIVE relocation, and will therefore never resolve the function address to the value in main.
I guess this is a consequence of using -Bsymbolic - when taking the address of a function, it should still go through the GOT, with a R_ARM_GLOB_DAT relocation, despite -Bsymbolic being set.

Or at least that is what I think is the cause of the problem, I am by no means a Linker export, I only recently started being interested in this topic.