我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到底做了什么?它如何使我的可执行文件被识别为共享对象?
答案 0 :(得分:4)
“可执行”和“共享对象”之间的区别在很大程度上是人为的。 file
命令向您显示的是ELF e_type
标头是ET_EXEC
还是ET_DYN
。这是一个相当技术性的区别,与装载机如何处理它们有关。应该教导file
(通过它的魔法文件)通过寻找其他特征(如PT_INTERP
的存在来区分“共享库”和“PIE可执行文件”意义上的“共享对象”。程序头(通常不会有库)或者可能是入口点地址(尽管有些库似乎没有意义)。
为了解决-pie
的问题,它产生一个可以在任意基地址加载的可执行文件,而不是加载地址固定为ld
- 时间的“普通”可执行文件。它们使用相同类型的与位置无关的代码和共享库中使用的加载头,它们也可以在任意地址加载(并且需要可以在任意地址加载,因为任何固定地址可能已经被占用由主要可执行文件或另一个库)。 PIE通常被认为是一种强化机制(允许地址随机化影响主程序中的代码和数据的地址),但它也可以有其他用途,例如使二进制文件更适合无MMU系统。