Реализация системных вызовов
Если пользовательское приложение выполняет системный вызов, срабатывает программное прерывание / исключение. Как я могу увидеть исходный код для генерации программного прерывания?
3 ответа
Это объясняется в Linux Assembly Howto. И вы должны прочитать страницу системного вызова в Википедии (а также о VDSO), а также справочные страницы intro(2) и syscalls(2). Смотрите также этот ответ и этот. Посмотрите также на исходный код Gnu Libc & musl-libc. Учитесь также использовать strace
чтобы выяснить, какие системные вызовы сделаны данной командой или процессом.
См. Также соглашения о вызовах и спецификацию Application Binary Interface, относящиеся к вашей системе. Для x86-64 это здесь.
Давным -давно, есть int 0x80
ловушка для входа в ядро, но в наше время sysenter
является предпочтительным.
Вы можете получить код, сбросив vsyscall
секция, которая автоматически отображается ядром в каждом процессе.
$ cat /proc/self/maps
blah blah blah
...
blah blah blah
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
для получения дополнительной информации проверьте эту статью
Программное прерывание может быть вызвано инструкцией по сборке Intel x86 int n
, где n
это номер прерывания. Системный вызов - это особый случай программного прерывания; в вы можете сделать системный вызов вручную
mov eax, m
int 0x80
где m
следует заменить номером прерывания. Вот списки 32-битных номеров системных вызовов и 64-битных номеров системных вызовов, которые связаны с онлайн-страницами man для каждой функции. Вам также необходимо передать параметры в системный вызов через другие регистры (ebx
, ecx
и т.д.), и вы можете прочитать больше об этом здесь.
Это наиболее общий способ выполнения системных вызовов, потому что он не зависит от внешних библиотек, таких как libc, и вы можете реализовать это в C/C++, если вам нужно, используя встроенную сборку.