How can I tell, with something like objdump, if an object file has been built with -fPIC?
How can I tell, with something like objdump, if an object file has been built with -fPIC?
From The Linux Programming Interface:
On Linux/x86-32, it is possible to create a shared library using modules compiled without the
–fPICoption. However, doing so loses some of the benefits of shared libraries, since pages of program text containing position-dependent memory references are not shared across processes. On some architectures, it is impossible to build shared libraries without the–fPICoption.In order to determine whether an existing object file has been compiled with the
–fPICoption, we can check for the presence of the name_GLOBAL_OFFSET_TABLE_in the object file’s symbol table, using either of the following commands:$ nm mod1.o | grep _GLOBAL_OFFSET_TABLE_ $ readelf -s mod1.o | grep _GLOBAL_OFFSET_TABLE_Conversely, if either of the following equivalent commands yields any output, then the specified shared library includes at least one object module that was not compiled with
–fPIC:$ objdump --all-headers libfoo.so | grep TEXTREL $ readelf -d libfoo.so | grep TEXTREL
However, neither above quoting nor any answer of this question works for x86_64.
What I've observed on my x86_64 Ubuntu machine is that, whether specifying -fPIC or not, it would generate fPIC .o. That is
gcc -g -Wall -c -o my_so.o my_so.c // has _GLOBAL_OFFSET_TABLE_
gcc -g -Wall -fPIC -c -o my_so_fpic.o my_so.c // has _GLOBAL_OFFSET_TABLE_
readelf -s my_so.o > 1.txt && readelf -s my_so_fpic > 2.txt && diff 1.txt 2.txt
has no difference and both my_so.o and my_so_fpic.o can be used to create a shared library.
In order to generate non fpic object file, I found a gcc flag called -fno-pic in the first comment of How to test whether a Linux binary was compiled as position independent code? .
This works,
gcc -g —Wall -fno-pic -c -o my_so_fnopic.o my_so.c // no _GLOBAL_OFFSET_TABLE_
and
gcc -g -Wall -shared -o libdemo.so my_so_fnopic.o
gives error:
/usr/bin/ld: my_so_fnopic.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
collect2: error: ld returned 1 exit status
can not create a shared library with non pic .o.