Откуда берутся mmaps `[stack]`, `[vdso]` и `[vsyscall]`?
Рассмотрим следующую программу, ориентированную на 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
содержит карту, которая учитывает первую запись в вышеупомянутых mmaps (a.out). (Даже если я раздеваю все, но этот заголовок и код одинаковые карты наблюдаются.) execve(2)
вызывает обработчик ELF в fs/binfmt_elf.c
который читает заголовок программы и вызывает mmap для файла.
То, что я не понимаю, откуда три других (стек, vdso, vsyscall). Они не упоминаются в файле ELF, поэтому ядро Linux должно по умолчанию настроить эти три "анонимные" или "специальные" карты.
Мой вопрос: где в коде ядра (или как) ядро Linux создает эти три другие карты? Они унаследованы через execve? Я не могу видеть, где в fs/exec.c
они созданы.
1 ответ
Они создаются ядром автоматически при загрузке файла в память для его запуска.
Точное управление потоками для [vdso]
а также [vsyscall]
трудно следовать, потому что есть все виды определения и переопределения имен функций как макросов в зависимости от того, является ли ядро 32- или 64-битным, но некоторые соответствующие процедуры включают в себя:
load_elf_binary
вfs/binfmt_elf.c
какие звонкиarch_setup_additional_pages
arch_setup_additional_pages
вarch/x86/vdso/vma.c
arch_setup_additional_pages
вarch/x86/vdso/vdso32-setup.c
[stack]
отображение не является специфичным для ELF и создается __bprm_mm_init
в fs/exec.c
который называется execve
код, прежде чем он вызывает конкретный формат загрузчик.