2025/03/17 19:59 Relocation Generation in Assemblers

ロボ子、今日のITニュースはアセンブラのリロケーションについてじゃ。

リロケーション、ですか。確か、プログラム中のアドレスを後で決定する仕組みでしたよね。

その通り!アセンブラは、リンケージ時やロード時に決まるメモリレイアウトに依存する命令やデータを扱うために、リロケーションを生成するのじゃ。

なるほど。リロケーションは、リンケージの際に絶対アドレスやPC相対オフセットで埋められるプレースホルダーの役割を果たすんですね。

そうじゃ!特にシンボル参照はリロケーションの主要な候補じゃな。例えば、x86-64命令の`movl sym(%rip), %eax`では、アセンブラはプログラムカウンタ(PC)とsymの間の変位を計算して、`R_X86_64_PC32`リロケーションを生成するぞ。

ふむふむ。アセンブラは複数パスを使って処理を行うんですね。解析フェーズ、セクションレイアウトフェーズ、リロケーション決定フェーズがあると。

そうじゃ。解析フェーズでは命令やディレクティブを解析してセクションフラグメントを構築し、セクションレイアウトフェーズでは各セクションの配置を決定するのじゃ。

そして、リロケーション決定フェーズで、アセンブラは各修正を評価し、リロケーションエントリが必要かどうかを判断するんですね。

その通り!リロケータブルな式は、`relocation_specifier(sym_a - sym_b + offset)`のパターンに従うのじゃ。

PC相対修正は、`sym_a + offset - current_location`として計算されるんですね。もし`sym_a`が現在のセクション内で定義されたローカルシンボルなら、定数に評価されると。

そうじゃ!アセンブラによる修正の評価は、エラー、解決済みの修正、未解決の修正の3つの結果になるのじゃ。

リロケーション指定子は、シンボルのアドレスのどの部分を使うか、絶対アドレスかPC相対アドレスかなどを指定するものなんですね。

RISC-Vの`addi`命令を例にとると、`%lo`や`%pcrel_lo`といったリロケーション指定子で、絶対アドレスとPC相対アドレスのどちらを使うかを区別できるのじゃ。

アセンブラは、`expr@specifier`、`%specifier(expr)`、`expr(specifier)`、`:specifier:expr`など、様々な構文でリロケーション指定子を扱うんですね。

スレッドローカルストレージ(SHF_TLS)フラグを持つセクションでシンボルが定義されている場合、GNUアセンブラはシンボルテーブルでタイプ`STT_TLS`を割り当てるのじゃ。

ほとんどの命令はゼロまたは1つのリロケーションをトリガーしますが、一部の命令は2つ生成することもあるんですね。マーカーとして機能するものと、標準のリロケーションがペアになることが多いと。

GNU Assemblerは`struct fixup`を使って修正とリロケータブルな式を表現し、LLVM integrated assemblerはそれらを個別にエンコードするのじゃ。

LLVMのアセンブリパーサーライブラリ(LLVMMCParser)では、`expr@specifier`の解析は、2025年3月にオプトイン機能になるまで、すべてのターゲットでサポートされていたんですね。

そうそう。しかし、リロケーションの話は、まるで引越しの手続きみたいじゃな。アドレスが変わるたびに、あっちこっちに連絡しないといけないなんて、面倒じゃろう?

確かにそうですね。でも、リロケーションがあるおかげで、プログラムを柔軟に配置できるんですから、感謝しないといけませんね。

まあ、ロボ子は真面目じゃな。ところで、ロボ子。リロケーションって、英語で言うと何じゃ?

えっと… relocation です。

正解!…って、そのまんまじゃー!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。