我怎么能告诉,像objdump,如果一个对象文件已经build立了-fPIC?

我怎么能告诉,像objdump ,如果一个对象文件已经build立了-fPIC

答案取决于平台。 在大多数平台上,如果从输出

 readelf --relocs foo.o | egrep '(GOT|PLT|JU?MP_SLOT)' 

是空的,那么foo.o不是用-fPIC编译的,或者foo.o不包含任何代码,其中-fPIC重要。

我只需要在PowerPC目标上执行此操作即可find正在构build哪个共享对象(.so)而没有-fPIC。 我所做的是运行readelf -d libMyLib1.so并寻找TEXTREL。 如果您看到TEXTREL,构成.so的一个或多个源文件不是用-fPIC构build的。 如有必要,你可以用elfdumpreplacereadelf

例如,

 [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]$ 

为了帮助人们寻找解决scheme,我运行可执行文件时遇到的错误是:

 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 

我不知道这个信息是否适用于所有架构。

资料来源: blogs.oracle.com/rie

 readelf -a * .so |  grep标志
  标志:0x50001007,noreorder,图片,cpic,o32,mips32

这应该大部分时间工作。

-fPIC意味着代码将能够以与编译的地址不同的地址执行。

要做到这一点,disasambler将看起来像这样….调用get_offset_from_compilation_address get_offset_from_compilation_address:pop ax sub ax,ax,&get_offset_from_compilation_address

现在我们有一个偏移量,我们需要添加到任何访问内存。 加载bx,[ax + var_address}

我想,你真正想知道的是共享库是否由用-fPIC编译的目标文件组成。

如前所述,如果有TEXTREL,则不使用-fPIC。

有一个很好的工具叫做scanelf,它可以显示导致.text重定位的符号。

更多信息可以在HOWTOfind并修复.text重新定位TEXTRELs 。

另一个选项来区分你的程序是否生成了-fPIC选项:

前提是您的代码在编译时启用了-g3 -gdwarf-2选项。

其他gccdebugging格式也可能包含macros信息:

注意下面的$'..'语法是假定bash

 echo $' main() { printf("%d\\n", \n#ifdef __PIC__\n__PIC__\n#else\n0\n#endif\n); }' | gcc -fPIC -g3 -gdwarf-2 -o test -xc - readelf --debug-dump=macro ./test | grep __PIC__ 

这样的方法是可行的,因为gcc手册声明如果使用-fpic, PIC定义为1,如果使用-fPIC,则PIC为2。

通过检查GOT的上述答案是更好的方法。 因为-g3 -gdwarf-2的预先请求我很less被使用。