リンカ自作メモ

はじめに

二年前にC++の勉強のついでに作った簡単な静的オブジェクトのリンカを書いた。

github.com

今度はRustで書き直している。最初の目標はlibc.soを動的or静的リンクして、Hello worldを動かすこと。

github.com

現時点での参考文献を挙げる。

mold

github.com

Rui Ueyamaさんの作っているとにかく速いリンカ。 自分は2021年あたりのコミットにcheckoutして読んでいる。

moldの優れた点は

  • コードがわかりやすい
  • 小さなコードでマルチアーキ対応をしている
  • できるだけ多くの箇所で並列化している

例えば、ELFヘッダ、セクションヘッダ、.textセクションなど異なる構造をChunkというクラスで上手く操作・管理している。初めてリンカをつくったときは、ヘッダやセクションの管理に苦労したため参考になった。

ただ、生ポインタの循環参照が多くunsafeなしのRustで同じことをやろうとすると、かえって複雑になる。Rustには循環参のためのポインタ型Weak<T>が用意されているが、これを使わずに、HashMap<Item, ItemId>のようなプールを作り、ItemIdを参照代わりに使うほうが良いと思う。

moldではリンカの各ステージで、tbb::parallel_for_eachを呼び出す構造になっており、クラスの同じフィールドに対して、読み出しと書き込みが同時に発生しないように注意して作られている。Rustではthread safetyが厳しく検査されるため、これを実現するには、構造体の各フィールドをMutexでラップするだけでは不十分で、スピンロックを使う必要がある。

lld

github.com

LLVMツールチェインのリンカ。 初めてリンカを書いたときに参考にした。

Tool Interface Standard (TIS) Executable and Linking Format (ELF)

https://refspecs.linuxfoundation.org/elf/elf.pdf

ELFの仕様書。情報が多いが、実装したい箇所の情報を取り出すのが難しい。というのもELFはリンカが使わない情報(ローダー、デバッグ情報)を含むからだ。 構造体のフィールドの意味を知りたいときに、辞書的に使うと良いと思う。

readelf (binutils)

readelf (GNU Binary Utilities)

リンカ自作の初期は、readelfに認識されるようなファイルを出力することが目標になる。 アラインメントがずれていたり、不正な値が入っているときは、警告を出してくれる。objdumpよりもよく使う。

Linkers and Loaders

https://www.amazon.co.jp/-/en/JohnR-Levine/dp/4274064379

20年以上前(2001年)の本なので古い。リンカについて知らない人が最初に読むにはいいかもしれない。


まだ読んでないものとしては以下の通り。

Linkers ブログシリーズ, Airs – Ian Lance Taylor

Airs – Ian Lance Taylor » Linkers part 1

goldの作者のブログ。

リンカ・ローダ実践開発テクニック

リンカ・ローダ実践開発テクニック

数少ないリンカの和書の一つ。読んだことない。


既存のリンカ

macOS/iOSwindowsはどのリンカを使っているのだろうか?