概要
- ARMの d4d4命令 が何か疑問に思った事例の調査
- LLDリンカ がd4d4を挿入する理由の解析
- GNU ld との動作比較
- d4d4命令の アーキテクチャ的意味 の検証
- 結論として、d4d4は 本来のトラップ命令ではない という指摘
ARMのd4d4命令とリンカの挙動調査
-
ARMの Thumb命令セット で、d4d4が不自然に挿入されている現象の発見
-
LLVMのobjdump によるとd4d4は「相対分岐命令(bmi)」として解釈
-
該当命令は 常に到達不能領域 に配置されている実例
-
Cコード上は単純な関数リターンのみ、余計な命令は不要なはず
-
1関数のみの場合にd4d4が出現し、2関数だと消える、3関数で再度出現など 挙動の変化
- 関数配置やオブジェクトファイルの順序 によってd4d4の位置が変化
-
main.o などのオブジェクト単体にはd4d4は存在せず、 リンク後に挿入 される
-
LLDリンカ がd4d4を使ってオブジェクト境界を 32bitアラインメント していると推測
-
GNU ld は同じ場面で 0x0000(movs r0, r0) を挿入、より無害なパディング
LLDのd4d4挿入理由と由来
- LLVM lldのソースコード (ARM.cpp)にて、trapInstr = {0xd4, 0xd4, 0xd4, 0xd4}と明記
- コミットログ によると、Theo de Raadtの提案で「トラップ命令」としてd4d4を推奨
- x86系の0xCC(int3)と同様の「穴埋めトラップ命令」目的で導入
- 公式ML等に明確な根拠は見当たらず、設計者の判断に依存
d4d4命令の実際の意味と問題点
- ARMv7-Mアーキテクチャリファレンスマニュアル にてd4d4のデコードを確認
- d4は 0b11010100、Thumbの16bit命令として解釈
- 0b1101xxは 条件付き分岐命令 (B命令)に該当
- d4d4は「bmi -0x58」(条件付き相対分岐)にデコードされる
- UDF(未定義命令) や SVC(スーパーバイザコール) ではない
- トラップ命令 としての本来の役割(CPU停止)を果たさず、分岐命令でしかない
- 条件が揃えば コードの他領域へジャンプ する可能性があるため安全性に疑問
結論と提言
- objdumpの解析は正しい、d4d4は分岐命令
- LLDが「トラップ命令」としてd4d4を選んだのは 設計ミスの可能性
- 本来は未定義命令(UDF) や NOP 等の方が安全
- LLDの現仕様では、 意図しない分岐 が発生するリスク
- GNU ld のように無害な値(0x0000等)を使う方が望ましい
- バグ報告を推奨、今後の修正が期待される
まとめ
- ARM/Thumb環境で LLDリンカが挿入するd4d4命令 は「トラップ」ではなく「条件付き分岐」
- 安全性や意図に疑問 が残る実装
- ARM向けリンカの パディング命令選択 には注意が必要