✨✨✨学习的道路很枯燥,希望我们能并肩走下来!
文章目录
前言
本篇详细介绍了进一步介绍Linux的ELF文件格式和重谈进程地址空间,让使用者有更加深刻的认知,而不是仅仅停留在表面,更好的模拟,为了更好的使用. 文章可能出现错误,如有请在评论区指正,让我们一起交流,共同进步!
一 ELF文件格式
1.1 简介
ELF的英文全称是The Executable and Linking Format,最初是由UNIX系统实验室开发、发布的ABI(Application Binary Interface)接口的一部分,也是Linux的主要可执行文件格式。
从使用上来说,主要的ELF文件的种类主要有三类:
- 可执行文件(exe):Executable File,包含代码和数据,是可以直接运行的程序。其代码和数据都有固定的地址 (或相对于基地址的偏移 ),系统可根据这些地址信息把程序加载到内存执行。
- 可重定位文件(.o文件):Relocatable File,包含基础代码和数据,但它的代码及数据都没有指定绝对地址,因此它适合于与其他目标文件链接来创建可执行文件或者共享目标文件。
- 共享目标文件(.so):Shared Object File,也称动态库文件,包含了代码和数据,这些数据是在链接时被链接器(ld)和运行时动态链接器(ld.so.l、libc.so.l、ld-linux.so.l)使用的。
1.2 elf文件的基本格式
ELF Header:
该文件的头部信息的情况
Program Header Table:
将来程序加载到内存,在内存中的整体布局
elf文件的节区(Section)
节区描述了文件的组成,节的位置等信息。通过
readelf -s
可以查看信息。
1.3 链接的本质
二 重谈进程地址空间
在我们前面的文章提到,进程地址空间与可执行文件加载的关系是这样的
我们就会有疑问了,
1. mm_struct 由谁来初始化的?
2. 可执行程序有没有地址的存在?
我们可以输入如下代码查看我们的可执行程序
objdump -S 可执行文件
可执行程序有地址的存在,作为mm_struct初始化的样本
一图流:
** 问题一:CPU最开始执行可执行程序的时候,是怎么进行的?**
找到对应文件的ELF中的ELF head中的程序入口 entry
传给pc寄存器
问题2:查表是如何进行的
CR3指向页表物理地址的起始地址
通过MMU硬件通过硬件电路进行查表
**问题三:为什么要有虚拟地址空间和虚拟地址 **
除了之前提到的,操作系统和编译器进行解耦
**总结: **
虚拟地址空间是操作系统,CPU,编译器共同协作下的产物!
三 重谈区域划分
分批加载和懒加载:
建立映射,操作完后释放再加载新的
甚至可以不加载,只把你程序的入口地址加载进来,剩下的,CPU进行寻址虚拟和物理的转化,没转化成功,会发生缺页中断,这时候再懒加载你的数据section
四 简单理解动态库加载
我们知道,动态库使用时也要被加载到内存中
那么OS,要不要对动态库进行管理呢?当然要!
ELF文件中有.got
.got中存放着库方法的偏移量,类似与一维数组
当加载到内存时,.got中的库名被替换成对应进程地址空间中的库的虚拟地址,
正文代码访问.got表的地址,通过这个表找到对应的方法,进行页表查找
总结
✨✨✨各位读友,本篇分享到内容是否更好的让你理解ELF文件格式和进程地址空间,如果对你有帮助给个👍赞鼓励一下吧!!
🎉🎉🎉世上没有绝望的处境,只有对处境绝望的人。
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!
版权归原作者 Chris-zz 所有, 如有侵权,请联系我们删除。