C 派到底做什么?

C 派到底做什么?,c,linux,gcc,linker,code-generation,C,Linux,Gcc,Linker,Code Generation,I文件/bin/ls并获得输出: /bin/ls:ELF 64位LSB共享对象,x86-64,版本1(SYSV),动态链接,解释器/lib64/ld-linux-x86-64.so.2,适用于GNU/linux 2.6.32,剥离 我发现原因是我的gentoo正在用-pie编译所有东西 如果我通过gcc的-nopie,我将得到正确的答案: a、 out:ELF 64位LSB可执行文件,x86-64,版本1(SYSV),动态链接,解释器/lib64/ld-linux-x86-64.so.2,用于G

I
文件/bin/ls
并获得输出:

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

我发现原因是我的gentoo正在用-pie编译所有东西

如果我通过gcc的-nopie,我将得到正确的答案:

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

还有,我在网上找到了一些东西。它使用-pie来生成DSO可执行文件

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

-馅饼
在支持位置独立的目标上生成位置独立的可执行文件

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

区分“可执行文件”和“共享对象”在很大程度上是人为的。
file
命令向您显示的是ELF
e\u type
头是
ET\u EXEC
还是
ET\u DYN
。这是一个相当技术性的区别,与加载器如何处理它们有关<代码>文件(通过其魔法文件)可能应该通过查找其他特征(如存在
PT_INTERP
程序头(库通常不会有)或入口点地址)来区分“共享对象”(在“共享库”和“饼图可执行文件”的意义上)(尽管有些图书馆似乎没有什么意义)

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