現在実行中のLinuxカーネルでサポートされているシステムコールの数またはリストを取得する方法はありますか?したがって、実行中のカーネルのsyscallテーブルを「読み取る」方法を見つけたいと思います。
ファイル/proc/kallsyms
には、実行中のカーネルのすべてのシンボルがリストされています。慣例により、システムコールの名前はsys_
で始まります。 64ビットシステムでは、32ビットプログラムのシステムコールの名前はsys32_
で始まります。厳密に言えば、これはシステムコールではなく内部カーネル関数をリストしますが、対応は機能すると思います(すべてのシステムコールは内部カーネル関数を呼び出してジョブを実行し、名前は常にsys_
を使用したシステムコールの名前だと思います先頭に追加)。
</proc/kallsyms sed -n 's/.* sys_//p'
システムコールの変更は非常に遅いため、これは通常、有用な情報ではありません。オプションのコンポーネントは、デバイス(read
とwrite
がそれを切り取らない場合 ioctl を使用)、ファイルシステム、ソケットなど。サポートされているシステムコールのリストを決定しても、システムがサポートしている機能については何もわかりません。他の内部関数名も非常に迅速に変更されるため、役に立ちません。あるカーネルバージョンで一部の機能を実装する関数の名前は、次のバージョンで変更される可能性があります。
私はこの回答を書いているときに新しい選択肢を見つけ続けたので、それぞれについて少し詳細を書いて、いくつかの統計を作成しました。基本的に、次のいずれかを実行できます。
/proc
に依存します)。/sys
ディレクトリを使用します。計算を行った後、システムコールの数の点で最良の結果が得られると思われるため、(代替案の中でも)/sys
ファイルシステムを使用することをお勧めします。他のトリックについて読みたくない場合は、そのセクションに直接ジャンプできます。
それらのいくつかを見逃すかもしれませんが、apropos
を使用して、セクション2(システムコール)に属するすべてのマンページを一覧表示できます。
$ apropos -s2 . | awk '{print $1}' | column
派手な列化された出力が必要ない場合は、column
を削除してください。
私はそれを見つけたばかりですが、システムコールに関するLinuxのマニュアルページがあり、そのほとんどを見つけることができます。
$ man syscalls
私はまた興味深いかもしれないこれらの2つのウェブサイトに出くわしました:
編集:さて、プログラムで(または少なくとも、文書化された機能に依存せずに)利用可能なシステムコールを決定することになると、カーネルはそのシステムコールのテーブルを保持していません。少なくとも、文字列のリストの形式ではありません(おそらくそれらを操作することを期待しています)。このレベルでは、関数名ではなく、関数のアドレスとポインターについて話します。
私は自分の/usr/include
ディレクトリを参照して、いくつかのことをgrep
- edしました。以下のディレクトリが興味深いかもしれません。それらのいくつかは、アーキテクチャとディストリビューションに応じて、マシン上で異なる場合がありますが、それらを適応させることができると確信しています。
このファイルで関数定義を探すと、完全には定義されていなくても、多くのシステムコールに出くわすでしょう。これらのディレクトリでいくつかの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 ')'
もう1つの解決策は、(ヘッダーだけでなく)カーネルソースコード自体を使用して、効率的に検索する方法を見つけることです。 カーネルコミット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
実際のsyscallsテーブルを取得したので、それを参照するだけです。
$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl
uname
とArch
を使用して、実行中にtbl
ファイルを git.kernel.org から直接ダウンロードする方法を見つけることができます。カーネルのバージョンとアーキテクチャ。
/sys
ファイルシステムの使用Gillesの答えは私に少しインスピレーションを与えました、そしてあなたはそれらのシステムコールを/sys/kernel/debug/tracing/events/syscalls
の中に見つけるかもしれません。このディレクトリは、システムでの各システムコールの使用を監視するために使用されます。各syscallには2つのディレクトリがあります。
したがって、ls
、grep
、およびcut
..を使用します。
$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3
私のシステムでは:
__SYSCALL
のgrep
- ingにより、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システムコールです。もちろん、この数は「システムコール」の非常に柔軟な定義を反映しています。 .13は274のシステムコールのみを提供することになっています (/sys
の読み取りが最も近いソリューションのようです)。
すべての答えは結構です。
特定のシステムコール名を探している場合:
$ cat /proc/kallsyms | grep <sys_call_name>
すべてのシステムコールのリストを探している場合:
$ cat /proc/kallsyms