[[katsu]] > [[katsu/refmon]] > [[katsu/refmon/arm_port]] [[katsuhiro]] -> [[katsuhiro/refmon]] -> katsuhiro/refmon/arm_port *ARM への移植作業 [#y86a7bd7] **アーキテクチャ固有のレジスタ [#a89a2b0e] CPSR があるのとないのとで struct pt_regs のレジスタ数が違う。 Armadillo-9 に使われている ARM9 は CPSR を持っているので armv の方である。 -CPSR レジスタがある CPU -> include/arch-arm/proc-armv/ptrace.h がインクルードされる -ない CPU -> include/arch-arm/proc-armo/ptrace.h がインクルードされる もっとも CPSR が何のレジスタであってもかまわないのだが、カーネルのヘッダがこういう定義をしているため非常にやりづらい。どういうことかというと CPSR の有無によって struct pt_regs 内での ARM_ORIG_r0 の位置が変わってしまうのである。 //include/arch-arm/proc-armv/ptrace.h struct pt_regs { long uregs[18]; }; #define ARM_cpsr uregs[16] #define ARM_pc uregs[15] (省略) #define ARM_r0 uregs[0] #define ARM_ORIG_r0 uregs[17] //include/arch-arm/proc-armo/ptrace.h struct pt_regs { long uregs[17]; }; #define ARM_pc uregs[15] (省略) #define ARM_r0 uregs[0] #define ARM_ORIG_r0 uregs[16] **システムコール周りの処理について [#db69979a] ARM は i386 と全然違うのでかなり困っている。ここに違いを適宜メモしていく予定である。 ***システムコールの引数について [#q1fc66ef] これで正しそう。引き続き観察する。 Intelx86 と違って、r0 が呼び出し時は第一引数なのに、返ってきた時は返り値になっているというのが後で困りそうな気がします。呼び出し時に引数を変更して、返ってきたときに元の値を復元しようとしておかしくなるんじゃないかという疑惑がわいております。 | レジスタ | 意味 | | orig_r0 | 第 1引数(元の r0) | | r0 | 第 1引数 帰ってくるときは、システムコールの返り値 | | r1 | 第 2引数 | | r2 | 第 3引数 | | r3 | 第 4引数 | | r4 | 第 5引数 | | r5 | 第 6引数 | -i386 ではシステムコールの開始地点か出口の判定に困ったが、ARM では簡潔な方法で判別できる。 --ip レジスタが 0 ならシステムコールの開始地点 --1 なら出口である ***システムコール番号の取得 [#tbdade40] i386 とは違って、システムコール番号の取得が結構面倒である。 -Thumb ではない場合(ARM モード) --pc - 4 の位置から PTRACE_PEEKTEXT で 32ビット取ると、SWI #9000xx のような命令が取れる。この下位 20ビットをマスクするとシステムコール番号が取得できる。 --SWI のオペランドは本来 24ビットだが、Linux では先頭 4ビットに 9 が入っているため、20ビットでマスクする。 -Thumb の場合 --r7 にシステムコールの番号が入っているらしい。 ---これはまだ未確認です。 --cpsr の 5ビット目が 1 なら、Thumb モードである。 ***システムコールの改変について [#f701d0e1] i386 では orig_eax を変更すると勝手に反映してくれたが、ARM のシステムコール呼び出しでは、変更する方法がなさそうである。どうしたものかな。