How can I tell, with something like objdump, if an object file has been built with -fPIC?
Thanks, -Crazy Chenz
How can I tell, with something like objdump, if an object file has been built with -fPIC?
Thanks, -Crazy Chenz
Updated: please see comments for clarified information.
The --reloc and --dynamic-reloc options should list the relocation information. If it is not empty it has been compiled with -fPIC
The answer depends on the platform. On most platforms, if output from
objdump --reloc foo.o | egrep '(GOT|PLT|JU?MP_SLOT)'
is empty, then either foo.o
was not compiled with -fPIC
, or foo.o
doesn't contain any code where -fPIC
matters.
I just had to do this on a PowerPC target to find which shared object (.so) was being built without -fPIC. What I did was run readelf -d libMyLib1.so and look for TEXTREL. If you see TEXTREL, one or more source files that make up your .so were not built with -fPIC. You can substitute readelf with elfdump if necessary.
E.g.,
[user@host lib]$ readelf -d libMyLib1.so | grep TEXT # Bad, not -fPIC
0x00000016 (TEXTREL)
[user@host lib]$ readelf -d libMyLib2.so | grep TEXT # Good, -fPIC
[user@host lib]$
And to help people searching for solutions, the error I was getting when I ran my executable was this:
root@target:/# ./program: error while loading shared libraries: /usr/lib/libMyLi
b1.so: R_PPC_REL24 relocation at 0x0fc5987c for symbol 'memcpy' out of range
I don't know whether this info applies to all architectures.
Source: blogs.sun.com/rie
Another option to distinguish whether your program is generated wit -fPIC option:
provided that your code has -g3 -gdwarf-2 option enabled when compiling.
other gcc debug format may also contains the macro info:
Note the following $'..' syntax is assumes bash
echo $' main() { printf("%d\\n", \n#ifdef __PIC__\n__PIC__\n#else\n0\n#endif\n); }' | gcc -fPIC -g3
-gdwarf-2 -o test -x c -
readelf --debug-dump=macro ./test | grep __PIC__
such a method works because gcc manual declares that if -fpic is used, PIC is defined to 1, and if -fPIC used, PIC is 2.
The above answers by checking the GOT is the better way. Because the prerequest of -g3 -gdwarf-2 I guess seldom being used.