http://www-06.ibm.com/jp/developerworks/linux/library/l-system-calls/
や "Binary Hacks" #25 を読むと、
「unistd.h で _syscall0, _syscall1 などのマクロが定義されており、そのマクロを使うことで、
libc を使わずに直接システムコールを発行できる」と書いてあります。
ところが、自分のシステム (ubuntu 7.04, AMD Athlon(tm) 64 X2 Dual Core Processor 4600+) の、
/usr/include/unistd.h (と、そこで include されているヘッダファイル) を見たところ、_syscallN の定義はありません。
また、Linux kernel のソースそのものを見ても、そのような定義はありません。
最近の Linux ではシステムコールの発行のしくみが代わったのでしょうか?
現在のしくみと参考文献を教えてください。
当該記事を見ました。
× /usr/include/unistd.h
○ /usr/include/linux/unistd.h
ではないですか?(もしくは、/usr/include/asm/unistd.h)
※RHEL4/RHEL5で確認したので、Ubuntuでは違うかもしれませんが。
OpenSUSE10.1を使用しております。
カーネルのバージョンは2.6系です。
私の環境の場合、
/usr/include/unistd.h は /usr/include/asm/unistd.h をインクルードしており、その中に_syscallNをインラインアセンブラで記述しているようです。
ですので、システムコールの仕組みは昔と変わらず、「int 0x80」から変わっていないと思います。
そうですか・・・。ディストリビューションによって変わるとは思えないんですが・・・。
何か大きな勘違いをしているのかもしれません。
sysenter/sysexitという方法もあるようなので、x86_64ではsysenter/sysexitを使っているのではないでしょうか?
消去法で考えればそうなんですが、ソースを知りたいんですよね・・・。
当方のUbuntsu 7.04 (amd64)では、 定義本体は
/usr/include/asm-x86_64/unistd.h
のようですが、上記の他
/usr/include/linux/unistd.h
/usr/include/asm/unistd.h
を探しても、__SYSCALL(a,b)はあっても、_syscallNはありませんでした。
また、system callは、/usr/include/unistd.hに定義されているsyscall()を使えば同じことができるような気がします。
御参考まで。
syscallは、システムコールを発行するためのwrapper functionだと思うので、「libcを使わずにシステムコールを発行できる」ことにはなりませんよね。
source codeを読んでいない上での回答で申し訳ないのですが、当該の書籍であるBinary Hacksを読むと、Hack #59にLinux 2.6からはsystenterがサポートされたとあります。
sysenterを使っている積極的な証拠が見たいです。
glibcのソースかなぁ・・・。
2回目の回答で申し訳ないです。
以下のメールによると、コメント欄に、
Ubuntu: Don't use _syscall macro
とあり、Ubuntuでは_syscallマクロは使うべきでないとあります。
http://www.redhat.com/archives/linux-cluster/2006-August/msg0006...
また、下記のManpageを見ると、
いくつかのアーキテクチャ、特に ia64、では _syscall マクロは提供されていない。
ともあります。ia64とamd64とはアーキテクチャが違いますが、同じ64bitであるため類似点として挙げられるのではないかと思います。
http://www.linux.or.jp/JM/html/LDP_man-pages/man2/intro.2.html
参考ですが、RHEL4/RHEL5 の /usr/include/linux/unistd.h を見た所、RHEL4 では _syscallマクロの記載方法が具体的に明記されていましたが、RHEL5では当該ソース(コメント)は全て取り外されているように見受けられました。
これらのことからも、_syscallマクロは使用すべきでは無いということではないでしょうか。
ありがとうございます。
id:daichan330さんを含め、皆さんからいただいた情報をもとに、もう少し調べてみます。
すみません。unistd.h のパスを書き間違えました。パスについてはご指摘の通りです。
ただし、/usr/include/unistd.h, /usr/include/linux/unistd.h のどちらにも _syscallN の定義はありません。
CentOS5にもなかったので、RHEL5にもないと思うのですが・・・。