最適化リンケージエディタは、命令の参照先シンボルの配置アドレスに応じてコードサイズの小さな命令に置き換える最適化を行います。よりコードサイズを小さくする効果を得るために、より多くの命令に対して置き換えを試みます。
しかし、命令の置き換えを実施した結果、参照先のシンボルの配置アドレスが変わってしまい、置き換えられた命令ではシンボルを参照できなくなってしまうケースがあります。最適化リンケージエディタでは、このような場合に問題のあるコードを生成しないためにE0562330エラーを出力して停止します。
この事象は、RXアーキテクチャの特性から、最適化前は FFFF8000h 番地以上にあるシンボル(変数や定数、スイッチテーブルなど)が最適化後にFFFF8000h 番地以下に配置を変更された場合に発生することがあります。
定数 CONST1,CONST2 を読み出すプログラムにおいて、最適化前のPセクションとCセクションが次のようにあり、Pセクションに後続してCセクションがFFFF8000hに配置されていたとします。
; 6byte命令 MOV.L #_CONST1:32, R1
MOV.L #0FFFF8002H, R1
; 6byte命令 MOV.L #_CONST2:32, R2
MOV.L #0FFFF8006H, R2
_CONST0: ; FFFF8000h に配置
.byte 00H,01H
_CONST1: ; FFFF8002h に配置
.byte "123"
.byte 00H
_CONST2: ; FFFF8006h に配置
.byte "abc"
.byte 00H
最適化によりCセクションの配置アドレスFFFF8000H(32bit即値)を-8000H(符号付き16bit即値)に出来るので、32bit即値転送MOV.L命令を16bitの即値転送命令に置き換えます。
これにより、Pセクションサイズは縮小し、後続するCセクションもより小さなアドレスに移動することになります。
; 4byte命令 MOV.L #_CONST1:16, R1
MOV.L #-8002H, R1 ; 符号付き16bitの範囲を超える。
; 4byte命令 MOV.L #_CONST2:16, R2
MOV.L #-7FFEH, R2
_CONST0: ; FFFF7FFCh に配置
.byte 00H,01H
_CONST1: ; FFFF7FFEh に配置
.byte "123"
.byte 00H
_CONST2: ; FFFF8002h に配置
.byte "abc"
.byte 00H
結果として、複数の MOV.Lの最適化の影響により、定数 CONST1が符号付き16bitで現せる範囲を超えた領域に配置され、次のようなE0562330エラーが発生します。
E0562330:Relocation size overflow : "fileA.obj"-"P"-"0000002"
以下に問題発生箇所の推定方法を示します。問題発生個所は次のように推定できます。
まず、最適化リンケージエディタを、nooptimizeオプションとlistオプションを指定してビルドし、リンク・マップ・ファイルを生成します。リンク・マップ・ファイルで "*** Mapping List ***"と書かれた行以降にセクション配置情報が出力されているので、FFFF8000h番地以降に配置されているセクションを調べます。
*** Mapping List ***
C
ffff7ffc ffff8005 a 1
次に、アセンブラにlistfileオプションを指定してビルドし、ソース・リスト・ファイルを生成します。エラーメッセージが示すオブジェクトファイル(例3では"fileA.obj")に対して生成されたソース・リスト・ファイルで、エラーメッセージが示すセクション(例3では"P")を探します。
最適化リンケージエディタが出力するエラーメッセージ中のオフセットは最適化実施後のオフセットになります。
このため、ソース・リスト・ファイルの中では、当該オフセット(例3では"0000002")以降にある命令でFFFF8000h番地以降に配置されているセクション内のシンボルを参照する命令が対象になりますので、その命令を調べてください。
例5では、FFFF8000h番地以降に配置したCセクションにある、定数 CONST1にアクセスする命令MOV.L が該当し、Cセクションに原因があることが特定できます。
.section P, CODE
00000000 FB1Arrrr MOV.L #_CONST1:16, R1 <- セクションCへのアクセス
00000004 FB2Arrrr MOV.L #_CONST2:16, R2
.section C, ROMDATA
00000000 _CONST0:
00000000 0001 .byte 00H,01H
00000002 _CONST1:
00000002 313233 .byte "123"
00000005 00 .byte 00H
00000006 _CONST2:
00000006 616263 .byte "abc"
00000009 00 .byte 00H
最適化無しではFFFF8000h番地以降に配置されていて、最適化有りではセクション先頭位置がFFFF8000h番地以前にあるセクションについて、startオプションでセクションの順番を入れ替える。
-start=P,C,L,D/FFFF7000
-start=P,L,C,D/FFFF7000
変更後でも同様のE0562330エラーが発生する場合があります。その場合は適宜入れ替えるセクションの組み合わせを変更してください。
最適化無しではFFFF8000h番地以降に配置されていて、最適化有りではセクション先頭位置がFFFF8000h番地以前にあるセクションについて、startオプションでFFFF8000h番地にセクションを配置する。
-start=P,C,L,D/FFFF7000
-start=P/FFFF7000,C,L,D/FFFF8000
-nooptimizeにより最適化全てを抑止するか、エラーの発生有無と最適化効果(サイズ)を見ながら-optimizeオプションのサブオプションを選択する。