Consider the following Linux x86_64-oriented program:
inf.s:
.global _start .text _start: jmp _start
This is basically an endless loop.
If I link and remove this, I get the ELF executable:
$ 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]
In the ELF executable, the first header of the LOAD program contains a map that takes into account the first entry in the aforementioned mmaps (a.out). (Even if I separate everything except this header and code, the same cards are observed.) execve(2) calls the ELF handler in fs/binfmt_elf.c , which reads the program header and calls mmap in the file.
What I don't understand is where the other three come from (stack, vdso, vsyscall). They are not mentioned in the ELF file, so the Linux kernel should install these three โanonymousโ or โspecialโ cards by default.
My question is where in the kernel code (or how) does the Linux kernel create these three other cards? Are they inherited via execve? I don't seem to see where they are created in fs/exec.c
source share