本文へ
ハクソク

世界を動かす技術を、日本語で。

Mold Linker バージョン 3.0.0 リリース – Rust で書き直し

元記事: 原文(github.com)

概要

  • mold 3.0.0 は高速リンカの新しいメジャーリリース
  • C++からRustへ全面書き換え、初のRust版リリース
  • 2.42.1 がC++版の最終リリース
  • GNU ld互換性向上 とLinuxディストリビューション標準化を目指す
  • 既存のコマンドやアーキテクチャ互換性維持、パフォーマンスも同等

mold 3.0.0 の主な変更点

  • C++からRustへの全面移行

    • コードベースを Rust で再実装
    • 安全性向上 :異常入力での境界チェック追加、セグメンテーションフォールト回避
  • GNU ldとの互換性強化

    • リンカスクリプト対応 など、互換性ギャップの解消を推進
    • Gentoo全パッケージ でのビルド検証済み、リグレッションなし
  • 2.42.1との完全な互換性

    • コマンドラインオプション・ターゲットアーキテクチャ に互換
    • 出力内容もバグ修正を除き同一
    • リンク性能 も2.42.1と同等
  • 安全性の向上

    • 異常入力ファイル での動作改善
      • C++版はメモリ範囲外アクセスでクラッシュ
      • Rust版はパニックで停止し、安全に処理

ビルド方法の変更

  • ビルドシステムの刷新

    • CMakeからCargoへ移行
    • 必要要件: Rust 1.95以降、Cコンパイラ
    • ビルド:cargo build --release
    • インストール:./install-mold.sh(PREFIX, DESTDIR対応)
    • CMakeオプション廃止
  • ライブラリ配置の注意

    • $PREFIX/lib以外(例:/usr/lib64)にインストール時はMOLD_LIBDIR環境変数を設定
  • 依存関係の変更

    • oneTBB依存廃止
    • mimalloc 3.5.3 を静的リンク(--features system-allocatorでシステムmalloc利用可)
    • zlib はシステム提供があればリンク、 zstd/BLAKE3 も同梱
    • ZSTD_SYS_USE_PKG_CONFIG=1でシステムzstd使用可
  • ターゲットビルド

    • Cargo features でターゲット指定
    • 配布物は全ターゲット対応が推奨
  • テスト実行方法

    • cargo testでテストスイート実行
    • install-test-deps.shでテスト用依存のみインストール

バグ修正・互換性改善

  • クラッシュや出力破損の修正

    • バージョンスクリプトや--default-symver利用時の静的リンク時クラッシュ修正
    • 出力ファイルを入力にも指定した場合のクラッシュや破損修正
    • --gc-sectionsで--initや--fini指定関数が削除されないよう修正
    • 同名・異サイズのcommon symbolで最大サイズ・厳密なアライメントを採用
  • ICF関連の修正

    • --icf=safeで共有ライブラリからエクスポートされた関数をマージしない
    • --icf=allと--emit-relocs併用時のクラッシュ修正
  • アーカイブ・シンボル関連

    • バージョン付き参照が未バージョン定義を引き込まないよう修正
  • 出力の決定性向上

    • --dependency-fileや--repro、COMDATグループ、動的リロケーションなどで出力の非決定性を解消
  • -r関連の複数修正

    • C++例外の破損、シンボル除去、データ損失、sh_link設定ミス、--strip-debug時のクラッシュなど修正
  • リロケーション関連

    • GOT相対リロケーションの誤アドレス修正、エラー報告強化
    • PC相対リロケーションの説明追加
  • エラー処理の強化

    • 不正な--defsymや未定義シンボル、圧縮済み割当セクション、--strip-all併用時のエラー化
  • コマンドラインオプション互換

    • 単一ダッシュオプションの解釈をGNU ld準拠に修正
  • 追加・改善されたオプション

    • --dynamic-list-data等の引数消費バグ修正、--no-color-diagnostics追加
  • バージョンスクリプトの優先順位修正

    • 複数ノード記載時、最初のノードを優先
  • パス・仮想アドレス空間関連

    • -C, --chroot, --reproでの相対パス修正
    • 起動時の仮想アドレス空間8GiB予約廃止、ulimit -v対応
  • 環境変数・デバッグファイル関連

    • MOLD_JOBSの空文字対応
    • --separate-debug-file生成ファイルから.gnu_debuglinkセクション削除
  • 無意味なシンボル生成廃止

    • __start_EHDR等の不要シンボルを生成しないよう修正

