5.1 windows的二进制文件格式PE/COFF
- windows 平台, 引入一种称为PE的可执行格式,他有着跟ELF一样良好的平台扩展性,和ELF一样都是从COFF发展而来的
6.1 进程虚拟地址空间
- 进程: 是一个动态概念, 程序是一个静态概念
- linux 中原则上 进程可以有 3GB的进程空间(剩下 1GB 给操作系统), windows 中原则上只有2G(2G给操作系统)
- PAE: 32bit cpu 虚拟地址空间只有 4GB, 但是通过扩展地址总线, 可以使得物理地址的寻址空间达到64GB(36地址总线)
6.2 装载方式
- 当需要的内存数量大于物理内存的数量的时候,最根本的解决方法是增加内存, 但是由于内存昂贵稀有, 采用覆盖装入和页映射技术 (两者都是基于局部性原理)
6.2.1 覆盖装入
- 现在基本不用, 但是在嵌入式领域,还是可以使用的呢
- 两个覆盖载入的示意图
6.2.2 页映射
- 类似覆盖装入技术, 将内存和所有磁盘中的数据和指令按照page 为单位划分成若干个也, 以后所有的装载和操作的单位都是页
- 装载管理器就是现代操作系统
6.3 从操作系统角度看可执行文件的装载
6.3.1 进程的建立
- 从操作系统角度一个进程最关键的特征是他拥有独立的虚拟地址空间,这使得他有别于其他进程
- 主要分为3个步骤:
- 创建一个独立的地址空间
- 读取可执行文件头, 建立虚拟地址空间和可执行文件之间的映射关系
- 将CPU的指令寄存器设置成可执行文件的入口地址,启动运行
6.3.2 页错误
- 上述操作执行完毕之后, 其实可执行文件的真正指令和数据都没有被装入内存中。其实只是一个空页面
6.4 进程虚存空间分布
6.4.1 ELF文件链接视图和执行视图
- 连接器会尽量吧相同权限属性的段分配在同一个空间
6.4.2 堆和栈
- ELF 和 linux 进程虚拟空间映射关系
6.4.4 段对齐
- 让各个段接触的部分共享一个物理页面, ie, 位于两个段中间的块会被映射两次
6.5 Linux 内核装载 ELF过程介绍
- 先fork 一个进程, 然后调用execve 执行指定的ELF 文件
- execve系统调用的相应入口为 sys_execve, 通过读取文件的前128字节(特别是开头4字节, magic number)确定文件的格式和相应类型,调用相应程序
- 主要流程:
6.6 Windows PE的装载
- RVA 相对虚拟地址, 方便重定位