Рассмотрим следующую программу, предназначенную для 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
содержит карту, на которую приходится первая запись в вышеупомянутых mmaps (a.out). (Даже если я удалю все, кроме этого заголовка и кода, будут наблюдаться те же карты.) execve(2)
вызывает обработчик ELF в fs/binfmt_elf.c
, который читает заголовок программы и вызывает mmap для файла.
Чего я не понимаю, так это откуда берутся остальные три (стек, vdso, vsyscall). Они не упоминаются в файле ELF, поэтому ядро Linux должно установить эти три «анонимных» или «специальных» карты по умолчанию.
Мой вопрос: где в коде ядра (или как) ядро Linux создает эти три другие карты? Наследуются ли они через execve? Кажется, я не вижу, где в fs/exec.c
они создаются.