各アーキテクチャ固有の修正・強化

  • AArch64/PPC32/ARM32
    • 範囲拡張スランクによる静的関数呼び出しの誤ジャンプ修正
  • AArch64
    • 新しいリロケーションタイプ(例:R_AARCH64_TSTBR14等)対応
  • ARM32
    • 新しいリロケーションタイプ、ビッグエンディアン時の-r出力修正
  • ARM32/i386
    • 一部分岐やTLSリロケーションでの命令破損修正
  • RISC-V/LoongArch
    • --icf=allによる関数折りたたみ時の呼び出し修正、32bitオブジェクトでのリロケーション修正
  • RISC-V
    • Clang 18生成オブジェクトやTLSDESC、--emit-relocs、フラグ、アラインメント、オーバーフロー等の修正
  • LoongArch
    • Extreme code modelでのTLSDESC対応、リロケーション値・TLS関連エラー修正
  • PPC32/m68k
    • GOTが16bitオフセット超過時にエラー化
  • PPC64
    • 静的リンク実行ファイルでのIFUNC呼び出し、アセンブリでの@got参照、関数合成対応
  • SH4
    • PLT経由の構造体返却関数呼び出しやC++例外のクラッシュ修正
  • SPARC64
    • ブランチ命令やリロケーション出力修正

謝辞

  • moldはオープンソースプロジェクト
    • GitHub SponsorsやOpenCollective経由での寄付を受付
    • 特に$32/月以上のスポンサー(Cybozu, Inc.、SAP、Mercedes-Benz Group、Signal Slot Inc.、Mercury、G-Research Open Source Software、Jinkyu Yi、kraptor23、Ahrefs、Pedro Navarro、Wei Wu、daquexian、CubeSoft, Inc.、Josh Triplett、nomeaning)へ感謝

提供: ハクソク · 要約更新:

AIによる日本語要約です。内容は原文とあわせてご確認ください。

Hacker Newsの議論を読む

Hackerたちの意見

これが数ヶ月かかるリライトになると思ってたのに、たった3週間で終わるとは。今はエージェントの時代だってことを忘れそうになったよ。追記:最初のコミットが出たときから、これがずっと進行中だったみたいだね。https://github.com/rui314/mold/commit/f41bfcd5c72ca30cce6498...

└

コンバージョンは手伝ってもらったの?Moldの作者ってすごく優秀な人だと思うから、彼なら一人でもできるんじゃないかな。

じゃあ、今のmoldとwildの違いは何なの? wildは違うデータ構造を使ってるの?(wildは別の高速リンカーで、Linuxだけをサポートしてる)

└

wildの主な目的はインクリメンタルリンクだよね。今の主な違いは、プロジェクト間のレースと微妙なパフォーマンスの違いかな。

└

Wildを指摘してくれてありがとう。

僕が共同メンテしてるLinuxディストリビューションでは、moldをブートストラップリンカーとして使ってるんだけど、これのおかげでバージョンごとのビルドチェーンで-何時間も-節約できたよ。moldがCで書かれてるから、早い段階でビルドできて、デフォルトリンカーとして全体で使えるようになったし、ビルドのスピードアップも享受できた。残念ながら、これからはmold2としてC版をフォークしてメンテし続けなきゃいけないね。Rustは実際にはすべての問題に対する正しいツールではない。

└

Moldのメンテナンス負担を減らすために言語を切り替える決定が、どうしてRustをここで間違ったツールにするのかちょっと混乱してる。リソースを考えると、恐れ知らずの並行性は彼らがやってることにとって大きな利点に思えるんだけど。

└

必要が十分に正当化されるなら、#[no_mangle]やextern Cサポートを追加するようお願いするチャンスがあるかも?リリースがとても新しいからね。それが問題を引き起こしてるのかな?それとも何か依存関係が問題?

└

RustをリンクするのにLLDを使わないのはなぜ? RustをビルドするためにはすでにLLVMが必要だから、依存関係は増えないよね。

└

再現性があり、密閉されたビルドを持つことで、同じ作業を何度も繰り返さないようにするのが良さそうだね。そうすれば、最新のビルド版を使ってmoldや次のバージョンのRustをビルドできるよ。

└

最近、Rustのブートストラップについて考えてたんだけど、借用チェッカーなしのRustコンパイラって比較的簡単に作れないかな?ソースコードに問題がなければ(それはRustコンパイラができた後にチェックすればいいし)、その部分は置いといて、.rsから実行コードへの最短ルートを取れると思うんだ(Cへのトランスパイルとか、インタプリタでも)。

└

ディストリをブートストラップするためにツールチェーンをブートストラップする必要があるのはなんで?一般的なことだとは思うけど、なんか美的な決定かglibcの余計なものに見える。

Hacker Newsで議論の続きを見る

同じ出典の記事