Ответы:
В файле /proc/kallsyms
перечислены все символы работающего ядра. По соглашению системные вызовы имеют имя, начинающееся с sys_
. В 64-битной системе системные вызовы для 32-битных программ начинаются с имени sys32_
. Строго говоря, здесь перечислены внутренние функции ядра, а не системный вызов, но я думаю, что переписка работает (каждый системный вызов вызывает внутреннюю функцию ядра для выполнения этой работы, и я думаю, что имя - это всегда имя системного вызова с sys_
префиксом). ).
</proc/kallsyms sed -n 's/.* sys_//p'
Обычно это бесполезная информация, потому что системные вызовы меняются очень медленно. Дополнительные компоненты обеспечивают функциональные возможности с точки зрения существующих системных вызовов, используя общие функции , такие как устройства (с IOCTL , когда read
и write
не резать), файловые системы, розетки и т.д. Определение списка поддерживаемых системных вызовов не будет ничего рассказывать об особенностях что система поддерживает. Другие внутренние имена функций также не помогут, потому что они меняются очень быстро: имя функции, реализующей некоторые функции в одной версии ядра, может измениться в следующей версии.
Я продолжал находить новые альтернативы, когда писал этот ответ, поэтому я просто написал немного деталей о каждом из них и сделал некоторые статистические данные. По сути, вы можете:
/proc
)./sys
каталог.После выполнения математики я бы порекомендовал (среди моих альтернатив) использовать /sys
файловую систему, поскольку она, похоже, дает лучший результат с точки зрения количества системных вызовов. Вы можете перейти прямо к этому разделу, если не хотите читать о других хитростях.
Хотя вы можете пропустить некоторые из них, вы можете использовать apropos
для просмотра всех man-страниц, относящихся к разделу 2 (системные вызовы):
$ apropos -s2 . | awk '{print $1}' | column
Удалите, column
если вы не хотите показывать колонки.
Я только что узнал, но есть справочная страница Linux о системных вызовах, и вы сможете найти большинство из них в ней.
$ man syscalls
Я также наткнулся на эти два веб-сайта, которые могут быть интересны:
Изменить: Теперь, когда речь идет о программном (или по крайней мере, не полагаясь на документированные возможности) определении доступных системных вызовов, я боюсь, что ядро не хранит таблицу своих системных вызовов, по крайней мере, не в форме список строк (как вы, вероятно, ожидаете манипулировать ими). На этом уровне мы больше говорим об адресах и указателях функций, а не об именах функций.
Я только что просмотрел мой /usr/include
каталог и grep
-ed несколько вещей: вы можете найти следующие каталоги интересными. Некоторые из них могут отличаться на вашей машине, в зависимости от вашей архитектуры и дистрибутива, но я уверен, что вы сможете адаптировать их.
Посмотрев определения функций в этом файле, вы столкнетесь со многими системными вызовами, даже если они там не будут полностью определены. Я провел несколько grep
секунд в этих каталогах и смог найти упоминания о некоторых системных вызовах. Вот пример:
$ grep 'sys_exit' /usr/include -R
asm-generic/unistd.h:__SYSCALL(__NR_exit, sys_exit)
Итак, я предполагаю, что другой способ найти некоторые из них будет:
$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')'
Другое решение - использовать сам исходный код ядра (а не только заголовки!) И найти способ его эффективного поиска. Поскольку ядро совершает 303395ac3bf3e2cb488435537d416bc840438fcb , вы можете найти это немного проще, чем раньше. Вот пример для 3.13 (который является моим ядром):
$ wget https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/plain/arch/x86/syscalls/syscall_64.tbl?id=refs/tags/v3.13 -O syscall_64.tbl
Теперь, когда вы получили реальную таблицу системных вызовов, просто просмотрите ее:
$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl
Вы можете найти способ, используя uname
и arch
, загрузить tbl
файл прямо с git.kernel.org , в зависимости от используемой версии ядра и архитектуры.
/sys
файловой системыОтвет Жиля дал мне немного вдохновения, и вы можете найти эти системные вызовы внутри /sys/kernel/debug/tracing/events/syscalls
. Этот каталог используется для мониторинга использования каждого системного вызова в системе. Каждый системный вызов имеет две директории:
Поэтому, используя ls
, grep
и cut
...
$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3
В моей системе:
grep
-ing для __SYSCALL
в заголовочных файлах выявлено 212 системных вызовов./sys
выявлено 290 системных вызовов.Теперь, если я соберу все вместе ...
$ apropos -s2 . | awk '{print $1}' > system_calls.txt
$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')' >> system_calls.txt
$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl >> system_calls.txt
$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3 >> system_calls.txt
$ sort < system_calls.txt | uniq | wc -l
707
Ну вот, 707 системных звонков! Конечно, это число отражает очень гибкое определение «системного вызова», поскольку предполагается , что 3.13 обеспечивает только 274 системных вызова (чтение /sys
является наиболее близким решением).
Все ответы в порядке.
Если вы ищете конкретное имя системного вызова:
$ cat /proc/kallsyms | grep <sys_call_name>
Если вы ищете список всех системных вызовов:
$ cat /proc/kallsyms
/proc/kallsyms
можно манипулировать, как и любым другим файлом, его довольно просто использовать в программе.