Var*_*iya 1 executable operating-system kernel coff portable-executable
我正在学习操作系统的概念.我自己设法创建了一个启动加载程序.我生成的每个可执行文件都在BIN中.我看到微软为其系统使用了PE文件格式.同样Unix使用COFF.这些多种文件格式有什么用?与其他相比,他们是否有任何文件保护或附加功能?
从历史上看,目前使用的通用目标文件格式,PECOFF,ELF和Mach-O是针对特定操作系统(Windows NT,Unix System V R4和Mach)完全独立开发的,旨在解决以前目标文件格式的缺点.
Unix使用的最早的目标文件和可执行格式是a.out格式.这是一种非常简单的格式,几乎是当时硬件所需的最低限度.它的名称取决于Unix汇编程序和链接器使用的默认输出文件名.如果未指定输出文件,则这些程序将创建一个名为的文件a.out.今天大多数Unix汇编程序和链接器仍然这样做.
在Unix System V中,AT&T引入了COFF(通用目标文件格式)来替换a.out格式.它也是一种可执行文件和目标文件格式.它改进了a.out格式的主要内容是多个部分.a.out格式仅支持带有隐含.bss部分的文本和数据部分.多个部分为工具和应用程序提供了布局可执行文件的更大灵活性,允许它们创建例如只读数据部分.COFF还增加了对共享库的支持.
为了解决COFF的许多问题,AT&T为Unix System V R4创建了ELF(可执行和可链接格式).COFF的主要问题是不够灵活且定义明确,因此必须由各种实施的供应商以各种不兼容的方式进行扩展.它不是希望的"共同"格式.ELF还为位置无关的共享对象提供支持,其具有比COFF共享库更动态的符号链接形式.它还有一个相当复杂和可扩展的相关调试格式,称为DWARF.
在Unix机器上,ELF是主要的可执行文件和目标文件格式.只有少数像AIX这样的操作系统坚持使用他们自定义的基于COFF的格式.所有大型开源操作系统,Linux和BSD都使用ELF,但值得注意的是,他们直接从基于a.out的格式转到ELF,跳过了COFF.由于ELF是目标文件格式和可执行格式,这意味着大多数Unix开发工具会创建链接在一起以创建ELF可执行文件的ELF对象.
在MS-DOS下,标准目标文件格式是Intel为其x86处理器创建的OMF(对象模块格式).MS-DOS本身使用了两种不同的可执行格式.起初它只支持简单的.COM文件,只是像引导程序一样的平面二进制文件,取自CP/M(就像MS-DOS 1.x中的几乎所有内容).使用MS-DOS 2.0,Microsoft添加了对"MZ".EXE可执行文件的支持,因为它使用两个字符MZ作为幻数来标识文件类型.MZ格式允许可执行文件使用多个段,而.COM格式有效地将程序限制为单个64K段.Microsoft自己的MS-DOS开发工具以及大多数其他第三方工具生成了OMF格式的目标文件,这些文件被链接到创建.COM和MZ格式的可执行文件.
对于Windows 1.0,Microsoft 为Windows可执行文件创建了新的可执行文件(NE)格式.这种格式的关键特征是它在可执行文件中显示了段,显示了它们的起始位置和结束位置.MZ格式通过重新定位代码中的段值来支持段.否则它是一个平面二进制文件,在一个连续的块中加载到内存中,就像.COM文件一样,除了段引用被修复了.在可执行文件中显式显示段允许Windows单独加载段,甚至可能移动它们并根据需要卸载它们.由于Windows与MS-DOS不同,支持一次运行多个程序,因此这非常重要,否则内存很快就会变得过于分散.NE格式添加的另一个重要功能是支持DLL(动态链接库).
但是Microsoft没有更改使用的目标文件格式.微软用于早期16位版本Windows的开发工具(以及16位版本的OS/2)继续创建链接以创建NE格式可执行文件的OMF目标文件.OMF格式易于扩展,并且NE格式仅需要少量添加,最明显的是用于导入和导出DLL的符号.
对于Windows/386 2.10,Microsoft创建了另一种名为Linear Executable(LE)的可执行格式.这个新版本的Windows有一个32位的虚拟机管理器(VMM),本质上是一个简单的虚拟机,可以并行运行Windows和一个或多个MS-DOS实例.对于每个操作系统来说,看起来他们拥有整个PC,但实际上它只是一个虚拟机.由于VMM,更重要的是它的驱动程序(VxD)是32位,它们旧的16位NE格式不起作用.
我不确定最初创建LE可执行文件时使用的对象格式.之后,在创建VxD时使用PECOFF目标文件成为标准,但直到几年后才创建该格式.他们可能使用OMF,扩展为支持32位对象,就像IBM对OS/2 2.0所做的那样,OS/2 2.0也使用了LE格式的32位可执行文件.
微软在Windows NT上推出了PECOFF.虽然它们已经是可用的32位可执行格式,LE格式和OMF支持的32位对象,但这两种格式都与英特尔x86处理器相关联.Windows NT旨在支持多种CPU,最初它支持MIPS和DEC Alpha CPU以及基于x86 Intel的PC.开发Windows NT的团队决定调整已支持多个CPU的现有Unix COFF格式,而不是让LE和OMF适应这些其他处理器.我的猜测是,早期的Microsoft Windows NT团队正在使用现有的基于Unix的开发工具来开发Windows NT,而不是等待Microsoft的独立开发工具团队为其他CPU创建工具.否则Windows NT可能会有LE和OMF格式的改编版本,如果只是为了让开发工具团队的工作更轻松.
PECOFF在COFF上添加的主要功能是对DLL的支持,这是Windows从一开始就固有的东西.COFF支持类似但不同的共享库机制.Microsoft后来扩展了PECOFF格式以支持64位CPU.
由于PECOFF既是目标文件格式又是可执行文件,因此用于32位版本Windows的Microsoft开发工具会创建链接以创建PECOFF可执行文件的PECOFF目标文件.值得注意的是,Borland的工具生成了OMF文件,这些文件被链接以创建PECOFF可执行文件,但是现在大多数其他工具都遵循微软的主导(例如MinGW或Intel的ICC).
Mach-O格式是为Mach内核创建的,因此得名.该内核用于NeXTSTEP,后者成为Apple OS X的基础.Mach-O格式是作为BSD使用的a.out格式的替代品而创建的,BSD提供了大多数基于Mach的操作系统的非内核部分.主要驱动力似乎是创建位置独立的共享库和可执行文件.Mach-O和使用它的操作系统的一个特点是所有代码都需要与位置无关,而不仅仅是共享库.
因此,您可以看到在不同操作系统上工作的不同人群已经独立工作,以根据他们当时的需求创建这些不同的格式.早期微软需要格式来支持Intel x86特有的分段内存模型,而OMF是唯一支持它的目标文件格式.Unix需要不同的东西,支持多个CPU.当Microsoft需要多个CPU支持时,他们选择将其格式基于最近废弃的COFF格式,当时这种格式可能是在比新的ELF格式更多的CPU类型上实现的.与此同时,Mach内核开发人员在他们自己的世界中离职,徒劳地试图创建一个可行的微内核.我不确定他们用Mach-O究竟在想什么,但是他们不得不用其他东西替换a.out,我猜COFF不能胜任任务而且ELF还不存在.