リンカ・ローダと実行形式

オブジェクトファイルを逆アセンブルすると、外部の関数printfを呼ぶ命令の飛び先が0のように仮の値になっていた。この値はいつ正しく埋められるか。

  1. Aコンパイラの誤りなので、ソースコードを直さないと埋められない
  2. BCPUが命令を実行する瞬間に、飛び先を推測して決める
  3. Cリンクのとき(動的リンクなら一部は実行時)に、再配置情報にもとづいて埋められる
答えと解説を見る

正解:C. リンクのとき(動的リンクなら一部は実行時)に、再配置情報にもとづいて埋められる

コンパイルの時点ではprintfの番地が分からないので、コンパイラは飛び先を仮の値にし、「この命令のこの欄にprintfの番地を入れる」という再配置情報を残します。リンカはそれを見て正しい値を書き込みます。動的リンクなら、PLTの入口を指すように書き換え、実際のライブラリ関数の番地は実行時に動的リンカがGOTに入れます。

  • A. 誤りではなく、再配置を前提にした正常な状態です。
  • B. CPUが飛び先を推測して決めることはありません。
  • C. 正しい。仮の値は正常な状態です。
この分野を解く 分野ページへ

リンカ・ローダと実行形式のほかの問題

  1. 組込み向けの開発で使うリンカスクリプトの役割として正しいものはどれか。
  2. OSのないマイコンで、電源を入れた直後に起動コードがmainを呼ぶ前に行う処理として正しいものはどれか。
  3. ELFのファイルにおける「セクション」と「セグメント」の違いとして正しいものはどれか。
  4. メモリのページに「書き込み可能」と「実行可能」を同時には許さない(W^X、書き込みと実行の分離)ことで防ぎやすくなる攻撃はどれか。
  5. Linuxの共有ライブラリで、libfoo.so.1の「.1」のようなsonameのバージョン番号を上げるのは、一般にどのようなときか。