从操作系统角度看可执行文件的装载

1、进程的建立

一个新进程的创建首先做三件事。

一:创建独立的虚拟地址空间。

二:读取可执行文件头,并建立虚拟地址和可执行文件的映射关系。

三:将CPU指令寄存器设置成可执行文件的入口地址,启动运行。

一个虚拟空间由一组页映射函数将各个页映射至相应的物理空间。在i386的Linux下,创建虚拟地址空间实际上只是分配了一个页目录即可,甚至不设置页映射关系,这些页映射关系可以等到后面程序发生页错误的时候再进行。

当程序执行发生页错误的时候,操作系统将从物理内存分配一个物理页,然后将该“缺页”从磁盘读取到内存,再设置缺页的虚拟页和物理页的映射关系。当操作系统捕获页错误的时候需要知道当前所需的页在可执行文件中的位置,这就是虚拟地址和可执行文件的映射。Linux将进程虚拟空间中的一个段叫做“虚拟内存区域”VMA(virtual memory area),windows将这个叫虚拟段(Virtual Section)。

最后操作系统通过设置CPU的指令寄存器将控制权交给进程,进程开始执行。这一步涉及到内核堆栈和用户堆栈的切换、CPU运行权限的切换。

2、页错误

一面的步骤执行完后,可执行文件的真正指令和数据还没有被装入内存中,操作系统只是通过可执行文件的文件头部信息建立的可执行文件盒进程虚存之间的映射关系。当CPU开始计算执行某个地址指令的时候,如果发现页面的空页面就会认为这是一个页错误(page fault),CPU将控制权交给操作系统,操作系统会通过专门的错误处理例程来查询创建页映射函数所需的那个数据结构,然后找到空页面所在的VMA,计算出它在可执行文件中偏移,然后分配一个物理页面,将虚拟页与分配的物理页之间建立映射关系。


3、进程虚拟空间分布

由于elf可执行文件一般有很多个段,如果每个段都映射到进程虚拟空间作为一个VMA,这样会浪费很多的空间,所以一般会把相同权限的段合并到一起进行映射,segment。Segment从装载的角度重新划分了elf的各个段。将目标文件链接成可执行文件时,链接器会尽量把权限相同段分配到一个空间。描述segment的结构叫做程序头,它描述了elf文件该如何被操作系统映射到进程的虚拟空间。从section的角度看elf文件就是链接视图(linking view),从segment角度看就是执行试图(execution view)。可执行文件有一个专门的数据结构叫做程序头表,用来保存segment信息。

进程虚拟地址空间概念:操作系统通过给进程空间划分出一个个VMA来管理进程的虚拟空间;基本原则是将相同权限属性的、有相同映像文件的映射成一个VMA;一个进程一般可以分为四种VMA区域:

代码VMA,权限可读可执行;有映像文件

数据VMA,权限可读写可执行;有映像文件

堆VMA,权限可读写可执行;无映像文件,匿名,可向上扩展,也就是地址从高到低

栈VMA,权限可读写不可以执行


段地址对齐:

为了节省内存,对于ELF文件,如果一个segment不足一个页,UNIX系统一般会将一个物理页映射到多个虚拟地址空间。在一个ELF文件中,对于任何一个可装载的segment,它的p_vaddr(虚拟地址)除以对齐属性的余数等于p_offset(segment在文件中的偏移)除以对齐属性的余数。

在PE文件中,所有段的起始地址都是页的倍数。PE文件中,链接器在生产可执行文件时,往往将所有的段尽可能的合并,所以一般只有代码段、数据段、只读数据段、和BSS等为数不多的几个段。不像ELF文件经常有十多个Section,最后不得不使用segment的概念把他们合并在一起。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值