4

考虑以下针对 Linux x86_64 的程序:

信息系统:

    .global _start
    .text
_start:
    jmp _start

这基本上是一个无限循环。

如果我链接并剥离它,我会得到一个 ELF 可执行文件:

$ gcc -nostdlib inf.s

$ ./a.out &

[1] 15862

$ cat /proc/15862/maps

00400000-00401000 r-xp 00000000 fc:00 11404632           a.out
7fffacdb8000-7fffacdd9000 rwxp 00000000 00:00 0          [stack]
7fffacddd000-7fffacdde000 r-xp 00000000 00:00 0          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0  [vsyscall]

在 ELF 可执行文件中,第一个程序头LOAD包含占上述 mmap (a.out) 中第一个条目的映射。(即使我剥离了所有内容,但此标头和代码观察到相同的映射。) execve(2)调用 ELF 处理程序,在fs/binfmt_elf.c该处理程序中读取程序标头并在文件上调用 mmap。

我不明白的是其他三个来自哪里(堆栈,vdso,vsyscall)。ELF 文件中没有提到它们,因此 Linux 内核必须默认设置这三个“匿名”或“特殊”映射。

我的问题是 Linux 内核在内核代码中的什么位置(或如何)创建这三个映射?它们是跨 execve 继承的吗?我似乎看不到fs/exec.c它们是在哪里创建的。

4

1 回答 1

6

它们是由内核在将文件加载到内存中以运行它时自动创建的。

由于内核是 32 位还是 64 位[vdso][vsyscall]有各种各样的函数名称定义和重新定义为宏,但一些相关的例程包括:

  • load_elf_binaryfs/binfmt_elf.c其中调用arch_setup_additional_pages
  • arch_setup_additional_pagesarch/x86/vdso/vma.c
  • arch_setup_additional_pagesarch/x86/vdso/vdso32-setup.c

[stack]映射不是特定于 ELF 的,而是由代码在调用格式特定加载器之前调用的__bprm_mm_initin fs/exec.cwhich创建的。execve

于 2013-01-14T09:17:59.687 回答