如何将正在执行的可执行文件全部加载到内存_操作系统 - 链接器和加载器

通常,程序以二进制执行文件的形式座落于磁盘上,比方说a.out或是prog.exe。为了在CPU上运行,程序必须先被带入内存,然后放入一个进程的上下文中。接下来我们会描述这一过程中的步骤,从编译程序到放入内存中。如下图所示:

d038467673b88fed6e881523d51efe9f.png

源文件被编译成目标文件,这些目标文件旨在装入任何物理内存中,这种格式称为可重定位目标文件relocatable object file。接下来,链接器linker将这些可重定位的目标文件组合为单个二进制可执行executable文件。在链接阶段,也可能包括其他目标文件或库,例如标准C或数学库(由标志-lm指定)。

加载器loader用于将二进制可执行文件加载到内存中,使得文件可以在CPU上运行。与链接和加载相关的活动是重定位relocation,重定位将最终地址分配给程序部分,并调整程序中的代码和数据以匹配这些地址,以便例如代码在执行时可以调用库函数并访问其变量。在上图中,我们看到要运行加载程序,所需要做的就是在命令行中输入可执行文件的名称。在UNIX系统上的命令行上输入程序名称(例如./main)时,shell首先使用fork()系统调用创建一个新进程来运行该程序。然后,shell通过exec()系统调用来调用加载程序,并向exec()传递可执行文件的名称。然后,加载程序将指定的程序加载到内存中使用新创建的进程的地址空间。 (使用GUI界面时,双击与可执行文件关联的图标会使用类似的机制调用加载程序。)

到目前为止描述的过程都是假定所有库都链接到可执行文件中并加载到内存中。实际上,大多数系统允许程序在加载程序时动态链接库。例如,Windows支持动态链接库(DLL)。这样做的好处这样做的方法是避免链接和加载可能最终没有被使用到可执行文件中的库。相反,该库是有条件链接的,并且在程序运行时需要时将其加载。例如,在上图中,数学库未链接到可执行文件main中。而是链接器插入重定位信息,使该信息可以在程序加载时动态链接和加载。

目标文件和可执行文件通常具有标准格式,其中包括编译后的机器代码和符号表,其中包含有关程序中引用的函数和变量的元数据。对于UNIX和Linux系统,此标准格式称为ELF(对于可执行和可链接格式Executable and Linkable Format)。可重定位文件和可执行文件有单独的ELF格式。可执行文件的ELF文件中的一条信息是程序的入口点,其中包含程序运行时要执行的第一条指令的地址。 Windows系统使用可移植可执行(Portable Executable,PE)格式,而Mac OS使用Mach-O格式。

ELF 格式

Linux提供了各种不同的指令去识别和评估ELF文件。比如说,file命令识别文件的类型。如果main.o是一个目标文件,且main是一个可执行文件,那么命令:

file main.o

会输出main.o是一个ELF可重定位文件,而命令:

file main

会输出main是一个ELF可执行文件。ELF文件被分成好几个段,通过readlf命令对其评估。

4c6c35de46ca995be8ebcffdfe9e8235.png
f2c7766c3cb6e217185dce6cec1cf76d.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值