_ELF加载_动态库

一.可执行文件和.o文件和库的格式

两个都是elf格式的文件,格式如下:

section:节,代码编译完的原代码段,数据段等都是一个一个section

(注意:在 ELF(Executable and Linkable Format)文件中,数据段(Data Segment) 通常由多个 Section 组成,主要用于存储程序运行时的已初始化数据全局/静态变量)

1.ELF Header:elf的头部信息,起始执行指令地址,段大小,数量等附加信息,一般用readelf -h 程序名读取

2.Program Header Table:整个程序的内存布局和访问权限

LOAD表示要将文件加载入内存的部分。下面两个LOAD分别表示代码区和数据区

注意:elf文件由节组成,故抽象为了一维数组,是以偏移量+节大小来定位数据的。

                                                                (readelf -l 文件名)

3.Section Header Table:文件中节的信息,如节相对文件起始位置的偏移量(字节),大小(字节),类型等

                                                     readelf -S 文件名

补充:链接本质是什么呢?

答:将.o文件的elf内每个部分进行合并成一个大的elf格式文件。(能找到函数等定义原因)

二.重谈进程地址空间

前提:

进程的虚拟地址空间是谁规定的?

答:编译时确定的,通过加载可执行程序的节来。验证:反汇编(反汇编出的是节的部分)

可见,编译完程序就有逻辑地址(=起始地址+偏移量),平坦模式(从00000开始,非平坦模式起始地址不是0)下就是进程虚拟地址空间内的虚拟地址

问2:CPU执行程序的时候用的是什么地址?

答:虚拟地址:因为pc寄存器拿到的是head table里的entry就是虚拟地址的。

问3:拿怎么加载实际地址拿到指令的?

答:CR3寄存器其实保存了页表的物理地址,MMU(内存管理单元)硬件可以直接拿pc寄存器里的虚拟地址去页表找物理地址,找到给cpu IR寄存器加载指令

问4:再谈为什么要有虚拟地址?

答:让编译器不用再考虑物理地址,让编译器和操作系统解耦。

问5:为什么有的程序8G,内存只有4G,是怎么让他运行的?

答:分批加载(懒加载)。

进程的虚拟地址空间其实是一个链表,也就是mmstruct内存了一个vm_area_struct指针,每个链表节点都是一个连续区域(一个大型的段,如代码段会被拆分成多个vm_area_struct)。程序加载时仅标记为“需要时加载”,实际页表条目为空,只记录那块的elf内偏移量。程序加载只要先给cpu entry入口地址,首次访问触发缺页异常,内核再按需加载数据并插入 vm_area_struct(如果尚未存在)/

问:为什么mmstruct要设计成内容为链表?

1.分批加载

2. 程序加载时的“确定”是初始布局,但运行时会动态变化

操作系统将elf部分载入内存时,就确定了mmstruct大小信息等,再建立页表映射。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值