次: , 前: Stub Contents, 上: Remote Serial


13.4.1.2 スタブに対する必須作業

GDBとともに配布されるデバッグ用スタブは、 特定のチップのアーキテクチャ用にセットアップされたものですが、 デバッグのターゲット・マシンに関してそれ以外の情報は持っていません。

まず最初に、 どのようにしてシリアル・ポートと通信するかをスタブに教えてやる必要があります。

int getDebugChar()
シリアル・ポートから単一文字を読み込むサブルーチンとしてこれを書きます。 これは、 ターゲット・システム上の getcharと同一かもしれません。 これら2つを区別したい場合を考慮して、 異なる名前が使われています。
void putDebugChar(int)
シリアル・ポートに単一文字を書き込むサブルーチンとしてこれを書きます。 これは、 ターゲット・システム上の putcharと同一かもしれません。 これら2つを区別したい場合を考慮して、 異なる名前が使われています。

実行中のユーザ・プログラムをGDBが停止できるようにしたいのであれば、 割り込み駆動型のシリアル・ドライバを使用して、 ^C (control-C文字、 すなわち`\003') を受信したときに停止するよう設定する必要があります。 GDBはこの文字を使って、 リモート・システムに対して停止するよう通知します。

デバッグ・ターゲットが適切なステータス情報をGDBに対して返せるようにするためには、 おそらく標準のスタブを変更する必要があるでしょう。 最も美しくなく、 しかし最も手っ取り早くこれを実現する方法は、 ブレイクポイント命令を実行することです (この方法が「美しくない」のは、 GDBがSIGINTではなくSIGTRAPを報告してくる点にあります)。

ユーザが提供する必要のあるルーチンには、 ほかに以下のようなものがあります。

void exceptionHandler (int exception_number, void *exception_address)
例外処理テーブルにexception_addressを組み込むよう、 この関数を書きます。 ユーザがこれを提供しなければならないのは、 スタブにはターゲット・システム上の例外処理テーブルがどのようなものになるかを知る手段がないからです (例えば、 プロセッサのテーブルはrom上にあり、 その中のエントリがram上のテーブルを指す、 という形になっているかもしれません)。 exception_number は例外番号で、 これは変更される必要があります。 例外番号の意味は、 アーキテクチャに依存します (例えば、 0による除算、 境界を無視したメモリ・アクセス等は、 異なる番号によって表わされるかもしれません)。 この例外が発生したとき、 制御は直接exception_addressに渡されなければならず、 また、 プロセッサの状態 (スタック、レジスタなど) はプロセッサ例外が発生したときの状態と同じでなければなりません。 したがって、 exception_addressに到達するのにジャンプ命令を使用したいのであれば、 サブルーチン・ジャンプではなく、 ただのジャンプ命令を使わなければなりません。

386では、 ハンドラが実行されているときに割り込みがマスクされるよう、 exception_addressは割り込みゲートとして組み込まれる必要があります。 そのゲートは特権レベル0 (最も高いレベル) でなければなりません。 sparc用のスタブや68k用のスタブは、 exceptionHandlerの助けを借りなくても自分で割り込みをマスクすることができます。

void flush_i_cache()
(sparc、 sparcliteのみ) ターゲット・マシンに命令キャッシュがある場合、 それをフラッシュするようこのサブルーチンを書きます。 命令キャッシュがない場合には、 このサブルーチンは何もしないものになるかもしれません。

命令キャッシュを持つターゲット・マシン上のGDBは、 ユーザ・プログラムが安定した状態にあることが この関数によって保証されることを必要とします。

また、次のライブラリ・ルーチンが使用可能であることを確かめなければなりません。

void *memset(void *, int, int)
あるメモリ領域に既知の値を設定する標準ライブラリ関数memsetです。 フリーのlibc.aを持っていれば、 そこにmemsetがあります。 フリーのlibc.aがなければ、 memsetをハードウェアの供給元から入手するか、 自分で作成する必要があります。

gnu Cコンパイラを使っていないのであれば、 他の標準ライブラリ・サブルーチンも必要になるかもしれません。 これは、 スタブによっても異なりますが、 一般的にスタブは、 gccがインライン・コードとして生成する共通ライブラリ・サブルーチンを使用する可能性があります。