Відповіді:
У файлі /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провів декілька речей: вам можуть бути цікаві наступні каталоги. Деякі з них можуть відрізнятися на вашій машині, залежно від вашої архітектури та розповсюдження, але я впевнений, що ви зможете їх адаптувати.
Шукаючи в цьому файлі визначення функцій, ви стикаєтеся з багатьма системними дзвінками, хоча вони там не будуть повністю визначені. Я пробіг декілька greps у цих каталогах, і мені вдалося знайти згадки про деякі системні виклики. Ось приклад:
$ 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можна маніпулювати, як і будь-яким іншим файлом, користуватися ним у програмі стає досить просто.