Lab environments:
- Ubuntu 18.04, gcc 7.5.0, binutils 2.30 (2019-05-08)
- openSUSE Leap 15.5, gcc 7.5.0, binutils 2.39 (2022-10-25)
I realize this problem when building a small .so file from foo1.c
.
#include <stdio.h>extern void FooX(int);void Foo1(int i){ printf("foo1(%d)\n", i); i++; FooX(i);}
On openSUSE, compile it using commands:
gcc -g -c foo1.cgcc -shared foo1.o -o libfoo1.so
The second command fails with error message:
ld: foo1.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
As suggested by above ld
error message. I go back and do gcc -g -c -fPIC foo1.c
, then ld
succeeds.
But on Ubuntu 18.04, I do not have to explicitly assign -fPIC
to gcc.
So, on openSUSE, the foo1.o
must have different machine code when it lacks vs has -fPIC
.
I make some effort to compare them on openSUSE.
gcc -g -c foo1.cmv foo1.o foo1-noPIC.ogcc -g -c -fPIC foo1.cmv foo1.o foo1-PIC.oobjdump -dSlr -M intel foo1-noPIC.o > foo1-noPIC.txtobjdump -dSlr -M intel foo1-PIC.o > foo1-PIC.txt
Below is the difference between foo1-noPIC.txt
and foo1-PIC.txt
:
I also do this on Ubuntu, and foo1-noPIC.txt
and foo1-PIC.txt
have same content, and they equal openSUSE's foo1-PIC.txt
.
Now, I confirm that Ubuntu's gcc implies -fPIC
for us.
Then, my question is, is such difference hard codeded into a Linux-distro's gcc binary, or, is it affected by some configuration file on a Linux distro? If latter, which configuration file?