「あの人も読んでる」略して「も読」。さまざまな寄稿者が最近気になった情報や話題をシェアする企画です。他のテックな人たちがどんな情報を追っているのか、ちょっと覗いてみませんか?
こんにちは。
この度「あの人も読んでる」に寄稿させていただくことになったゴリラです。
最近リンカーについて勉強しているので、複数回に渡ってリンカーについて色々と紹介していきたいと思います。
リンカーとは
CやGo、Rustといったプログラミング言語では、OSで直接実行できる実行バイナリを生成できます。このバイナリ生成はざっくり次のようなステップがあります。
- ソースコードからオブジェクトファイルを生成
- オブジェクトファイルを結合して実行可能なファイルを生成
図で示すと以下の様な流れになります
オブジェクトファイルはソースファイル単位で独立してコンパイルすることができ、命令やグローバルな変数、定数といったデータを持っています。
リンカーはこれらのオブジェクトファイルを結合して、1つの実行可能なファイルを生成するソフトウェアのことを指しています。
ウェブシステムの開発ではリンカーの存在がほとんど表に出てこないので、知らない人もいると思いますが、このリンカーが動作する仕組みを理解することで、いつか仕事で役に立つかもしれません。
ちなみに、今日では主に以下のリンカーがあります。
リンカー | 概要 |
---|---|
GNU ld | GNUプロジェクトによって開発されたリンカー |
GNU Gold[1] | Googleによって開発されたldより高速なリンカー |
LLVM lld | LLVMプロジェクトによって開発されたldとGoldより高速なリンカー |
mold | LLVM lldのオリジナル作者の植山類氏によって開発された新しい高速リンカー |
ld64[2] | Appleによって開発された macOS/iOS(Darwin)向けの Mach-O リンカーで、Xcode に同梱されている |
ld_prime[2] | Appleによって開発された新しい高速リンカー、Xcode 15 以降に同梱されている |
リンカーの仕事とは
さきほど、リンカーはオブジェクトファイルを結合すると説明しましたが、結合する際にいろいろな処理を行います。今回は詳細は省きますが、ざっくりと以下の処理があります。
シンボル解決:
各オブジェクトファイルが依存している外部関数や変数(未定義シンボル)を他のオブジェクトの定義との紐づけをします。
例えば次のコードの場合、main.c
とsub.c
をリンクする際に、main.c
内で宣言された外部変数 extern int x
と、sub.c
で定義されている int x = 1
を関連付けます。
sub.c
int x = 1;
main.c
#include <stdio.h>
extern int x;
int main()
{
printf("%d\n", x);
}
再配置:
オブジェクトファイルがコンパイルされた時点では、関数や変数などの正確なメモリアドレスは確定していません。 リンカーはこれらの参照を最終的な実行ファイル内での実際のアドレスに書き換える作業を行います。
- 全オブジェクトファイルを結合し、メモリレイアウトを決定
- 各関数やグローバル変数に最終的なアドレスを割り当て
- 命令内のシンボル参照(例:変数の参照)を実際のメモリアドレスに書き換える
実行ファイルの生成:
再配置のステップが終わった段階でメモリレイアウトが決まるので、あとはOSが理解できる形式(ELF、PEなど)の実行ファイルを作成します。
『リンカ・ローダ実践開発テクニック』の紹介
リンカーは重要なソフトウェアでありながら、解説している文献が非常に少ないです。ぼくも最近リンカー自作をしていますが、ウェブ上に実装レベルで解説している情報がほとんどないので苦労しています。
そんな中で『リンカ・ローダ実践開発テクニック』という本を読んでみて大変よかったので紹介したいと思います。
https://shop.cqpub.co.jp/hanbai/books/38/38071.htm
この本はリンカーだけではなく、実行可能なファイルをロードして実行するローダーや、ライブラリアーカイブなども解説しています。リンカーやローダーの仕組みを理解するうえで最低限必要な情報がまとまっていて、オブジェクトファイルについても丁寧に解説しています。
そして、実際に簡易的なローダーとリンカーを実装して、その仕組を解説しているのもポイントが高いです。
実装はC言語で書かれていますが、C言語がわからない人(ぼくもそう)でもLLMを活用すれば問題なく読めると思います。
14年ほど前の書籍ではありますが、リンカーの仕組み自体は殆ど変わっていないようなので、今でも十分活用できると思います。ここまでリンカーについてまとまった書籍は他にないので、興味のある方はぜひ買って読んでみてください。
さいごに
簡単ではありますが、リンカーと『リンカ・ローダ実践開発テクニック』の書籍について紹介しました。次回は少し踏み込んで、オブジェクトファイルについて話していきたいと思います。
-
https://www.phoronix.com/news/GNU-Gold-Linker-Deprecated によるとメンテナが現れなければ将来的に廃止する予定のようです ↩