Lets say I have a code.c with two ordinary functions outer and inner.
outer calls inner.
I use GCC 11.2 on Linux, x86-64.
If I compile a shared lib with
gcc -shared -fPIC -O3 code.c
and look at the disassembly of
objdump -d a.out
I can see that the ´inner´ call withoin outer uses the PLT and is not inlined.
Thats fine and how it should be now even inner-library calls can eg. replaced by LD_PRELOAD.
If I add a main function and compile an executable instead
gcc -fPIE -O3 code.c
the call is inlined (if small enough etc.) an doesn`t use the PlT.
Fine too.
My problem is this call, a non-library executable with fPIC
gcc -fPIC -O3 code.c
Now the inner´ call does not use the PLT (but is not inline either). The unlinked asm (gcc call with -S) still uses the PLT, just the full binary and its disassembly not anymore. Adding an explicit -fsemantic-interposition` does not help.
Questions
How can I have PLT calls in my program that is not a library so that things like LD_PRELOAD work even for the functions there?
And whats the point of the non-shared fPIC behaviour to prevent inlining without using the PLT?