Reputation: 28872
On gcc target machines, when one wanted to compile a shared library, one would need to specify -fpic or -fPIC to get things to work correcly. This is because by default absolute addressing was used, which is suitable for executable that have full control of their own address space, but not shared libraries, which could be loaded anywhere in an executable's address space.
However modern kernels are now implementing address space randomization and many modern architectures support PC relative addressing. This all seems to make the absolute addressing either unusable (address space randomization) or unneeded (PC relative addressing).
I have also noticed that clang does not have an -fPIC option which makes me think that it is no longer necessary.
So is -fPIC now redundant or does one need to generate separate .o files, one for static library use, and one for shared library use?
Upvotes: 14
Views: 7257
Reputation: 126120
It depends on the target. Some targets (like x86_64) are position independent by default, sp -fpic
is a noop and has no effect on the generated code. So in those cases you can omit it and nothing changes. Other targets (like x86 32-bit) are not position independent by default, so on those machines, if you omit -fpic
for the executable, it will disable ASLR for that image file (but not for shared libraries it uses).
Upvotes: 3
Reputation: 22074
gcc
targets a lot of platforms and architectures, and not all of them supports natively PIC like the x86 architecture does. In some cases, creating PIC means additional overhead, which may be undesired, and wether you want or need this is depending on your project and the platform you are targeting,.
Upvotes: 0
Reputation: 20392
You still need to compile with -fPIC. The problem isn't solvable with pc-relative addressing. The problem is how you resolve external symbols. In a dynamically linked program the resolution follows different rules and especially with adress space randomization it can't be resolved during link time.
And clang does have the -fPIC flag just like gcc.
$ cat > foo.c
void foo(void);
void bar(void) { foo(); }
$ gcc -S foo.c && grep call.*foo foo.s
call foo
$ gcc -fPIC -S foo.c && grep call.*foo foo.s
call foo@PLT
$ clang -S foo.c && grep call.*foo foo.s
callq foo
$ clang -fPIC -S foo.c && grep call.*foo foo.s
callq foo@PLT
$
Upvotes: 7
Reputation: 2882
I agree with you: in many cases the -fpic/-fPIC options are almost redundant, I do however use them to ensure:
Upvotes: 1
Reputation: 283614
You never needed to generate separate .o
files. Always specify the compiler options to generate portable code (typically -fPIC
).
On some systems, the compiler may be configured to force this option on, or set it by default. But it doesn't hurt to specify it anyway.
Note: One hopes that where PC-relative addressing is supported and performs well, that -fPIC
uses that mode rather than dedicating an extra register.
Upvotes: 0