doron
doron

Reputation: 28872

Does one still need to use -fPIC when compiling with GCC?

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

Answers (5)

Chris Dodd
Chris Dodd

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

Devolus
Devolus

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

Art
Art

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

GMasucci
GMasucci

Reputation: 2882

I agree with you: in many cases the -fpic/-fPIC options are almost redundant, I do however use them to ensure:

  • portability (never sure what particular OS/kernel will be available)
  • backwards compatibility: with those options it ensures the behaviour you want on older kernels
  • habit - Hard things to break :)
  • compliance with older codebases that may require it

Upvotes: 1

Ben Voigt
Ben Voigt

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

Related Questions