関数 execve の実装 (x86_64 Linux で) を確認するにはどうすればよいですか? ライブラリ unistd にあります。execveを呼び出さずに、アセンブラを使用して外部プログラムを呼び出す方法を知りたいので、これが必要です。execve という名前のシステムコールがあることは知っていますが、それをどのように使用すればよいかわかりません。
char * 型と char * [] 型の変数をレジスタに入れるにはどうすればよいですか?
関数 execve の実装 (x86_64 Linux で) を確認するにはどうすればよいですか? ライブラリ unistd にあります。execveを呼び出さずに、アセンブラを使用して外部プログラムを呼び出す方法を知りたいので、これが必要です。execve という名前のシステムコールがあることは知っていますが、それをどのように使用すればよいかわかりません。
char * 型と char * [] 型の変数をレジスタに入れるにはどうすればよいですか?
ユーザースペースでの関数の実装は次のexecve()
ようになります。
int execve(const char *filename, char * const argv[], char * const envp[]) {
return syscall(SYS_execve, filename, argv, envp);
}
実際の「作業」はすべてカーネルで行われます。おそらくいくつかのスレッドのクリーンアップを除いて、libcで特に興味深いことが起こっていることはありません。
カーネル ソース (より具体的には: arch/YOUR-ARCH/kernel/head*.S) を参照して、アーキテクチャのシステム コール規則 (syscall 番号とパラメータのレジスタおよび/またはスタック) を確認してください。
たとえば、ARM では、__NR_execve
r7 にロードし、引数を r0、r1、r2 にロードしてから、swi 0
. 詳細については、この ARM EABI syscall の説明に興味があるかもしれません。
glibcのソースコードにシステムコールを実際に簡単に実装することはできません。これは、ビルド時にシステムコール番号を定義するさまざまなファイルから生成されます。
関連する情報は、実際のシステムコール番号を除いて、理解していればsysdep.h__NR_execve
にあります( IIRCで必要なの#include <asm/unistd.h>
は、x86_64の内容をすぐに思い出せないことです)。
システムコール番号は%raxになり、引数は%rdi%rsi%rdxになります。このすべての情報(スタックの配置やカーネルによるレジスタの使用に関する情報を含む)は、sysdep.hにコメントされています。