11.4 最適化リンケージエディタにおいて最適化有効時のE0562330エラー発生の回避

最適化リンケージエディタは、命令の参照先シンボルの配置アドレスに応じてコードサイズの小さな命令に置き換える最適化を行います。よりコードサイズを小さくする効果を得るために、より多くの命令に対して置き換えを試みます。

 

しかし、命令の置き換えを実施した結果、参照先のシンボルの配置アドレスが変わってしまい、置き換えられた命令ではシンボルを参照できなくなってしまうケースがあります。最適化リンケージエディタでは、このような場合に問題のあるコードを生成しないためにE0562330エラーを出力して停止します。

 

この事象は、RXアーキテクチャの特性から、最適化前は FFFF8000h 番地以上にあるシンボル(変数や定数、スイッチテーブルなど)が最適化後にFFFF8000h 番地以下に配置を変更された場合に発生することがあります。

 

(1)

概略

以下にエラー発生に至るまでの概略を示します。

 

定数 CONST1,CONST2 を読み出すプログラムにおいて、最適化前のPセクションとCセクションが次のようにあり、Pセクションに後続してCセクションがFFFF8000hに配置されていたとします。

 

例 1.

Pセクション

            ; 6byte命令 MOV.L #_CONST1:32, R1
            MOV.L #0FFFF8002H, R1
 
            ; 6byte命令 MOV.L #_CONST2:32, R2
            MOV.L #0FFFF8006H, R2

 

Cセクション

            _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セクションもより小さなアドレスに移動することになります。

 

例 2.

Pセクション

            ; 4byte命令 MOV.L #_CONST1:16, R1
            MOV.L #-8002H, R1  ; 符号付き16bitの範囲を超える。
 
            ; 4byte命令 MOV.L #_CONST2:16, R2
            MOV.L #-7FFEH, R2
 

Cセクション

            _CONST0:                       ; FFFF7FFCh に配置
                .byte 00H,01H
            _CONST1:                       ; FFFF7FFEh に配置
                .byte "123"
                .byte 00H
            _CONST2:                       ; FFFF8002h に配置
                .byte "abc"
                .byte 00H

 

結果として、複数の MOV.Lの最適化の影響により、定数 CONST1が符号付き16bitで現せる範囲を超えた領域に配置され、次のようなE0562330エラーが発生します。

 

例 3.

            E0562330:Relocation size overflow : "fileA.obj"-"P"-"0000002"

 

(2)

問題発生箇所の推定方法

以下に問題発生箇所の推定方法を示します。問題発生個所は次のように推定できます。

 

まず、最適化リンケージエディタを、nooptimizeオプションとlistオプションを指定してビルドし、リンク・マップ・ファイルを生成します。リンク・マップ・ファイルで "*** Mapping List ***"と書かれた行以降にセクション配置情報が出力されているので、FFFF8000h番地以降に配置されているセクションを調べます。

 

例 4.

            *** Mapping List ***
            C
                                            ffff7ffc  ffff8005        a   1

 

次に、アセンブラにlistfileオプションを指定してビルドし、ソース・リスト・ファイルを生成します。エラーメッセージが示すオブジェクトファイル(例3では"fileA.obj")に対して生成されたソース・リスト・ファイルで、エラーメッセージが示すセクション(例3では"P")を探します。

最適化リンケージエディタが出力するエラーメッセージ中のオフセットは最適化実施後のオフセットになります。

このため、ソース・リスト・ファイルの中では、当該オフセット(例3では"0000002")以降にある命令でFFFF8000h番地以降に配置されているセクション内のシンボルを参照する命令が対象になりますので、その命令を調べてください。

例5では、FFFF8000h番地以降に配置したCセクションにある、定数 CONST1にアクセスする命令MOV.L が該当し、Cセクションに原因があることが特定できます。

 

例 5.

                            .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

 

(3)

回避策

以下に回避策を示します。

 

-

回避策1:セクションの指定を入れ替える。

最適化無しではFFFF8000h番地以降に配置されていて、最適化有りではセクション先頭位置がFFFF8000h番地以前にあるセクションについて、startオプションでセクションの順番を入れ替える。

 

変更前:

            -start=P,C,L,D/FFFF7000

変更後(C <-> L を入れ替え):

            -start=P,L,C,D/FFFF7000

 

変更後でも同様のE0562330エラーが発生する場合があります。その場合は適宜入れ替えるセクションの組み合わせを変更してください。

 

-

回避策2:FFFF8000h番地にセクションを配置する。

最適化無しではFFFF8000h番地以降に配置されていて、最適化有りではセクション先頭位置がFFFF8000h番地以前にあるセクションについて、startオプションでFFFF8000h番地にセクションを配置する。

 

変更前:

            -start=P,C,L,D/FFFF7000

変更後:

            -start=P/FFFF7000,C,L,D/FFFF8000

 

-

回避策3:最適化リンケージエディタの最適化を抑止する。

-nooptimizeにより最適化全てを抑止するか、エラーの発生有無と最適化効果(サイズ)を見ながら-optimizeオプションのサブオプションを選択する。