这个测试运行在Ubuntu 12.04 64位的x86架构上。
我对位置无关可执行文件(PIE)和位置无关代码(PIC)的概念感到困惑,而且我猜它们不是正交的。
这是我的快速实验。
gcc -fPIC -pie quickSort.c -o a_pie.out
gcc -fPIC quickSort.c -o a_pic.out
gcc a.out
objdump -Dr -j .text a.out > a1.temp
objdump -Dr -j .text a_pic.out > a2.temp
objdump -Dr -j .text a_pie.out > a3.temp
我有以下发现。
A. a.out包含一些PIC代码,但仅仅存在于libc的序言和结语函数中,如下所示:
4004d0: 48 83 3d 70 09 20 00 cmpq $0x0,0x200970(%rip) # 600e48 <__JCR_END__>
在我编写的简单快速排序程序的汇编指令中,我没有找到任何PIC指令。
B. a_pic.out包含PIC代码,并且我没有找到任何非PIC指令... 在我的快速排序程序的指令中,所有全局数据都是通过像这样的PIC指令访问的:
40053b: 48 8d 05 ea 02 00 00 lea 0x2ea(%rip),%rax # 40082c <_IO_stdin_used+0x4>
C. a_pie.out的语法和a_pic.out相同,但是a_pie.out的.text段的内存地址范围从0x630到0xa57,而a_pic.out的相同部分范围从0x400410到0x400817。
有人能解释一下这些现象吗?特别是发现C。同时,我真的很困惑PIE vs. PIC,不知道如何解释C的发现。
-fPIE
代码生成选项,而不是-fPIC
。-pie
是一个链接器选项,用于控制代码实际放入哪种可执行文件中。(-pie
单独使用会失败,因为它与32位绝对寻址不兼容)。有关 PIE 可执行文件与非 PIE 的更多信息,请参见 32-bit absolute addresses no longer allowed in x86-64 Linux?。(请注意,大多数发行版都使用-fPIE -pie
作为默认值构建 GCC)。 - Peter Cordes