これはすべてのシステムコールに適用されますが、例のように exit() を使用します。
sys_exit() 形式の関数は、exit() と考えられる関数を実装するカーネル ルーチンへの実際のエントリ ポイントです。これらのシンボルは、ユーザーモードのプログラマーも利用できません。つまり、カーネルをハッキングしていない限り、これらの関数にリンクすることはできません。これらの関数のシンボルはカーネルの外では使用できないためです。次のようなファイルスコープ機能を持つ libmsw.a を書いた場合
static int msw_func() {}
定義されている場合、libmsw シンボル テーブルにエクスポートされていないため、リンクしようとしても成功しません。あれは:
cc your_program.c libmsw.a
次のようなエラーが発生します。
ld: cannot resolve symbol msw_func
エクスポートされていないためです。カーネルに含まれている sys_exit() にも同じことが当てはまります。
ユーザー プログラムがカーネル ルーチンに到達するには、syscall(2) インターフェイスを使用して、ユーザー モードからカーネル モードへの切り替えを行う必要があります。そのモード切り替え (トラップと呼ばれることもあります) が発生すると、小さな整数を使用して、整数をカーネル関数にマップするカーネル テーブル内の適切なカーネル ルーチンを検索します。テーブルのエントリの形式は次のとおりです。
{SYS_exit, sys_exit},
SYS_exit はプリプロセッサ マクロで、
#define SYS_exit (1)
変更する理由がないため、生まれる前から 1 です。また、単純な配列インデックスを検索するシステム コールのテーブルの最初のエントリでもあります。
質問で指摘したように、通常のユーザーモード プログラムが sys_exit にアクセスする適切な方法は、glibc (または同様のコア ライブラリ) のシン ラッパーを使用することです。SYS_exit や sys_exit をいじる必要がある唯一の理由は、カーネル コードを書いている場合です。