Shared objects (*.so) in Unix-like systems are inefficient because of the symbol interposition: Every access to a global variable inside the .so needs a GOT lookup, and every call from one function to another inside the .so needs a PLT lookup. I was therefore happy to see that gcc version 5.1 has added the option -fno-semantic-interposition. However, when I try to make a .so where one function calls another without using a PLT, I get the error message:
relocation R_X86_64_PC32 against symbol `functionname' can not be used when making a shared object; recompile with -fPIC
I expected the option -fno-semantic-interposition to eliminate this error message, but it doesn't. -mcmodel=large doesn't help either. The reference to the function is indeed position-independent, which the error message actually confirms (R_X86_64_PC32 means PC-relative 32-bit relocation in 64-bit mode). -fPIC does not really mean position-independent, as the name would imply, it actually means use GOT and PLT.
I cannot use __attribute__((visibility ("hidden")))
because the called function and the caller are compiled in seperate files (caller is in C++, called function is in assembly).
I tried to make an assembly listing to see what the option -fno-semantic-interposition does. I found out that it makes a reference to a local alias when one function calls another in the same file, but it still uses a PLT when calling a function in another file.
(g++ version is 5.2.1 Ubuntu, 64-bit mode).
Is there a way to make the linker accept a cross-reference inside a .so without the GOT/PLT lookup?