我怎样才能知道,有像objdump
,如果目标文件已建成-fPIC
?
Answer 1:
答案取决于平台。 在大多数平台上,如果从输出
readelf --relocs foo.o | egrep '(GOT|PLT|JU?MP_SLOT)'
是空的,那么要么foo.o
未经编译-fPIC
,或foo.o
其中不包含任何代码-fPIC
事宜。
Answer 2:
我不得不这样做对PowerPC的目标找到其共享(的.so)正在建造不-fPIC对象。 我所做的就是运行readelf -d libMyLib1.so,寻找TEXTREL。 如果你看到TEXTREL,一个或多个源文件,使你的。所以没有用-fPIC建成。 如果需要,可以与elfdump替代readelf。
例如,
[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]$
并帮助人们寻找解决方案,当我跑我的可执行文件是这样的,我得到的错误:
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
Answer 3:
readelf -a *.so | grep Flags Flags: 0x50001007, noreorder, pic, cpic, o32, mips32
这应该工作的大部分时间。
Answer 4:
我想,你真的想知道的是,是否共享库是从与-fPIC编译的对象文件组成。
前面已经提到,如果有TEXTRELs,则没有使用-fPIC。
有一个伟大的工具,叫做scanelf它可以告诉你引起的.text重定位的符号。
更多信息,可以发现在HOWTO找到并修复的.text重定位TEXTRELs 。
Answer 5:
-fPIC意味着码将能够在不同的地址形式来执行,这是编译的地址。
要做到这一点,disasambler看起来像这样....
call get_offset_from_compilation_address
get_offset_from_compilation_address: pop ax
sub ax, ax , &get_offset_from_compilation_address
现在斧头我们已经偏移,我们需要增加内存的任何访问。
load bx, [ax + var_address}
Answer 6:
另一种方法来区分你的程序是否生成带有-fPIC选项:
前提是你的代码有-g3编译时启用-gdwarf-2选项。
其他海湾合作委员会调试格式也可能包含宏信息:
请注意以下事项$“..”语法是假设的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__
这种方法有效,因为gcc手册声明,如果-fpic被使用,PIC被定义为1,并且如果使用-fPIC,PIC是2。
以上答案通过检查GOT是更好的办法。 由于-g3 -gdwarf-2的prerequest我估计很少被使用。