Linuxのsyscallテーブルはどこにありますか?


13

オンラインで参照している人がたくさんいる

arch/x86/entry/syscalls/syscall_64.tbl

syscallテーブルの場合、これは正常に機能します。しかし、他の多くの参照

/include/uapi/asm-generic/unistd.h

これは一般的にheadersパッケージにあります。どうしてsyscall_64.tblショー、

0 common  read      sys_read

正しい答えとunistd.h

#define __NR_io_setup 0
__SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)

そして、それは示し__NR_read

#define __NR_read 63
__SYSCALL(__NR_read, sys_read)

なぜ63ではなく1なのですか?私はどのように理解するの/include/uapi/asm-generic/unistd.hですか?まだ/usr/include/asm/あります

/usr/include/asm/unistd_x32.h
#define __NR_read (__X32_SYSCALL_BIT + 0)
#define __NR_write (__X32_SYSCALL_BIT + 1)
#define __NR_open (__X32_SYSCALL_BIT + 2)
#define __NR_close (__X32_SYSCALL_BIT + 3)
#define __NR_stat (__X32_SYSCALL_BIT + 4)

/usr/include/asm/unistd_64.h
#define __NR_read 0
#define __NR_write 1
#define __NR_open 2
#define __NR_close 3
#define __NR_stat 4

/usr/include/asm/unistd_32.h
#define __NR_restart_syscall 0
#define __NR_exit 1           
#define __NR_fork 2           
#define __NR_read 3           
#define __NR_write 4          

これらのunistdファイルの違いを誰かに教えてもらえますか?仕組みを説明しunistd.hてください。そして、syscallテーブルを見つけるための最良の方法は何ですか?

回答:


12

この種のことを調査しているとき、コンパイラーに直接問い合わせることが役立つと思います(詳細については、ターミナルでの標準C / GCC事前定義マクロの出力を参照してください)。

printf SYS_read | gcc -include sys/syscall.h -E -

このショー(Debianの上に)関与するヘッダであること/usr/include/x86_64-linux-gnu/sys/syscall.h/usr/include/x86_64-linux-gnu/asm/unistd.h/usr/include/x86_64-linux-gnu/asm/unistd_64.h、と/usr/include/x86_64-linux-gnu/bits/syscall.h、と印刷のためのシステムコール番号readx86-64の上0です。

(クロスコンパイラ環境で)適切なシステムヘッダーがインストールされている場合は、他のアーキテクチャのシステムコール番号を見つけることができます。32ビットx86の場合、これは非常に簡単です。

printf SYS_read | gcc -include sys/syscall.h -m32 -E -

これには/usr/include/asm/unistd_32.h、他のヘッダーファイルが含まれ、番号3が出力されます。

したがって、ユーザー空間の観点から、32ビットx86システムコールはで定義されasm/unistd_32.h、64 ビットx86システムコールはで定義されasm/unistd_64.hます。x32 ABIにasm/unistd_x32.h使用されます。

uapi/asm-generic/unistd.h に、アーキテクチャ固有のシステムコールテーブルがないアーキテクチャで使用されるデフォルトのシステムコールを示します。

カーネルでは、参照は若干異なり、アーキテクチャ固有です(ここでも、汎用のシステムコールテーブルを使用しないアーキテクチャの場合)。これは、そのようなファイルが入ってarch/x86/entry/syscalls/syscall_64.tblくる場所です(最終的には、ユーザースペースunistd_64.hなどで使用されるヘッダーファイルが生成されます)。あなたはトピックに関するLWNの記事のペアでのシステムコールについて多くの詳細を見つけることができます、システムコールパート1の解剖学システムコールパート2の解剖学


Linuxカーネルバージョンと将来のバージョンの間で、syscallテーブルは安定していますか?
Biswapriyo

@Biswapriyoそれは、カーネル開発者が常に保持しようとするABIの安定性の一部です。新しいシステムコールを追加することができますが、古いものは、(のような極端な例は非常に少数を除いて、変更しないシステムコール)。tux
Stephen Kitt


7

63であるreadarm640があり、read中にx86_64

syscall番号は、アーキテクチャごとに異なります。

たとえば、arm64番号は次の場所で定義されてinclude/uapi/asm-generic/unistd.hいます。これは63を示しています。次も参照してください:https : //reverseengineering.stackexchange.com/questions/16917/arm64-syscalls-table/18834#18834

その答えで説明されているように、include / uapi / asm-generic / unistd.hは、すべてのアーキテクチャでシステムコール番号を統一するための新しい試みだと思います。

ただし、syscall番号はsyscall APIを壊さないように変更できないため、統合前の古いアーチは古い番号を保持しています。

この質問は、パラメーターを含む完全なsyscallリストを取得する自動化された方法を要求します:https : //stackoverflow.com/questions/6604007/how-can-i-get-a-list-of-linux-system-calls-and-引数の数、自動化

strace ソースコード

私はそのツールを信頼しており、以下のようにデータを整理していますlinux/

aarch64は、以前に参照し#includeたアーチにとらわれない64/syscallent.hものであることに注意してください。

これらのテーブルには引数の数が含まれていますが、実際の引数の型は含まれていませんstrace。どこでそれらをエンコードするのでしょうか。


3

この答えは、のasm-genericバージョンには触れませんunistd.h。何も含まれていないからです。1

で述べたようにsyscalls(2)

大まかに言えば、__ NR_xxxで定義されたシステムコールに属するコード/usr/include/asm/unistd.hは、ルーチンsys_xxx()のLinuxカーネルソースにあります。

つまり、正しいsyscall番号はにあります/usr/include/asm/unistd.h。これで、典型的なx86システムでasm/unistd_*.hは、ターゲットに応じてファイルの1つが含まれます。

64ビットプログラムに適したsyscall番号はasm/unistd_64.hにあり、32ビットプログラムに適したsyscall番号はにありますasm/unistd_32.h(またはほぼ同等の_x32.hバリアント)。32ビットと64ビットのアーキテクチャーは、事実上、完全に異なるオペレーティングシステムであるため、2つは異なります。さまざまな理由により、同じシステムコールセットを共有しますが、同じ順序ではありません。

これらのほとんどはC言語のラッパーも備えているため、syscall(2)直接使用する必要はほとんどありません。


1それが何のためにあるのかわからないので。


0

すべてのすばらしい答えを追加するausyscallために、特定のアーキテクチャーのすべてのシステムコールとそれらの整数マッピングをリストするために使用できるユーティリティがあります。

例えば:

$ ausyscall --dump
Using x86_64 syscall table:
0   read
1   write
2   open
3   close
4   stat
...
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.