ppcsimはPowerPCの命令コードをソフトウェア的に解釈して動作をシミュレートする
ソフトウェアシミュレータです。Power-Xプロジェクトの先行実験検証用(本当は単なる
お勉強用)に作成しました。本物PPCが使えれば良いのですが、Power-Xプロジェクト
自体が現実のものになるのかどうか不明であったので、労力はかかるけど設備投資が不要な
ソフトシミュレータで、GNUツールのレベル検証であるかとか、性能見積もりであるだとか
を行ってみようとTANEが勝手に行った実験の産物の一つです。
Cygwin版はソースのみの配布となっていますので、コンパイルする必要があります。
アーカイブを展開して、ディレクトリを移動し、 make を実行すれば ppcsim.exeが
できあがります。
コマンドシェル型のユーザインターフェースとなっています。
> ppcsim
> ppcsim -f foo.ppc
> ppcsim.exe --help
PPC Simulator for Cygwin Ver 0.96 1999-2004 TANE
Usage: ppcsim [-Options] [cmd arg1 arg2 ....]
Options
-M num or --text-memsize=num :
Change default memory size for exec command & fork emulate
-H num or --heaptop-adrs=num :
Change default heap top for sbrk emulate
-P num or --heap-memsize=num :
Change default heap size for sbrk emulate
-E num or --exec-start-adrs=num :
Change default execute start address for exec command & fork emulate
-S num or --stack-top-offset=num :
Change default stack offset
-L or --linux-sc-emu :
Change to Linux Syscall Emulation mode
-o log or --outlog=log :
Simulation log message output to file(default=stderr)
-f ... or --file :
Exec script file mode
-h or --help :
Print this help
if cmd or -f option is not specified, it start with interactive shell mode.
サンプルを実行してみます。
サンプルアーカイブ(test_08x.tar.gz)を展開し、test_08xディレクトリ
の下に移動します。そしてppcsimを起動します。グラフィックウインドが開くと
共に、起動したターミナルでは以下のようなプロンプト表示状態となります。
test_08x> ppcsim.exe PPC>
PPC> exec hello hello ppcsim world PPC>
PPC> exit test_08x>
test_08x> ppcsim.exe hello hello ppcsim world
バグの入ったプログラムを意図して作るのは難しい(^^;ので、hello実行ファイルの
実行をトレースしてみます。
hello実行ファイルのスタートアドレスを調べます。テストで使用するhello実行ファイル
は以下の様なバイナリ配置になっています。
PPC> eload -i hello [No] Name Adrs Type Size Offset [ 0] 00000000 00000000 00000000 00000000 [ 1] .text 00010000 00000001 000030c8 00010000 [ 2] .rodata 000130c8 00000001 0000001c 000130c8 [ 3] .sdata2 000130e4 00000001 00000000 000130e4 [ 4] .data 000230f0 00000001 000007a8 000130f0 [ 5] .sdata 00023898 00000001 0000000c 00013898 [ 6] .sbss 000238a4 00000008 00000010 000138a4 [ 7] .bss 000238b4 00000008 00000028 000138a4 [ 8] .comment 00000000 00000001 00000500 000138a4 [ 9] .shstrtab 00000000 00000003 00000052 00013da4 [10] .symtab 00000000 00000002 00000a20 00013fd8 [11] .strtab 00000000 00000003 0000055e 000149f8
PPC> bp 0x10000 + start_adrs Setting bp=0x00010000 , BPID=1 , label=start_adrs , PID=1
PPC> bp --- Break Point(s) for Process ID = 1 -- No.00 : 0x00010000 start_adrs PPC>
PPC> exec hello Exec stop by break point. 1 : 00010000 : 54210036 rlwinm %r1, %r1, 0, 0, 27 PPC>
PPC> dump reg PC : 00010000 MSR : 00000000 SPRG0 : 00000000 DEC : 00000000 CR : 00000000 SRR0 : 00000000 SPRG1 : 00000000 TBU : 00000000 XER : 00000000 SRR1 : 00000000 SPRG2 : 00000000 TBL : 00000000 LR : 00000000 HID0 : 00000000 SPRG3 : 00000000 FPSCR : 00000000 CTR : 00000000 HID1 : 00000000 SDR1 : 00000000 GPR : 00-07 : 00000000 007fef00 00000000 00000001 007ff000 00000000 00000000 00000000 08-15 : 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 16-23 : 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 24-31 : 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
PPC> s PPC>
PPC> trace pc PPC> s 5 1 : 00010004 : 38000000 addi %r0, %r0, 0 1 : 00010008 : 9421fff0 stwu %r1, -16(%r1) 1 : 0001000c : 7c0803a6 mtspr %r0, %spr8 1 : 00010010 : 90010000 stw %r0, 0(%r1) 1 : 00010014 : 48000039 bl 56
PPC> s 1 : 0001004c : 9421ffe0 stwu %r1, -32(%r1) 1 : 00010050 : 7c0802a6 mfspr %r0, %spr8 1 : 00010054 : 7d2b4b78 or %r11, %r9, %r9 1 : 00010058 : 90010024 stw %r0, 36(%r1) 1 : 0001005c : bf810010 stmw %r28, 16(%r1)
PPC> ps ID size name 0 65536 init 1 8388608 hello
PPC> trace off PPC> c hello ppcsim world
PPC> sum subfic = 3 0.224215 % cmpli = 12 0.896861 % cmpi = 80 5.979073 % addic. = 5 0.373692 % : <中略> or = 113 8.445441 % mtspr = 37 2.765321 % srawi = 3 0.224215 % Total_count = 1338
PPC> help List of builtin commands memal : Allocate memory , load : Load file to memory save : Save file from memory , set : Set Register/Memory value dump : Dump Register/Memory , d : Same "dump" command go : Start simulation , g : Same "go" command step : Step execution , s : Same "step" command td : Print trace history , bp : Set break point pp : Set pass point , truss : Set truss mode exec : Load ELF-binary & exec , c : Continue execution kill : Kill current process , ps : Print process list trace : Set trace mode , ppmsg : Set pass point message eload : Load ELF-binary , sim : Set exception simlate status mount : Mount DISK device , umount : Unmount DISK device dload : Load from DISK device , dsave : Save to DISK device sum : Print execution summary , dis : Disassemble run : Run ppcsim-script , prob : Probe memory dbp : Delete break point , dpp : Delete pass point help : Listing builtin commands ,
PPC> exec --help
Loading ELF file and execute
Usage: exec [Options] file [arg1 arg2 ...]
Options
-b or --break : 実行ファイルロード後、プロセスを停止します
-h or --help : Print this help.
ELF形式の実行ファイルをロードし実行します。
PPC> dis 0x10000
1 : 00010000 : 54210036 rlwinm %r1, %r1, 0, 0, 27
1 : 00010004 : 38000000 addi %r0, %r0, 0
1 : 00010008 : 9421fff0 stwu %r1, -16(%r1)
1 : 0001000c : 7c0803a6 mtspr %r0, %spr8
1 : 00010010 : 90010000 stw %r0, 0(%r1)
1 : 00010014 : 48000039 bl 56
1 : 00010018 : 60000000 ori %r0, %r0, 0
1 : 0001001c : 60000000 ori %r0, %r0, 0
: <略>
powerpc-linux-objdump --source hello > hello.dis
システムコール実行(sc命令)時の振る舞いや、ppcsimで実行前に行う内部処理には
以下のようなものがあります。
0x00000000┌───────────────┐
│ユーザテキスト/データ領域 │
-0x????????├───────────────┤
│スタック領域 │
-0x00001000├───────────────┤
│argvポインタリスト( 256byte) │
-0x00000f00├───────────────┤
│argv文字列群 (3840byte) │
0x00800000└───────────────┘
完全にPowerPCの動作をシミュレートできている訳ではありません。
実行する
ための最低限の事しか書いていないので、イマイチよく判らない所もあるかと思います。
判りにくいと思った点や、間違っている点などありましたら、ご指摘いただけると
幸いです。
全然関係無い話ですが、PPCSIMは「シミュレータ」という位置付けに
しています。シミュレータとエミュレータの呼び方の違いについて、正確な定義が
あるのか判りませんが、この場では以下のような定義で区別しています。
2000/05/04 : ppcsim-0.04+ppclibc2(based newlib)用に書き換えた。 2001/04/02 : ppcsim-0.50ベースに書き換えた。 2001/04/02 : 書き抜けていた部分やらをちょっこり修正。 2002/05/13 : ppcsim-0.84ベースに書き換えた。 2002/05/14 : wait()システムコールの説明を修正 2004/09/18 : ppcsim-0.96ベースに書き換えた。 2004/10/04 : 誤記の修正やら文章の追加などを行なった。