Відповіді:
У файлі /proc/kallsyms
перераховані всі символи запущеного ядра. За умовами, системні дзвінки мають назву, що починається з sys_
. У 64-бітовій системі системні виклики для 32-бітних програм мають ім'я, яке починається з sys32_
. Строго кажучи, у цьому списку перераховані внутрішні функції ядра, а не системний виклик, але я думаю, що кореспонденція працює (кожен системний виклик викликає внутрішню функцію ядра, щоб виконати цю роботу, і я думаю, що ім'я завжди є ім'ям системного виклику з попередньою sys_
формою ).
</proc/kallsyms sed -n 's/.* sys_//p'
Зазвичай це не корисна інформація, оскільки системні дзвінки змінюються дуже повільно. Додаткові компоненти забезпечують функціональні можливості з точки зору існуючих системних викликів, використовуючи загальні функції , такі як пристрої (з IOCTL , коли read
і write
не різати), файлові системи, розетки і т.д. Визначення списку підтримуваних системних викликів не буде нічого розповідати про особливості що система підтримує. Інші внутрішні назви функцій також не допоможуть, оскільки вони змінюються дуже швидко: назва функції, яка реалізує якусь функцію в одній версії ядра, може змінитися на наступній версії.
Я продовжував знаходити нові альтернативи, коли писав цю відповідь, тому просто написав трохи деталей про кожну з них і зробив кілька статистичних даних. В основному, ви можете:
/proc
)./sys
каталогом.Займаючись математикою, я б рекомендував (серед моїх альтернатив) використовувати /sys
файлову систему, оскільки це, здається, дає найкращий результат за кількістю системних викликів. Ви можете перейти прямо до цього розділу, якщо не хочете читати про інші хитрощі.
Незважаючи на те, що ви можете пропустити деякі з них, ви можете скористатись apropos
списком усіх мандатів, що належать до розділу 2 (системні дзвінки):
$ apropos -s2 . | awk '{print $1}' | column
Видаліть, column
якщо ви не хочете вигадливого колонного виводу.
Я щойно це з’ясував, але є сторінка Linux щодо системних викликів, і ви зможете знайти більшість із них у ньому.
$ man syscalls
Я також натрапив на ці два веб-сайти, які можуть бути цікавими:
Редагувати: Тепер, коли мова йде про програмне (або принаймні, не покладаючись на задокументовані функції) визначення того, які системні дзвінки доступні, я боюся, ядро не зберігає таблицю своїх системних викликів, принаймні, не у формі список рядків (як ви, напевно, очікували, що ними маніпулюєте). На цьому рівні ми говоримо більше про адреси функцій та покажчики, а не назви функцій.
Я просто переглянув свій /usr/include
каталог і grep
провів декілька речей: вам можуть бути цікаві наступні каталоги. Деякі з них можуть відрізнятися на вашій машині, залежно від вашої архітектури та розповсюдження, але я впевнений, що ви зможете їх адаптувати.
Шукаючи в цьому файлі визначення функцій, ви стикаєтеся з багатьма системними дзвінками, хоча вони там не будуть повністю визначені. Я пробіг декілька grep
s у цих каталогах, і мені вдалося знайти згадки про деякі системні виклики. Ось приклад:
$ 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
можна маніпулювати, як і будь-яким іншим файлом, користуватися ним у програмі стає досить просто.