I've seen a lot of questions at SO asking why not all code is compiled as PIC or why we can't always use -fPIC
.
However all of the answers lack an explanation about what happens when your objects are compiled with -fPIC
but you link them to an executable that is not a PIE (position-independent executable).
From my understanding (using a few small examples and disassembling/inspecting them with readelf
), it looks like compiling with -fPIC
does not result in a different binary when linked without -pie -fPIE
.
My (simplistic?) explanation would be that during link time, it is known that the final executable is not intended to be relocatable, so we can resolve all addresses as in a non-PIC build and get rid of GOT and PLT completely. That is also my observation: If I build a PIE, readelf
displays a GOT/PLT section. If I don't build a PIE, the GOT/PLT is gone, no matter if I used -fPIC
or not.
My question is whether this observation
- is correct (as well as my explanation) and
- if not, why is my reasoning wrong then?
I found it surprisingly difficult to find a concrete answer to this simple question, that's why I'm asking here.