2010년 2월 14일 일요일

__use_no_semihosting_swiエラー対策



セミホスティングとはアプリケーションによるサービス要求を、デバッガを通してホストコンピュータで動作する機能です。サービス要求方法としては標準ライブラリ関数を呼び出すことによる間接的な方法もありますが、SWI命令語を直接呼び出す方法もあります。

例えば、ある関数で時間を得るためにtime関数を呼び出したとします。time関数は以下のようになっています。

time
    (省略)
    0x00008028: ef123456 V4.. SVC #0x123456 ; formerly SWI
    (省略)

標準ライブラリの大半は上記のようにSVCを呼び出してホストにサービス要求を依頼します。これは通常デバッグ環境で必要であり、出荷するバージョンだと困ります。スタンドーアロンで動作できるように、すなわちそれ自体の持っている機能だけで動作しなければなりません。

解決方法としてセミホスティング機能を使っている箇所を見つけ、直接実装する方法があります。
以下のように明示的にセミホスティングを使わないように指定できます。

C言語の場合
#pragma import(__use_no_semihosting_swi)

アセンブリの場合
IMPORT __use_no_semihosting_swi

再度ビルディングすると以下のようなエラーが発生します。

Error: L6915E: Library reports error: __use_no_semihosting_swi was requested, but time was referenced

エラーは“セミホスティングを使用しないと宣言したのにどこかでtimeを参照している”という意味です。
さて、どこで参照しているでしょうか?希望が大きいプロジェクトだとソースコードが多くて見つけるのも大変です。またサードーパーティー会社から提供して頂いたライブラリが参照しているかも知れません。

以下のようにリンカーオプションを追加しますと参照している箇所を教えてくれます。

armlink (オプション省略) --list info.map --verbose

そして生成されたinfo.mapファイルから「__I_use_semihosting」を検索します。

Loading member sys_time.o from c_4.l.
    definition: time
    reference : __I_use_semihosting

すなわち、time関数でセミホスティングの機能を使っていました。
セミホスティング機能を使わないようにtime関数を直接実装して解決できます。

댓글 없음:

댓글 쓰기