-pie到底做了什么?

时间:2015-05-24 17:37:31

标签: c linux gcc linker code-generation

file /bin/ls并获得输出:

  

/ bin / ls:用于GNU / Linux 2.6的ELF 64位LSB共享对象,x86-64,版本1(SYSV),动态链接,解释器/lib64/ld-linux-x86-64.so.2 .32,剥离

我发现原因是我的gentoo正在使用-pie编译所有内容。

如果我将-nopie传递给gcc,我会得到正确答案:

  

a.out:用于GNU / Linux 2.6.32的ELF 64位LSB可执行文件,x86-64,版本1(SYSV),动态链接,解释器/lib64/ld-linux-x86-64.so.2 ,没有被剥夺

另外,我在building a .so that is also an executable找到了一些东西。它使用-pie来生成DSO。

在gcc的手册页中,它简要描述了:

  

-pie
  在支持它的目标上生成与位置无关的可执行文件。

所以我想知道-pie到底做了什么?它如何使我的可执行文件被识别为共享对象?

1 个答案:

答案 0 :(得分:4)

“可执行”和“共享对象”之间的区别在很大程度上是人为的。 file命令向您显示的是ELF e_type标头是ET_EXEC还是ET_DYN。这是一个相当技术性的区别,与装载机如何处理它们有关。应该教导file(通过它的魔法文件)通过寻找其他特征(如PT_INTERP的存在来区分“共享库”和“PIE可执行文件”意义上的“共享对象”。程序头(通常不会有库)或者可能是入口点地址(尽管有些库似乎没有意义)。

为了解决-pie的问题,它产生一个可以在任意基地址加载的可执行文件,而不是加载地址固定为ld - 时间的“普通”可执行文件。它们使用相同类型的与位置无关的代码和共享库中使用的加载头,它们也可以在任意地址加载(并且需要可以在任意地址加载,因为任何固定地址可能已经被占用由主要可执行文件或另一个库)。 PIE通常被认为是一种强化机制(允许地址随机化影响主程序中的代码和数据的地址),但它也可以有其他用途,例如使二进制文件更适合无MMU系统。