为什么 elf 文件中的段可以重叠

blu*_*sea 5 assembly elf segment

简单的C文件:

#include <stdio.h>
int main(){
    printf("Hello World");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译代码后,使用readelf -a a.out,精灵信息如下:

elf 程序头、段信息

问题:

  1. 几个部分出现在不同的段中,例如第二段和第三段中的 interp 部分。一个部分如何出现在多个部分中?
  2. 第二段的地址从 0x8048134 开始,但第三个 LOAD 段从 0x8048000 开始,0x004d0 memsize。那么这两段重叠?两个段如何在内存中重叠?
  3. 为什么程序头的偏移量和 viraddr 必须与页面大小模数一致?

Igo*_*sky 6

节表中可能有垃圾,或者可能完全丢失。对于动态加载器来说,所有重要的是段表(程序头),即使如此,只有 PT_LOAD 段不应该重叠*。其他类型的段(INTERP、DYNAMIC 等)为加载程序提供附加信息,通常引用 LOAD 段的某些部分。

*这是规范所说的:

PT_LOAD 数组元素指定一个可加载段,由p_filesz和描述 p_memsz。文件中的字节映射到内存段的开头。如果段的内存大小 ( p_memsz) 大于文件大小 ( p_filesz),则定义“额外”字节以保存值 0 并跟随段的初始化区域。文件大小不得大于内存大小。程序头表中的可加载段条目以升序出现,按p_vaddr成员排序。

正如你所看到的,没有提到重叠,所以它似乎没有被禁止,尽管我认为我没有看到任何具有重叠 PT_LOAD 段的文件。


Emp*_*ian -3

  1. 几个部分出现在不同的段中,例如第二段和第三段中的插值部分。

所以?

一个节怎么能出现在多个节段中?

为什么不?

一个节不会出现在多个段中,但同时出现在 a和 a中PT_LOAD也没有问题。.interpPT_LOADPT_INTERP

  1. 两个段在内存中如何重叠?

再说一遍,为什么不呢?

  1. 为什么程序头的偏移量和viraddr必须与页面大小的模一致?

因为否则就不可能进行mmap分段并将其显示在 处virtaddr

  • 当它包含比问题“更多”的问号时,它仍然是答案吗? (24认同)
  • 人们期望,对“你”来说显而易见的事情应该很容易向“不”具有相同洞察力的人解释。你在这方面并没有特别成功。事实上,听起来你实际上并不知道答案。如果您这样做,您当然可以发布更好的答案吗?至少解释一下段和部分是如何关联的。 (16认同)