考虑以下针对 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
它们是在哪里创建的。