Article Outline
動的リンクについて (Linux)
Linuxの動的リンクについて学習したため、そのまとめとしてここに整理する。
動的リンクとは
- プログラムとライブラリを連結させる方法の一つで、予めコンパイルされ所定の場所に置かれているオブジェクトファイル(共有ライブラリ)を読み込むように連結させる方法。
- コンパイル後の実行ファイルには、ライブラリ自体のコードは含まれず、共有ライブラリをロードし呼び出す処理が含まれる。
- 正反対の連結方法として静的リンクという方法が存在し、プログラムのコンパイル時にライブラリを直接埋め込んだ状態で実行ファイルを生成する。
動的リンクのメリット
- ライブラリ自体のコードが含まれないため、静的リンクよりもファイルサイズが小さくなる。
- ライブラリを実行ファイルに直接埋め込まないため、ライブラリのアップデートやリプレイスが静的リンクに比べ容易に行える(静的リンクの場合は再コンパイルが必要)。
動的リンクのデメリット
- ライブラリの有無など、プログラムの実行環境に依存する(実行環境に共有ライブラリが存在しない場合など実行できない)。
共有ライブラリの検索
- 動的リンクによってプログラムをコンパイルする際、共有ライブラリは以下の順序で検索される。
- 環境変数
LD_LIBRARY_PATH
で指定されているパスの配下 - 設定ファイル
/etc/ld.so.cache
内に記載されているパスの配下 /lib
,/usr/lib
の配下
動的リンクでコンパイルされた実行ファイルについて
- Linuxにおいて、実行ファイルは
ELF
という形式に基づいて生成される。(ELFに関しては別記事にて整理) - ライブラリ呼び出す処理は、
PLT (Procedure Linkage Table)
内のエントリを介して呼び出すように抽象化されており、ライブラリの関数名の末尾に@plt
が付与されている。 PLT
自体は.plt
セクションに配置されており、各エントリ内ではGOT (Global Offset Table)
と呼ばれる「プログラム実行時に共有ライブラリをロードしたメモリのアドレス等を管理しているテーブル」からアドレスを取得し呼び出している。
共有ライブラリのロード
- Linuxにおいて動的リンクが必要なELF実行ファイルを実行する際、共有ライブラリは以下の流れでロードされる。
- カーネルはELFファイルの
.interp
セクションから動的リンカ(動的リンクを行うプログラム)が存在するパスを読み込み、そのパスから動的リンカをメモリにロードする。 - 動的リンカは実行ファイルの
.dynamic
セクションから共有ライブラリが存在するパスを読み込み、メモリにロードする。 - 動的リンカは共有ライブラリをロードしたアドレスで
GOT
の各エントリを書き変える