Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

c

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?

like image 327
doron Avatar asked Dec 17 '13 14:12

doron


People also ask

Which GCC option should be used to do compilation?

The different options of gcc command allow the user to stop the compilation process at different stages. Most Useful Options with Examples: Here source. c is the C program code file. -o opt: This will compile the source.

Should I compile with GCC or G ++?

The usual way to run GCC is to run the executable called gcc , or machine-gcc when cross-compiling, or machine-gcc-version to run a specific version of GCC. When you compile C++ programs, you should invoke GCC as g++ instead.

What is the default program name when compiling with GCC?

By default, gcc assumes that you want to create an executable program called a.exe. Here are the common options that you'll use to change what gcc does. To change where the output file goes, use the -o option, like "gcc hello. c -o hello.exe".


2 Answers

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
$
like image 61
Art Avatar answered Oct 05 '22 06:10

Art


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
like image 26
GMasucci Avatar answered Oct 05 '22 05:10

GMasucci