加载 ELF 可执行文件

Loading of ELF executable

specification of the ELF file format 的第 2-7 和 2-8 页上有两张图片给出了可执行文件的程序头以及它们将如何加载到内存中的示例:

规范说明:

Although the example’s file offsets and virtual addresses are congruent modulo 4 KB for both text and data, up to four file pages hold impure text or data (depending on page size and file system block size).

  • The first text page contains the ELF header, the program header table, and other information.
  • The last text page holds a copy of the beginning of data.
  • The first data page has a copy of the end of text.
  • The last data page may contain file information not relevant to the running process.

我的问题是:

  1. 第 i-th"text page" 和 "data page" 是什么意思?
  2. 以上四句话中的第2项和第3项是什么意思?
  3. 为什么数据填充出现在文本段之后,而文本填充出现在数据段之前,形成交错布局?
  4. 如果可执行文件有两个以上的段(文本和数据除外)要加载怎么办?

页面是虚拟内存的最小可映射单元。如果您不熟悉基础知识,请参阅 the wikipedia article on virtual memory。在普通系统上,页面的大小为 4096 字节,或十六进制的 0x1000。

一个"text page"包含可执行代码; a "data page" 包含数据。这些必须映射到固定地址,以便代码中的偏移量是正确的。在共享库或与位置无关的可执行文件中,不再指定确切的虚拟地址,而是指定它们的 relative 位置。在这个例子中,第 0 个文本页从 0x8048000 到 0x8048fff,这是在文本段开始之前(在 0x8048100)。第 1 个文本页从 0x8049000 到 0x8049fff。最后一个文本页面从 0x8073000 到 0x8073fff,超出了文本段的末尾(在 0x8073eff)。

第一个数据页位于 0x8074000,但数据段直到 0x8074f00 才开始。此页面由文件的 相同 部分作为最后一个文本页面支持,但必须单独映射,因为它具有不同的权限(PROT_EXEC|PROT_READPROT_READ ).这就是 "copy of the beginning of the data" / "copy of the end of the text".

的意思

如果有两个以上的段,则加载完全相同。 "text" 和 "data" 完全是任意的,重要的是为每个段指定的标志和地址。您可以使用 readelfobjdump 查看此信息。

请注意,在现实世界中,文本和数据段之间通常存在未映射的 space("hole"),但只读数据和读写数据之间不一定-数据或初始化数据与未初始化数据。

例如,运行 cat /proc/self/maps 给我:

ben@joyplim ~ % cat /proc/self/maps
00400000-0040c000 r-xp 00000000 fe:01 36176026                           /bin/cat
0060b000-0060c000 r--p 0000b000 fe:01 36176026                           /bin/cat
0060c000-0060d000 rw-p 0000c000 fe:01 36176026                           /bin/cat
<plus the heap, stack, library, and special kernel stuff>