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 を呼び出します。
私が理解していないのは、他の 3 つ (stack、vdso、vsyscall) がどこから来たのかということです。これらは ELF ファイルには記述されていないため、Linux カーネルはこれら 3 つの「匿名」または「特別」マップをデフォルトでセットアップする必要があります。
私の質問は、Linux カーネルがこれらの他の 3 つのマップをカーネル コードのどこ (またはどのように) 作成するのかということです。それらは execve 全体で継承されますか? fs/exec.c
それらが作成された場所が見えないようです。