はじめに
二年前にC++の勉強のついでに作った簡単な静的オブジェクトのリンカを書いた。
今度はRustで書き直している。最初の目標はlibc.soを動的or静的リンクして、Hello worldを動かすこと。
現時点での参考文献を挙げる。
mold
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
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の作者のブログ。
リンカ・ローダ実践開発テクニック
数少ないリンカの和書の一つ。読んだことない。
既存のリンカ
- GNU ld
- gold
- lld
- mold
- IL Linker (.NETのリンカ)