逆アセンブル。
大分進んだ。 PRC中で今のところ必要なリソースは全部解析出来た。 クラスについても取得出来たし、各セレクタのコンパイル済みイメージも取得可能。
指定したクラスの指定したセレクタを逆アセンブルも可能だ。 まあ、まだ逆アセンブル自体は出来たわけじゃないけど、それぞれの命令のサイズを取得してステップ数ぐらいは出せた。 PST上のDisassemblyと比較しても一致。
ドキュメントに記載されてない部分が結構はまったな。 メモメモ。
ヘッダー6バイトに可変サイズのデータが後続する。
struct { u_int16 length; u_int16 class; u_int16 objref; }
length&0x3FFFがオブジェクトのサイズになる。単位はword(2バイト)。 サイズにはヘッダーも含むため、データ部のサイズは((length&0x3FFF)-3)wordになる。 ポインター所持オブジェクトの場合0x4000が論理和されている。 またGCにマークされると0x8000が論理和される。
classはクラスインデックス。0から3の値にはならない。
objrefはオブジェクトテーブル内の自分のインデックス。
ObjDリソースにstaticオブジェクトが入っている。
テーブルの0,1,2は必ずそれぞれnil,true,falseの各オブジェクト。
それ以降はクラスインデックスに対応したクラスオブジェクト。
それ以降は任意。
ドキュメントに無い命令。
0x62、0x67: systrap xxxx yy ?? ?? ?? ?? ??
xxxxのsystrapを引数の数yy個として呼び出す。後に引数の型がyy個続き、最後に戻り値の型が1つ続く。
0x62は戻り値を使用する場合に使う。戻り値を使用しない場合は0x67を使う。
0x63、0x64: push|store global xxxx
グローバルオブジェクトxxxxをpush(0x63)したりstore(0x64)したり。
0x65: send xx yyyy
スタックトップのオブジェクトにセレクタyyyyを引数の数xx個として呼び出す。
0x66: send xx yyyy
セレクタyyyyを引数の数xx個として呼び出す。スタック中でレシーバは引数の下のオブジェクト。
レシーバのクラスを取ってそのクラスの中でセレクタを探す。
クラスメソッドを呼びたいときには当然クラスオブジェクトのクラスをとってその中から対象のセレクタを探す。
必要ならsuperclassも探す。