Mixing fPIC and non-fPIC object modules

Environment: Ubuntu 16.04

In my experiment, I ran the following commands:

gcc -c 1.c
gcc -c -fPIC 2.c
gcc -shared 1.o 2.o -o libmyxxx.so

      

The functions I need to expose are defined in 2.c via declarations extern "C"

. These functions internally call other functions defined in 1.c.

Note that I have not applied -fPIC

to 1.c. It still seems to compile / link fine without any warnings.

Can we conclude that it -fPIC

should only be applied to those source files that expose external functions?

In the enlarged picture, I have a bunch of archive files (.a) that may not have been compiled with the flag -fPIC

. I need to create my own shared library that will link to these archive files. If my guess is valid, I think it would be good to combine these archive files. Appreciate your thoughts. Regards.

+3


source to share


2 answers


Can we conclude that -fPIC should only be applied to source files that expose external functions?

No, we cannot. The sole purpose -fPIC

is to ensure that the resulting machine code can be associated with position-independent binary code. However, it's possible that some code looks PIC-ready even though the source was compiled without -fPIC

. These can be short, self-consistent functions with no external dependencies, regardless of whether they require additional data structures in the generated object file, such as PLT and GOT records.



Either way, the linker will fail with a complete error message if your object file cannot be linked to position-independent binary. And you need to recompile it with this magic option.

Therefore, you should always put -fPIC

in CFLAGS

your shared library just to save your time and avoid wasteful recompilation.

+1


source


If there is an object file in the executable that is compiled without the -fPIC flag, it will display pages of program text that reference dependent positions. These pages will not be able to be translated to the appropriate virtual memory addresses at runtime (which is basically the purpose of shared objects). When you build your code on some other machine, or link .so with some other code, these memory-dependent entries will come along and bytes you.

-fPIC is required to generate location-independent code for:



  • global variables
  • static variables
  • external variables
  • String constants
  • accepts function addresses

Also, you can get away without any warnings or errors when compiling / linking an object file without -fPIC on Linux / x86-32; but this cannot be done on some architectures.

+1


source







All Articles