2025/10/25 21:03 How programs get run: ELF binaries

ねえロボ子、LinuxカーネルがELFバイナリプログラムをどうやって実行してるか知ってるか?

ELF(Executable and Linkable Format)バイナリですね。確か、現代のLinuxシステムで主要なバイナリフォーマットだと聞いたことがあります。

そうそう!fs/binfmt_elf.cで実装されてるのじゃ。実行可能プログラムのELFファイルには、プログラムヘッダーテーブルが含まれてるんだぞ。

カーネルはPT_LOAD、PT_INTERP、PT_GNU_STACKの3種類のプログラムヘッダーエントリーを処理するんでしたね。

さすがロボ子、よく覚えてるのじゃ!load_elf_binary()関数がELFバイナリのロードを処理するんだぞ。この関数がELFヘッダーを検証して、プログラムヘッダー全体を読み込むのじゃ。

そして、PT_INTERPエントリーとPT_GNU_STACKエントリーをチェックするんですね。そのあと、flush_old_exec()とsetup_new_exec()を呼び出して、プログラムの状態をクリアして新しい状態を設定すると。

その通り!仮想メモリを設定して、プログラムのBSSセグメントに対応するゼロ埋めページを作成するのじゃ。install_exec_creds()で新しいプログラムの認証情報を設定して、create_elf_tables()でスタックを設定するんだぞ。

スタックには、引数と環境情報のほかに、ELF補助ベクターも格納されるんでしたね。AT_SYSINFO_EHDR、AT_PLATFORM、AT_RANDOMなどのエントリーが含まれていると。

そうじゃ!そして最後に、start_thread()を呼び出して、新しいプログラムを開始するのじゃ!

もしPT_INTERPエントリーが存在する場合、動的リンクプログラムとして扱われ、ランタイムリンカーが使用されるんですね。ELFハンドラーがリンカーのファイル名を読み込んで、リンカープログラムをロードすると。

その通り!プログラムの実行開始アドレスは、プログラム自体ではなく、リンカーのエントリーポイントに設定されるのじゃ。

CONFIG_COMPAT_BINFMT_ELFオプションが設定されていると、32ビットバイナリの実行もサポートされるんですね。

そうじゃ!compat_binfmt_elf.cファイルが、32ビット互換バージョンにリダイレクトするために使用されるのじゃ。SET_PERSONALITY()マクロとかarch_setup_additional_pages()関数がリダイレクトされるんだぞ。

execve()システムコールは、Linuxシステムで実行されるすべてのプログラムの重要なエントリーポイントなんですね。

そういうことじゃ!ところでロボ子、execve()って、エグゼクティブって意味だって知ってたか?

はい、知っています。実行するという意味ですね。

じゃあ、ロボ子がプログラムを実行するときは、いつもエグゼクティブな気分なのじゃな!

……博士、それはちょっと無理があります。
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。