考虑以Linux x86_64为目标的以下程序:
inf.s:
.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)在fs/binfmt_elf.c中调用ELF处理程序,读取程序头并在文件上调用mmap。
我不明白的是其他三个来自哪里(堆栈,vdso,vsyscall)。在ELF文件中没有提到它们,所以Linux内核必须默认设置这三个“匿名”或“特殊”映射。
我的问题是,在内核代码中(或者Linux内核是如何创建这三个映射)的地方?他们是继承来的吗?我似乎看不到在fs/exec.c中创建它们的位置。
发布于 2013-01-14 09:17:59
它们是由内核在将文件加载到内存以运行它时自动创建的。
[vdso]和[vsyscall]的精确控制流很难理解,因为根据内核是32位还是64位,可以将各种函数名定义和重新定义为宏,但一些相关例程包括:
load_elf_binary in fs/binfmt_elf.c,称为arch_setup_additional_pagesarch_setup_additional_pages in arch/x86/vdso/vma.carch_setup_additional_pages in arch/x86/vdso/vdso32-setup.c[stack]映射不是ELF特定的,而是由__bprm_mm_init在fs/exec.c中创建的,在调用特定格式的加载程序之前,execve代码会调用该映射。
https://stackoverflow.com/questions/14314535
复制相似问题