5

简单的 C 文件:

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

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

elf 程序头,段信息

问题:

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

2 回答 2

6

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

*这是规范所说的:

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

如您所见,没有提到重叠,因此似乎没有被禁止,尽管我认为我没有看到任何具有重叠 PT_LOAD 段的文件。

于 2012-06-04T12:07:43.083 回答
-2
  1. 几个部分出现在不同的段中,例如第 2 段和第 3 段中的 interp 部分。

所以?

一个部分如何出现在多个段中?

为什么不?

一个部分不会出现在多个段中,但同时出现在 a和 a中并PT_LOAD没有错。.interpPT_LOADPT_INTERP

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

再说一次,为什么不呢?

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

因为否则将不可能mmap将该段并使其出现在virtaddr.

于 2012-06-03T20:57:32.303 回答