Reputation: 507155
Compiling code to an object file needs to be done position-independent if the object file is intended to be loaded as a shared library (.so
), because the base virtual address that the shared object file is loaded into in different processes may be different.
Now I didn't encounter errors when I tried to load an .so
file compiled and linked without the -fpic
GCC option on 32bit x86 computers, while it fails on 64bit bit x86 computers.
Random websites I found say that I don't need -fpic
on 32bit because code compiled without -fpic
works by coincidence according to the X86 32bit ABI also when used in a position-independent manner. But I still found software that ship with separate versions of libraries in their 32bit versions: One for PIC, and one for non-PIC. For example, the intel compiler ships with libirc.a
and libirc_pic.a
, the latter being compiled for position-independent mode (if one wants to link that .a
file into an .so
file).
I wonder what the precise difference between using -fpic
and not using it is for 32bit code, and why some packages, like the intel compiler, still ship with separate versions of libraries?
Upvotes: 14
Views: 1382
Reputation: 215457
It's not that non-PIC code works "by coincidence" on x86 (32-bit). It's that the dynamic linker for x86 supports the necessary "textrels" needed to make it work. This comes at a very high cost in memory consumption and startup time, since basically the entire code segment must be patched up at load time (and thus becomes non-shareable memory).
The dynamic linker maintainers claim that non-PIC shared libraries can't be supported on x86_64 because of fundamental issues in the architecture (immediate address displacements can't be larger than 32-bit) but this issue could be easily solved by just always loading libraries in the first 4gb of virtual address space. Of course PIC code is very inexpensive on x86_64 (PIC isn't a performance-killer like it is on 32-bit x86) so they're probably right to keep it unsupported and prevent fools from making non-PIC libraries...
Upvotes: 10
Reputation: 283773
the base virtual address that the shared object file is loaded into in different processes may be different
Because shared objects usually load at their preferred address, they may appear to work correctly. But fPIC
is a good idea for all shared code.
I believe the reason that there aren't often two versions of the library is that many distributions use fPIC
as the default for all code.
Upvotes: 0