静态程序编译链接与装载(三)segment分析以及链接视图与执行视图

程序通过编译,链接生成ELF可执行之后,如果要被执行,是需要装载到内存当中,然后去执行的。

那么装载的过程,应该是如何装载的?是按照链接时候的section为单位进行装载吗?下面,就要基于这个问题,进行分析。

链接的时候,是通过section进行组合,得到最终的ELF,但是对section进行分类的话,section无非就下面几种权限:

  • RX:可读可执行,对应于代码段

  • RW: 可读可写,对应于数据段

  • R:  只读,对应于只读段

因为,就可以考虑,将相同权限,并且地址连续的的section,合并成一个大的段,这样的话,就方便装载。此时,这个段,就称为segment。

一、程序头表

对于可执行程序,是看的program headers表

对于可执行程序,program header table,程序头表,表征了 程序的 加载信息。

程序装载到内存,也是按段进行装载,不过此时,用的是segment

对于ELF可执行程序,关于program域的成员变量,都不为0


start of program headers

程序头表在elf文件中的偏移

size of program headers

程序头表,一个表项所占大小

number of program headers

程序头表的表项个数

 程序头表数据结构如下图所示:


p_type

segment的类型,关注LOAD,表示要加载到内存

p_offset

segment在文件中的偏移

p_vaddr

segment的va,也就是VMA

p_paddr

segment加载到内存中的pa,一般pa和va一样,除非链接脚本单独指定,也就是LMA

p_files

segment在elf文件中所占空间的大小

p_memsz

segment加载到内存中,所占的大小

p_flags

segment的权限,RWX

p_align

segment的对齐要求。实际对齐字节等于2的p_align次方

 通过readelf -l 可以查看程序头表信息


有2个segment

第一个segment: va是0x40_0000  pa是0x40_0000, 权限可读可执行, 包含了 .text 段

第二个segment: va是0x41_007c, pa是0x41_007c, 权限可读可写, 包含了.data和.bss 段

所以segment就是 section的集合,将相同权限,并且地址是连续的section,合并成一个segment,方便加载。

这样,就引出了链接视图与执行视图。


链接视图: 通过section来描述,也就是elf中section header table

执行视图: 通过segment来描述,也就是elf中的program header table

那么对于section,是如何映射到segment的呢?

以下是链接视图,可以看到各个section。


以下是执行视图,可以看到各个segment,以及segment集合的section。

每个section有VMA,每个segment也有VMA

如果一个section的VMA,属于一个segment的VMA范围内,那么该section会被合并到该segment

.text的VMA处于segment0的VMA范围内,因此划分到segment0

.data和.bss的VMA处于segment1的VMA范围内,因此划分到segment1

此条目发表在其他分类目录。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。