Откуда берутся ммапы `[stack]`, `[vdso]` и `[vsyscall]`?

Рассмотрим следующую программу, предназначенную для 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 они создаются.


person Andrew Tomazos    schedule 14.01.2013    source источник


Ответы (1)


Они автоматически создаются ядром, когда оно загружает файл в память для его запуска.

Точные потоки управления для [vdso] и [vsyscall] трудно проследить, потому что существуют всевозможные определения и переопределения имен функций в виде макросов в зависимости от того, является ли ядро ​​32-битным или 64-битным, но некоторые соответствующие процедуры включают:

  • load_elf_binary в fs/binfmt_elf.c, который вызывает arch_setup_additional_pages
  • arch_setup_additional_pages in arch/x86/vdso/vma.c
  • arch_setup_additional_pages in arch/x86/vdso/vdso32-setup.c

Отображение [stack] не является специфичным для ELF и создается __bprm_mm_init в fs/exec.c, которое вызывается кодом execve перед вызовом загрузчика, специфичного для формата.

person TomH    schedule 14.01.2013