段(Section)划分
文件段(Section)一般可分为以下几个区域

  • .text. :代码段
  • .rodata:只读数据段
  • .data: 已初始化全局数据段
  • .bss:未初始化全局数据段。因为为初始化变量没有具体的值,所以无需在目标文件中分配用于保存值的空间,也就是在目标文件中不会占有实际的磁盘空间,仅仅是一个占位符。区分已初始化和为初始化全局变量是为了提高空间利用率。
  • .symtab:符号表(symbol table)。在程序中被定义和引用的函数名和全局变量名都属于符号,与这些符号相关的信息都保存在符号表中。

映射
上面提到的段(Section)的内容在链接成可执行文件时,会分配不同的虚拟内存空间,也就是会映射到段(Segment)内。这个映射关系由段头表(Segment header table)来记录,它是一个结构数组。

root@000d3fada0b3:~/asm# readelf -l hello

Elf file type is EXEC (Executable file)
Entry point 0x4000b0
There are 2 program headers, starting at offset 64

Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000000d5 0x00000000000000d5 R E 0x200000
LOAD 0x00000000000000d8 0x00000000006000d8 0x00000000006000d8
0x000000000000000e 0x000000000000000e RW 0x200000

Section to Segment mapping:
Segment Sections...
00 .text
01 .data

上面就是可执行程序中存在的段(Segment header table)。将.text放在第一个Load的内存空间。将.data放在第二个Load的内存空间。