【问题标题】:When we run an executable, do all the sections get loaded into memory at once?当我们运行一个可执行文件时,是否所有部分都一次加载到内存中?
【发布时间】:2018-08-22 06:11:31
【问题描述】:
所以一个可执行文件包含不同的部分和标题。
在ELF Header,我们可以看到一些关于它们的元数据,例如不同标题的大小、起点等。
可执行文件的不同部分是否一次全部加载到内存中?
如果是,如何/何时定义它以及我们可以在哪里看到相关信息,因为ELF Header 似乎没有任何参数。
提前致谢。
【问题讨论】:
标签:
linux
assembly
process
elf
virtual-memory
【解决方案1】:
对于 ELF 二进制文件,段不是决定二进制文件如何加载到内存中的因素。它们只是对调试器和其他工具有用的元数据,段和段之间不需要对应关系,并且通常多个段包含在一个段中。二进制文件可以完全没有节标题,但仍然可以正常加载。
实际决定加载什么以及程序头在哪里。每个程序头描述一个内存段并包含以下信息:
-
p_type字段告诉你程序头包含什么样的信息。这通常只是 PT_LOAD 表示“可加载段”。
-
p_offset 字段告诉您与段所在文件开头的偏移量。请注意,在极少数情况下,这可能超出文件末尾。
-
p_vaddr 字段告诉您映射段的虚拟地址。还有p_paddr指定物理地址,不过一般不用。
-
p_filesz 字段告诉您该段在文件中的长度。
-
p_memsz 字段告诉您该段在内存中的时间长度。如果这超过了文件中的段长度,则剩余部分用零填充。
-
p_flags 字段告诉您该段是否可读 (PF_R)、可写 (PF_W)、可执行 (PF_X) 或这三者的某种组合。加载段时,操作系统使用这些标志来设置写和可执行保护。
-
p_align 字段告诉您如何对齐段。这在这里并不重要。
当操作系统加载您的二进制文件或运行时链接编辑器加载一个共享对象时,它会读取您的二进制文件的程序头文件并按照它们出现的顺序加载或映射每个段。完成后,您的程序将被执行。
您可以通过运行readelf -l binary 来获取有关二进制程序头的信息。