如果使用-fPIC构建目标文件,我怎么能用objdump这样的东西来判断?

时间:2009-08-27 11:15:12

标签: gcc shared-libraries objdump fpic

如果使用objdump构建目标文件,如何使用-fPIC之类的内容告诉我?

6 个答案:

答案 0 :(得分:59)

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

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

为空,然后foo.o未使用-fPIC进行编译,或者foo.o不包含-fPIC重要的任何代码。

答案 1 :(得分:12)

我只需要在PowerPC目标上执行此操作,以查找在没有-fPIC的情况下构建的共享对象(.so)。我做的是运行 readelf -d libMyLib1.so 并寻找TEXTREL。如果您看到TEXTREL,则构成.so的一个或多个源文件不是使用-fPIC构建的。如有必要,您可以将 readelf 替换为 elfdump

如,

[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

答案 2 :(得分:2)

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

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

有一个名为scanelf的好工具可以显示导致.text重定位的符号。

可以在HOWTO Locate and Fix .text Relocations TEXTRELs找到更多信息。

答案 3 :(得分:2)

readelf -a *.so | grep Flags
  Flags:                             0x50001007, noreorder, pic, cpic, o32, mips32

这应该在大部分时间都有效。

答案 4 :(得分:2)

-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}

答案 5 :(得分:0)

用于区分是否使用-fPIC选项生成程序的另一个选项:

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

其他gcc调试格式也可能包含宏信息:

请注意以下$'..'语法假定为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的预先请求我猜想很少被使用。