Common object on Linux without character interpolation, -fno-semantic-interposition error

Shared objects (* .so) on Unix-like systems are inefficient due to character interpolation: every access to the global variable inside .so requires a GOT search and every call from one function to another inside .so requires a PLT search. So I was glad to see that gcc version 5.1 added the -fno-semantic-interposition option. However, when I try to do .so, when one function calls another without using PLT, I get an error:

moving R_X86_64_PC32 with the symbol `functionname 'cannot be used when creating a shared object; recompile with -fPIC

I expected the -fno-semantic-interposition option to clear this error message, but it is not. -mcmodel = large doesn't help either. The reference to the function is really position-independent, which actually confirms the error message (R_X86_64_PC32 means transferring 32-bit 32-bit in 64-bit mode). -fPIC does not really mean position independence, as it implies a name, it actually means using GOT and PLT.

I cannot use __attribute__((visibility ("hidden"))) because the called function and the calling object are compiled in separate files (the calling object is in C ++, called the function in assembly).

I tried to make a list of assemblies to see what the -fno-semantic-interposition option does. I found out that it refers to a local alias when one function calls another in one file, but when calling a function in another file, it still uses PLT.

(g ++ version is 5.2.1 Ubuntu, 64-bit mode).

Is there a way to get the linker to cross-reference inside .so without looking for a GOT / PLT?

+3
source share
1 answer

Is there a way to get the linker to cross-reference inside .so without looking for a GOT / PLT?

Yes: attribute((visibility("hidden"))) is exactly how to do this.

I cannot use the attribute ((visibility ("hidden"))) because the called function and the caller are compiled in separate files

You are confused: visibility("hidden") means that the symbol will not be exported from the shared library when it is finally linked. But the symbol is global and visible for several translation units up to this last link.

Evidence:

 $ cat t1.c extern int foo() __attribute__((visibility("hidden"))); int main() { return foo(); } $ cat t2.c int foo() __attribute__((visibility("hidden"))); int foo() { return 42; } $ gcc -c -fPIC t1.c t2.c $ gcc -shared t1.o t2.o -o t.so $ nm -D t.so | grep foo $ 

I tried to make a list of assemblies to see what the -fno-semantic-interposition option does. I found out that it refers to a local alias when one function calls another in one file, but when calling a function in another file, it still uses PLT.

If you read the discussion in gcc-patches, you will see that -fno-semantic-interposition allows you to enable the embedding of possibly interchangeable functions, rather than how they are actually called when they are not inline.

+5
source

Source: https://habr.com/ru/post/917184/


All Articles