昼頃起床。アパートの更新作業後、休出。
ppcsim-0.93をリリースしました。御参考まで。
0.93をリリースしたばっかだけどgccのPPCネイティブコンパイルでコンパイラ
ドライバがイマイチうまく動かなかったのを調査(^^;
メモリアクセス越えになっていたのですが、メモリクリアをする必要が
ありそうだったので追加。その時発見されたバグとしてexecve()を
実行した時にmmap()されていた領域を開放する処理が抜けていたので
修正。メモリクリアを行う事でメモリアクセス越えは発生しなく
なりました(メモリクリアされている事を期待しない様なコードに
直して欲しいというのは置いといて)。続いて、何故かファイルを
指定しているのに標準入力のread()待ちとなって停止している模様。
execve()された後の引数領域をよーく見てみると、
引数が途中で切れてます(汗; トークン分離関数で使用するバッファ
サイズが256byteしかなかったため、途中で切れてしまった模様。
コンパイラドライバがコンパイラ本体に渡す引数って凄く長いのを
忘れてました(昔Human68k用にbuildしたPPC-gccはそれのせいで
HUPAR対応shellを使う必要がありました)。そこを直すと
「gcc-cross -B./ -S foo.c」はどうにかクリア。最後、子プロセスが
終了した後、親プロセスに戻ってきた所で、wait4()を無限に
実行している模様。戻り値を0固定から親プロセスIDを返す様に
変更したら取りあえず無限実行は収まったものの、親プロセスが
exit(1)で終了してて死亡。うーむ、これだとmakeで使えないなぁ....
後、execve()の指定は第一引数がファイル名で、第二引数がコマンド引数
という解釈でシステムコールエミュレーションを行っていたの
ですが、第二引数にはargv[0]すなわちコマンド自身も含んで渡す
必要があるらしい。あくまで第一引数は実行ファイル名で、
子プロセスに渡すargv[0]とは無関係というもののようです。
という訳で、この修正を入れると以前サンプルで作成した「ニセsh」
にも修正を入れる必要があったりして(^^;
その後、wait4()の第二引数であるstatus変数をクリアして返す様にすると
exit(0)で終了するようになった模様。で、-cオプションに挑戦
した所、なんとかOKそう。
gcc> ~/develop/ppcsim/src/ppcsim.exe -L gcc-cross -B./ -c -O3 -v test.c Reading specs from ./specs Configured with: ../configure --target=powerpc-linux --prefix=/usr/local/ppc --e nable-languages=c : (reconfigured) ../configure --target=powerpc-linux --prefix= /usr/local/ppc --enable-languages=c --disable-threads --disable-shared Thread model: single gcc version 3.2 ./cc1 -lang-c -v -iprefix ../lib/gcc-lib/powerpc-linux/3.2/ -isystem ./include -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=0 -D__GXX_ABI_VERSION=102 -DPPC -D__ELF__ -Dpowerpc -D__PPC__ -D__ELF__ -D__powerpc__ -D__PPC -D__powerpc -Acpu=powerpc -Amachine=powerpc -D__OPTIMIZE__ -D__STDC_HOSTED__=1 -D_CALL_SYSV -D_BIG_ENDIAN -D__BIG_ENDIAN__ -Amachine=bigendian -D_ARCH_PPC -D__unix__ -D__gn u_linux__ -D__linux__ -Dunix -D__unix -Dlinux -D__linux -Asystem=unix -Asystem=p osix test.c -quiet -dumpbase test.c -O3 -version -o /tmp/ccbZnu2d.s GNU CPP version 3.2 (cpplib) (PowerPC GNU/Linux) GNU C version 3.2 (powerpc-linux) compiled by GNU C version 3.2. ignoring nonexistent directory "../lib/gcc-lib/powerpc-linux/3.2/include" ignoring nonexistent directory "../lib/gcc-lib/powerpc-linux/3.2/../../../../pow erpc-linux/sys-include" ignoring nonexistent directory "../lib/gcc-lib/powerpc-linux/3.2/../../../../pow erpc-linux/include" ignoring nonexistent directory "/usr/local/ppc/powerpc-linux/sys-include" #include "..." search starts here: #include <...> search starts here: include /usr/local/ppc/include /usr/local/ppc/lib/gcc-lib/powerpc-linux/3.2/include /usr/local/ppc/powerpc-linux/include End of search list. ./as -mppc -V -Qy -o test.o /tmp/ccbZnu2d.s GNU assembler version 2.13 (powerpc-linux) using BFD version 2.13
本日休業。
ELFフォーマットの仕様を.....と思ったのですが、よくよく思い返して
みますに、stripしてしまうとシンボルを読むことができないので、
erronoの格納領域を知ることは基本的にできなくなってしまいます。
ですから、何かしらの方法でシステムコール実行の成功と失敗が
区別できるハズという事で見直してみた所、ちゃんと成功時とエラー時
とで動作が別れていました。成功時はGPR3に戻り値を返すので良しと
して、失敗時はどうなっていたかというと、errno値はGPR3に返す
のですが、CR0のbit3に1を立てる事でエラーを判別するという
仕組みになっていて、その時はラッパーがGPR3をerrnoに格納した後、
-1を返して見かけ上システムコールが失敗した様に見えるという
事の様です。CR0のbit3に1を立てる事で、ラッパーが-1を返す
様になっている為、そのように実装してあれば、未実装システムコール
でも失敗時は-1を返すという事が可能となっている様です。
で、cpはOK、gzipで存在しないファイルを指定した時もOKとなり
ました。
Cygwinのアップデートを行った所、今日はOK。rxvtがアップデートされて
いたのですが、それのお陰でinfoか何かのファイルが壊れていたのが
直ったか何かしたからでしょうか。
日付け越え前に帰着。
lsがなんとなくOKっぽくなったので、cpやmvが使えるかと思って
試してみた所、微妙にNG。例えば cp src.c dst.c という風に
した所、dst.cが存在しないとエラーでずっこける模様。
touch dst.c などで空ファイルを作成してから実行すると
コピーOKでした。truss onでシステムコール実行をトレース
した所、lstat64()でdst.cをテストした所で存在してなくて
エラーしたしたらそのままずっこけ終了という感じになっている
様です。やってることに対する反応は正しいような気がします。
で、cpのソースを眺めてみた所、
static int do_copy (int n_files, char **file, const char *target_directory, const struct cp_options *x) { <中略> if (lstat (dest, &sb)) { if (errno != ENOENT) { error (0, errno, _("accessing %s"), quote (dest)); return 1; } new_dst = 1; } <略>
日付け越え前に帰着。
ioctl()について調査。
ioctl(fd,req,ptr)というのが基本型になっている様で、
reqの中に様々な情報を詰め込んでいるという仕掛けのようです。
asm/ioctl.hにマクロが色々入っていますが、reqの
ビットフィールドは以下の様な
+---+-------------+--------+--------+ |000|0000000111111|11112222|22222233| |012|3456789012345|67890123|45678901| +---+-------------+--------+--------+ |dir|size | type | nr | +---+-------------+--------+--------+
_IO(type,nr) _IOR(type,nr,size) _IOW(type,nr,size) _IOWR(type,nr,size)
#define TIOCGWINSZ _IOR('t', 104, struct winsize)
ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) ;
ioctl(00000001,402c7413,007fe698,00000001)
src> ~/develop/ppcsim/src/ppcsim.exe -L ls *.c ansi2knr.c chown.c dd.c install.c ls-vdir.c mknod.c rmdir.c chgrp.c copy.c df.c ln.c ls.c mv.c shred.c chmod.c cp-hash.c dircolors.c ls-dir.c mkdir.c remove.c sync.c chown-core.c cp.c du.c ls-ls.c mkfifo.c rm.c touch.c
日付け越え前に帰着。
CygEmacsのターミナル(rxvt)での日本語表示について。
なんのことは無い、LANGをjaにして、rxvt(日本語化したもの)
のオプションで -km eucjを指定すれば良いらしい。おぉ、
確かに日本語表示はバッチリです。が、入力はできず。ヘコリ。
でもLANG jaは他のアプリも同時に日本語化されるのが微妙(^^;
diff utilsとかは日本語でメッセージを出されるよりもASCII文字で
出てくれた方がサーチしやすい様に感じます
(diff ./a/ ./b/ | grep ^Only とか)。vimも日本語表示できるように
なりましたが、やっぱり入力はできず。もうちょいですけど
ねぇ....多分......
そういえば、ppcネイティブのlsですが、オプション無しで実行
すると、一行一ファイルで表示されています。どうやら、isatty()
でttyかファイルかをチェックしている様なのですが、glibcでは
isatty()はioctl()を使って実装されているようです。
現在のppcsimではioctl()はNOP扱いに実装している為、それが
良い方向に働いていないといった感じ。で、ioctl()の実装なの
ですが、ioctl(fd,request,)までは良いのですが、その後ろの
引数が可変長引数となっていて、どう動かすのが良いのか悩ましい
感じ。
体調悪くて一回休み。
寒くてエアコン付けていても昼間はちっとも動いてません。設定
温度通りになっているので省エネ状態になっているようですが、
体感的にもっと温度が低いと思うのは単に風邪のせいだからかしら?
ニセshをコンパイル。子プロセス起動はOKでしたが、wait4()システム
コールがUnknownSyscallだったので追加しました。newlibベースの
ライブラリではwait()システムコールはスタブで実装していたので、
ライブラリ内で閉じているのを忘れてました(^^;
トリビアの泉。宝塚の第一回公演は桃太郎(ベースの「どんぶらこ」という
オペラ)だったとか、色々ムダな知識が付きましたが、それよりも
できるかなのゴン太くんが1974/4/1生まれで、トリビア司会(左側)の
高橋氏と誕生日が同じで、
高橋氏が思ったよりも若いという事の方に
18へぇ って感じでした。
昼頃起床。寒さに輪がかかってて死亡。
先日テストしたlsはfileutils-4.0のものだったので、色々とオプションが無かったり
したので、fileutils-4.1をコンパイルしてみることにしました。
configureで--hostを指定しなくてはならないとか、--hostを指定すると一部ネイティブ
で実行するべきコマンドが実行できないと怒られるだとか、fileutilsに含まれる
関数とglibcの関数や変数が衝突していてコンパイルエラーやリンクエラーになる
だとか「うぉーいっ!!」って感じの色々な罠を乗り越えてどうにかlsのコンパイルに
成功。fileutils-4.0との大した差はありません。
src> ~/develop/ppcsim/src/ppcsim.exe -L ls -ltr --full-time l*.c -rw-r--r-- 1 500 544 46 Mon Feb 15 15:35:30 1999 ls-vdir.c -rw-r--r-- 1 500 544 37 Mon Feb 15 15:35:30 1999 ls-ls.c -rw-r--r-- 1 500 544 44 Mon Feb 15 15:35:30 1999 ls-dir.c -rw-r--r-- 1 500 544 16540 Sat Feb 03 17:57:02 2001 ln.c -rw-r--r-- 1 500 544 87632 Sun Apr 29 09:42:48 2001 ls.c src> ls -ltr --full-time l*.c -rw-r--r-- 1 tane 544 46 Tue Feb 16 00:35:30 1999 ls-vdir.c -rw-r--r-- 1 tane 544 37 Tue Feb 16 00:35:30 1999 ls-ls.c -rw-r--r-- 1 tane 544 44 Tue Feb 16 00:35:30 1999 ls-dir.c -rw-r--r-- 1 tane 544 16540 Sun Feb 04 02:57:02 2001 ln.c -rw-r--r-- 1 tane 544 87632 Sun Apr 29 18:42:48 2001 ls.c
local void usage() { printf ("usage: %s [-%scdfhlLnN%stvV19] [-S suffix] [file ...]\n", progname, #if O_BINARY "a", #else "", #endif #ifdef NO_DIR "" #else "r" #endif ); }
static void usage() { printf "", "r" ); }
local void usage() { printf( "usage: %s [-acdfhlLnNrtvV19] [-S suffix] [file ...]\n",progname); }
gzip-1.3.3> ~/develop/ppcsim/src/ppcsim.exe -L gzip -l *.gz compressed uncompressed ratio uncompressed_name 8589934618 2719971 -1323848094425.9% xxx 17179869210 16730 -6904801580517128.0% yyy 17179869148 2736701 -43526186772795.2% (totals) gzip-1.3.3> gzip -l *.gz compressed uncompress ratio uncompressed_name 989407 2719971 63.6% xxx 6633 16730 60.5% yyy 996040 2736701 63.6% (totals)
昼頃起床。寒くて死亡。でも休出。
lstat()の仕込み。仕込み完了後、試してみるも改善せず。というか
余計ひどくなった気分(汗;
以下のようなコードでstat構造体先頭から見たメンバの相対位置を
調べて、ppcsimに仕込みました。
#include <stdlib.h> #include <stdio.h> #include <sys/stat.h> int main() { struct stat st ; printf("%d\n",sizeof(struct stat)) ; printf("st.st_dev %08x %3d %d\n",(int)(&st.st_dev) ,(int)(&st.st_dev)-(int)(&st) ,sizeof(__dev_t)) ; printf("st.st_ino %08x %3d %d\n",(int)(&st.st_ino) ,(int)(&st.st_ino)-(int)(&st) ,sizeof(__ino_t)) ; printf("st.st_mode %08x %3d %d\n",(int)(&st.st_mode) ,(int)(&st.st_mode)-(int)(&st) ,sizeof(__mode_t)) ; printf("st.st_nlink %08x %3d %d\n",(int)(&st.st_nlink) ,(int)(&st.st_nlink)-(int)(&st) ,sizeof(__nlink_t)) ; printf("st.st_uid %08x %3d %d\n",(int)(&st.st_uid) ,(int)(&st.st_uid)-(int)(&st) ,sizeof(__uid_t)) ; printf("st.st_gid %08x %3d %d\n",(int)(&st.st_gid) ,(int)(&st.st_gid)-(int)(&st) ,sizeof(__gid_t)) ; printf("st.st_rdev %08x %3d %d\n",(int)(&st.st_rdev) ,(int)(&st.st_rdev)-(int)(&st) ,sizeof(__dev_t)) ; printf("st.st_size %08x %3d %d\n",(int)(&st.st_size) ,(int)(&st.st_size)-(int)(&st) ,sizeof(__off_t)) ; printf("st.st_blksize %08x %3d %d\n",(int)(&st.st_blksize),(int)(&st.st_blksize)-(int)(&st),sizeof(__blksize_t)) ; printf("st.st_blocks %08x %3d %d\n",(int)(&st.st_blocks) ,(int)(&st.st_blocks)-(int)(&st) ,sizeof(__blkcnt_t)) ; printf("st.st_atime %08x %3d %d\n",(int)(&st.st_atime) ,(int)(&st.st_atime)-(int)(&st) ,sizeof(__time_t)) ; printf("st.st_mtime %08x %3d %d\n",(int)(&st.st_mtime) ,(int)(&st.st_mtime)-(int)(&st) ,sizeof(__time_t)) ; printf("st.st_ctime %08x %3d %d\n",(int)(&st.st_ctime) ,(int)(&st.st_ctime)-(int)(&st) ,sizeof(__time_t)) ; }
test2> ~/develop/ppcsim/src/ppcsim.exe -L -x a.out 88 st.st_dev 007fee48 0 8 st.st_ino 007fee54 12 4 st.st_mode 007fee58 16 4 st.st_nlink 007fee5c 20 4 st.st_uid 007fee60 24 4 st.st_gid 007fee64 28 4 st.st_rdev 007fee68 32 8 st.st_size 007fee74 44 4 st.st_blksize 007fee78 48 4 st.st_blocks 007fee7c 52 4 st.st_atime 007fee80 56 4 st.st_mtime 007fee88 64 4 st.st_ctime 007fee90 72 4
src> ~/develop/ppcsim/src/ppcsim.exe -L -x ls -ltr ls.c ?---r-s-wx 0 1 500 268573304 Jan 1 1970 ls.c
src> ~/develop/ppcsim/src/ppcsim.exe -L -x ls -ltr ls.c -rw-r--r-- 0 500 544 75363 Sep 19 1998 ls.c src> ls -l ls.c -rw-r--r-- 1 tane 544 75363 Sep 20 1998 ls.c
__extension__ typedef unsigned long long int __u_quad_t; <中略> typedef __u_quad_t __dev_t;
日付け越え前に帰着。
lstat()のメンバについて調査。眠くて死亡。
そういや、何気に表のカウンタが10000を越えてました。いつも見て
いただいてどうもありがとうございますm(_'_)m
日付け越え前に帰着。
segfault調査。gdbはやっぱり使えずじまいでしたが、しょーもない
間違いだったのを修正。でもシミュレータメモリのアクセス越え。
どうやら、getdents64()のバッファサイズはあくまで上限サイズという
事で、実際にはstruct direntのサイズ単位で扱い、バッファ内に
収まるサイズに丸める必要があるみたい。最後は読み出しサイズ
0を返す事で終了という事のようです。struct direntよりもサイズ
が小さいとうまく動かないような気がしますが、そんときは
segfaultで死ぬから良いという事なのでしょうか。で、実行
したら以下の通り。
src> ~/develop/ppcsim/src/ppcsim.exe -L -x ls -l l*.c -rw-r--r-- 1 35680983 14244 268573304 Jan 1 1970 ln.c -rw-r--r-- 1 35680983 44 268462376 Jan 1 1970 ls-dir.c -rw-r--r-- 1 35680983 37 268462376 Jan 1 1970 ls-ls.c -rw-r--r-- 1 35680983 46 268462376 Jan 1 1970 ls-vdir.c -rw-r--r-- 1 35680983 75363 268462376 Jan 1 1970 ls.c
日付け越え前に帰着。
何気にRXVT on Cygwin関連ページを眺めていたら、フォントの変え方に
ついて書かれたページがあったので参考にしてみました。
rxvt -sl 3000 -fg white -bg black +vb -fn msgothic-14 -fm msgothic-14 -e /bin/bash
日付け越え前に帰着。
getdents64()の実装。あぁ....面倒臭い。何が面倒かって、
引数に指定されている読み出し量がBYTE単位という所。
どうせdirent構造体単位でしか扱わないのだから、
全エントリのdirentのリストでも返す様にすれば良いのに
なぜこんなに面倒な方法にしたのかしら?と思ったり。
システムコールは(プロセスの持ち物でないメモリ領域の)
ポインタを返す事ができないからか?それはそうかも......
readdir()がシステムコールとして存在しているのに
(opendir()は見当たりませんが....)
あえてgetdents()を使用するのはパフォーマンス的に
問題があるからなのでしょうか。
因みにgetdents64()などLargefile系システムコールは二年以上
前のLinuxカーネルヘッダ(linux-2.0.xくらい)には含まれていませんでした。
なのでnewlib on ppcsimで勝手に割り当てたsbrk()とシステムコール番号が
衝突しています(^^; GNU-Hurdのシステムコールの様に-1の方から割り当てた
方が良かったかも。
日付け越え前に帰着。
Webぐるでgetdents()で検索すると、
このようなページが見つかったり。
実行により得られるデータがそのものズバリって感じ。
でも、newlibではgetdents()を持たない為、opendir(),readdir()
などを使用してデータを生成する必要がありそうです。でも、
getdents()がopen()で得たfdを引数にするのに対してreaddir()は
opendir()で得たDIR構造体が引数なのでどうしたものか。
gcc on Cygwinがアップデートされていたので入れ替え。
キャストの不具合は直っていない模様。
昼頃起床。
getdents64()の仕様を探しにWebぐる。良いのが見つからず。
ぐるぐるしていると、
このようなページを見つけたり。なんとなく判るなぁ(^^;
ワンピースを観てたらカレーが食べたくなったり。
特に得るものなく眠くて死亡。
昼頃起床。なんか今日はムチャクチャ寒いんですけど。
fileutilsをppcネイティブコンパイルしてみたり。以前はコンパイル自体が
うまく行かずに玉砕しましたが、今回はコンパイルだけはなんとか。
でもls実行はうまくゆかず。getdents64()というディレクトリエントリを
得ると思われるシステムコールが未実装で死亡。でも、このシステムコール
の仕様がよく判らず。
暇だったので、Emacs on Cygwinなどをインストールしてみました。
取りあえず emacs -nw で起動してみ所、Meadowで使用している
.emacsに入れてあるWindows用設定でエラー。取りあえず、
;;; ;;; IME SetUp ;;; (if (string-match "windows98" (version)) (progn (mw32-ime-initialize);;; (setq default-input-method "MW32-IME")))
日付け越え。
brk()を実装したppcsimでpovray-3.5を使用してメモリの使われ具合
を観察してみました。すると、mmap()によりメモリ割り当てを行っている
のですが、メモリ不足によりmmap()での割り当てが失敗すると、
brk()を使用してメモリ割り当てを行うしかけになっているようです。
ppcsimではメモリ管理の都合でmmap()で割り当てる領域とbrk()で割り当てる
領域を別にしているので、それでもうまくいくのですが、実際の所、
mmap()がダメだとアウトっぽい気がしなくもありません。それでうまく
メモリ割り当てできるのか?って感じ。
Webぐるしていたら
afioとやらのメリットについて書かれたページを発見。なる。
前述ページを見ていてbeavが出てきたので、あぁそういや
バイナリエディタって無かったなぁと思い、beav-1.4を拾ってコンパイル。
初めてソースを見たような気がしますが、思いのほかコンパクトで
ちょっとびっくり。make一発でさっくりコンパイルできて幸せ。ステキ。
本日休業。
データアクセス越えを調査。0x00000000番地をアクセスしてそれを
ポインタとしてアクセスした先がメモリの割当たっていない所だと
いう感じになっていたようなので、メモリプローブした所、0x00000000番地
にはロードアクセスしか発生していなくて謎。
trussコマンドでシステムコール実行を眺めてみると、time()システムコール
の引数に0x00000000 が指定されていて、それにより値がセットされている
というのが直接の原因という事のようです。それにしても、それ以前にも
0x00000000番地をロードアクセスしている形跡があるので、それを
まず調査する必要がありそうです。メモリ保護が入っていればsegfaultに
できる所なのですけどね。
brk()を何気に動く様に実装して、djpegなど今までテストしたプログラム
を実行してみた所、今までmmap()を使ってメモリ割り当てを
行っていた部分がbrk()を使ってメモリ割り当てを行う様になりました。
でも、完全にbrk()にとって代わっている訳ではなく、時々mmap()も
使用されている模様。何故に?全部mmap()でやっても問題無かろうと
思うのですが......
水夏とかいうエロゲーのキャラクタを使った教育向けソフトというのが
巷で話題になっているようです。これを見てると、昔、小さな女の子が
セーラームーンのマンガ本(18才未満は購入できないエロパロ本,勿論
その子は知るよし無し)を買おうとして、店員が購入できない事の
説明に苦慮していたのを思い出しました。でもまぁ、エロゲーキャラ
でもセーラームーンくらいに知名度がありゃぁ話は別ですが、
ぶっちゃけ美少女キャラなんて、エロかどうかに関係無く見た目に
区別付かないんだから(暴言)、大勢に影響は無いように思います。
日付け越え。
bash on ppcsimのメモリエラーを調査。どうやらbrk()を実行した
その結果がまずいらしい。brk()の戻り値は0で成功だと思っていた
ので、常に0を返していたのですが、それだとNGの模様。
glibcのmisc/brk.dより元のソースsysdeps/unix/sysv/linux/powerpc/brk.Sを
辿ってみると、何やらbrk()の戻り値とbrk()の引数アドレスを比較して
引数アドレスよりも値が小さいとエラーとなるコードになっている様に
見えます。なので、戻り値を引数アドレスと同じものを返す様にすると、
先に進んだ様子。でも、データセグメントの先頭である_endの次のアドレス
なんて、シミュレーション実行するにあたってどこからも情報を渡していない
ので、実際にはアドレス0番地からメモリ割り当てを行っている様に
見えます。うーん、なんだかよく判らないや。
その後、rt_sigprocmask(),uname()がUnknownSyscallになったので、
いいかげんに追加したらデータアクセスエラーになったりして(^^;
日付け越え前に帰着。
netpbmなどをコンパイルしてみたり。最新版でJPEG2000への相互変換が
可能という感じの噂を小耳に挟んだのですが、それっぽいコマンドが見つ
からなかったり。
bashをPPCネイティブコンパイルしてみたり。コンパイルは通った
のですが、ppcsimで実行してみると、
bash-2.04> ~/develop/ppcsim/src/ppcsim.exe -L -x bash : error while loading shared libraries: cannot create capability list: Cannot allocate memory
日付け越え。
Cygwinをアップデート。cygwin1.dllとかbinutilsとかgccがアップデートされて
いました。gccがアップデートされていたので、先日のキャスト不具合
ソースをコンパイル&実行してみましたが結果は変わらず、NGっぽい。
ppcsimの方は書き方で直せるものについては直しましたが、書き方を
変えるとわかりづらくなるものについてはどうしようかと思案中。
コンパイラが直ってくれるのが一番良いのですが......
結局、当面の間オプティマイズレベルを下げて使用するという事で
ppcsim-0.92をリリースしました。しばらくの間はgccがアップデート
される度にコンパイルオプションをテストして、直ればオプティマイズレベルを戻す
という事で。直らなかったら.........どうしよう?(^^;
昼前起床。ちょこーり休出。
一応、テストでpovray-3.1、povray-3.5の両方でシーンファイルを
レンダリングした所、OKそう。今回は忘れずにサマリを取りました(^^;
exec povray -Linclude -IMegaPov/spherecyl_for3.5.pov +W320 +H240 +A -Ospherecyl_ppcsimpov3.5.png <中略> Statistics for MegaPov/spherecyl_for3.5.pov, Resolution 320 x 240 ---------------------------------------------------------------------------- Pixels: 77120 Samples: 168152 Smpls/Pxl: 2.18 Rays: 1417650 Saved: 3 Max Level: 4/4 ---------------------------------------------------------------------------- Ray->Shape Intersection Tests Succeeded Percentage ---------------------------------------------------------------------------- Box 875989 457194 52.19 Cone/Cylinder 915023 522700 57.12 Sphere 399515 263188 65.88 Bounding Box 8205875 3383525 41.23 Light Buffer 3257386 1537976 47.22 Vista Buffer 531713 365415 68.72 ---------------------------------------------------------------------------- Calls to Noise: 0 Calls to DNoise: 10 ---------------------------------------------------------------------------- Shadow Ray Tests: 722427 Succeeded: 235148 Reflected Rays: 536445 Total Internal: 26642 Refracted Rays: 496436 Transmitted Rays: 27451 Number of photons shot: 189166 Surface photons stored: 453289 Priority queue insert: 53261589 Priority queue remove: 22269685 Gather function called: 327723 ---------------------------------------------------------------------------- Smallest Alloc: 13 bytes Largest: 327688 Peak memory used: 9372221 bytes ---------------------------------------------------------------------------- Time For Parse: 0 hours 0 minutes 2.0 seconds (2 seconds) Time For Photon: 0 hours 38 minutes 29.0 seconds (2309 seconds) Time For Trace: 10 hours 23 minutes 19.0 seconds (37399 seconds) Total Time: 11 hours 1 minutes 50.0 seconds (39710 seconds) ------------ sum mulli = 264219038 0.336390 % subfic = 11868718 0.015111 % cmpli = 10624571 0.013527 % cmpi = 773462216 0.984731 % addic = 21722600 0.027656 % addic. = 22198545 0.028262 % addi = 5222175951 6.648596 % addis = 4809371839 6.123036 % bc = 5069626601 6.454378 % sc = 5786 0.000007 % b = 1312565799 1.671089 % rlwimi = 25730 0.000033 % rlwinm = 5156258531 6.564673 % ori = 134065829 0.170685 % oris = 260257777 0.331346 % xori = 899158407 1.144761 % xoris = 107158597 0.136429 % andi. = 48427572 0.061655 % andis. = 233556585 0.297352 % lwz = 7266978924 9.251930 % lwzu = 46540 0.000059 % lbz = 408710303 0.520348 % lbzu = 1629943 0.002075 % stw = 4871279951 6.201854 % stwu = 739897962 0.941999 % stb = 6192257 0.007884 % stbu = 33785 0.000043 % lhz = 9641566 0.012275 % lhzu = 393236 0.000501 % lha = 16361384 0.020830 % sth = 644480 0.000821 % stbu = 2 0.000000 % lfs = 1634026533 2.080355 % lfd = 5741398074 7.309642 % stfs = 312056946 0.397294 % stfd = 2243722645 2.856588 % bclrx = 775467148 0.987283 % crnor = 28130402 0.035814 % crxor = 3175585 0.004043 % creqv = 17 0.000000 % cror = 11168652 0.014219 % bcctrx = 9103681 0.011590 % cmp = 926467630 1.179529 % subfcx = 411516 0.000524 % addc = 20 0.000000 % mulhwu = 34063 0.000043 % mfcr = 625760262 0.796685 % lwzx = 876774812 1.116263 % slw = 428251 0.000545 % cntlzw = 7874 0.000010 % and = 25439445 0.032388 % cmpl = 16614108 0.021152 % subf = 7416794 0.009443 % andc = 11166573 0.014217 % mulhw = 189228 0.000241 % lbzx = 2329532 0.002966 % neg = 569518368 0.725080 % lbzux = 181 0.000000 % nor = 101798 0.000130 % subfe = 22135106 0.028181 % adde = 167691 0.000213 % mtcrf = 14077884 0.017923 % stwx = 406666111 0.517746 % stwux = 178 0.000000 % addze = 1332882 0.001697 % stbx = 271721 0.000346 % addme = 732701 0.000933 % mullw = 880241 0.001121 % add = 1361478117 1.733361 % lhzx = 2754186 0.003506 % xor = 1192548 0.001518 % mfspr = 638954243 0.813482 % sthx = 533283 0.000679 % orc = 32 0.000000 % or = 2948444571 3.753802 % divwu = 345 0.000000 % mtspr = 662075033 0.842919 % nand = 17 0.000000 % divw = 2001 0.000003 % lfsx = 951280146 1.211119 % srw = 134980 0.000172 % lfdx = 1232460195 1.569103 % stfsx = 2451206 0.003121 % stfdx = 408237895 0.519747 % sraw = 32281664 0.041099 % srawi = 630973460 0.803322 % extshx = 42 0.000000 % extsbx = 61738257 0.078602 % dcbz = 14129 0.000018 % fsubs = 1663288 0.002118 % fadds = 5355087 0.006818 % fmuls = 104694938 0.133292 % fmadds = 5545983 0.007061 % fcmpu = 2927810259 3.727532 % frsp = 318285068 0.405224 % fctiwz = 4963837 0.006320 % fneg = 5141669 0.006546 % mtfsb0 = 23164319 0.029492 % fmr = 3826187068 4.871297 % mtfsfi = 227439569 0.289564 % fabs = 218754722 0.278507 % mffs = 250603889 0.319056 % mtfsf = 250603889 0.319056 % fdiv = 85977396 0.109462 % fsub = 1596871400 2.033052 % fadd = 1364413023 1.737098 % fmul = 2290823908 2.916555 % fmsub = 3004493 0.003825 % fmadd = 2560540014 3.259943 % fnmsub = 1592076983 2.026948 % fnmadd = 881871 0.001123 % Total_count = 78545544701
test2> cat cast.c #include <stdlib.h> #include <stdio.h> int main() { double pi ; unsigned int *ip ; pi=3.141592654 ; printf("%f\n",pi) ; ip=(unsigned int *)&pi ; ip++ ; *ip |= 0x80000000 ; printf("%f\n",pi) ; } test2> gcc -O0 cast.c test2> ./a.exe 3.141593 -3.141593 test2> gcc -O1 cast.c test2> ./a.exe 3.141593 -3.141593 test2> gcc -O2 cast.c test2> ./a.exe 3.141593 3.141593 test2> gcc -O3 cast.c test2> ./a.exe 3.141593 3.141593 test2> gcc --version gcc (GCC) 3.2 20020818 (prerelease) Copyright (C) 2002 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
起きたら日が沈んでいて滝汗;;;。
init_view_coordinates()内のAssign_Vector()というマクロで
memcpy()を実行しているようですが、このmemcpy()のソースデータが
既に違っているという事のようです。で、probコマンドを使用して
該当メモリアドレスを触っている命令を探ってみたのですが、
何故かsrcポインタのくせに、そのmemcpy()内処理でポインタの先を
初めて参照している様子。んー?なんで?
ppcsimをチェックしたら、exec,c(continue)系実行コマンドでは
メモリプローブしていない事が発覚(^^;。しまった。
goコマンドでプローブしていった所、Parse_Camera()でデータを生成
しているようで、その最後のストア結果が違っている様子。ふむ、
カメラの向きがめちゃくちゃになっているという感じでしょうか?
更に追いかけた結果、演算結果が異なっている事が判明。しかも
ソース的に全然更新していない命令である所のfnmsub。で、ppcsimのソースを
少しいじったら結果が変わりました。どうやらdouble型のFPRの
符号反転をint型にキャストして符号ビットだけをいじって
いたのですが、それがうまく動作しなくなったらしいです。
Cygwinネイティブgccが3.2になった
影響かどうかは要調査。以下の例で左が正解値。結果である所の
fr13の符号がひっくり返っています。
PC : 100901e0 MSR : 00000000 SPRG0 : 00000000 DEC : 00000000 PC : 100901e0 MSR : 00000000 SPRG0 : 00000000 DEC : 00000000 CR : 42000824 SRR0 : 00000000 SPRG1 : 00000000 TBU : 00000000 CR : 42000824 SRR0 : 00000000 SPRG1 : 00000000 TBU : 00000000 XER : 20000000 SRR1 : 00000000 SPRG2 : 00000000 TBL : 03259c80 | XER : 20000000 SRR1 : 00000000 SPRG2 : 00000000 TBL : 03250320 LR : 1003a688 HID0 : 00000000 SPRG3 : 00000000 FPSCR : 00000000 LR : 1003a688 HID0 : 00000000 SPRG3 : 00000000 FPSCR : 00000000 CTR : 00000000 HID1 : 00000000 SDR1 : 00000000 CTR : 00000000 HID1 : 00000000 SDR1 : 00000000 GPR : GPR : 00-07 : 40300000 00ffebb0 00000000 40100000 00000000 3ffe4000 00000000 403e40 00-07 : 40300000 00ffebb0 00000000 40100000 00000000 3ffe4000 00000000 403e40 08-15 : 00000000 100ee730 803e4000 100efec8 28000820 1011e618 00000000 000000 08-15 : 00000000 100ee730 803e4000 100efec8 28000820 1011e618 00000000 000000 16-23 : 00000000 00000000 00000000 10119ed8 10110000 10110000 10110000 3ff000 16-23 : 00000000 00000000 00000000 10119ed8 10110000 10110000 10110000 3ff000 24-31 : 00000000 0020ba20 0020b9c0 00000000 10119ed8 101190e8 10120000 0020b9 24-31 : 00000000 0020ba20 0020b9c0 00000000 10119ed8 101190e8 10120000 0020b9 FPR : FPR : 00-03 : 3fd741f220000000 403e400000000000 bff0000000000000 000000000000000 00-03 : 3fd741f220000000 403e400000000000 bff0000000000000 000000000000000 04-07 : 3fe0000000000000 bfcdd3dc8b86b160 bfcdd3dc00000000 3fe000000000000 04-07 : 3fe0000000000000 bfcdd3dc8b86b160 bfcdd3dc00000000 3fe000000000000 08-11 : 3fe0000000000001 3ffe400000000000 3feb6d00a3c42ade bc71d0000000000 | 08-11 : 3fe0000000000001 3ffe400000000000 3feb6be4e79fa07b befc931d1e834e0 12-15 : 3ff602de00000000 7ff0000000000000 0000000000000000 000000000000000 12-15 : 3ff602de00000000 7ff0000000000000 0000000000000000 000000000000000 16-19 : 0000000000000000 0000000000000000 0000000000000000 000000000000000 16-19 : 0000000000000000 0000000000000000 0000000000000000 000000000000000 20-23 : 0000000000000000 0000000000000000 0000000000000000 000000000000000 20-23 : 0000000000000000 0000000000000000 0000000000000000 000000000000000 24-27 : 0000000000000000 0000000000000000 0000000000000000 000000000000000 24-27 : 0000000000000000 0000000000000000 0000000000000000 000000000000000 28-31 : 0000000000000000 0000000000000000 3ff0000000000000 403e40000000000 28-31 : 0000000000000000 0000000000000000 3ff0000000000000 403e40000000000 100901e0 : fdac4b3c fnmsub %fr13, %fr12, %fr9, %fr12 100901e0 : fdac4b3c fnmsub %fr13, %fr12, %fr9, %fr12 PC : 100901e4 MSR : 00000000 SPRG0 : 00000000 DEC : 00000000 PC : 100901e4 MSR : 00000000 SPRG0 : 00000000 DEC : 00000000 CR : 42000824 SRR0 : 00000000 SPRG1 : 00000000 TBU : 00000000 CR : 42000824 SRR0 : 00000000 SPRG1 : 00000000 TBU : 00000000 XER : 20000000 SRR1 : 00000000 SPRG2 : 00000000 TBL : 03259c90 | XER : 20000000 SRR1 : 00000000 SPRG2 : 00000000 TBL : 03250330 LR : 1003a688 HID0 : 00000000 SPRG3 : 00000000 FPSCR : 00000000 LR : 1003a688 HID0 : 00000000 SPRG3 : 00000000 FPSCR : 00000000 CTR : 00000000 HID1 : 00000000 SDR1 : 00000000 CTR : 00000000 HID1 : 00000000 SDR1 : 00000000 GPR : GPR : 00-07 : 40300000 00ffebb0 00000000 40100000 00000000 3ffe4000 00000000 403e40 00-07 : 40300000 00ffebb0 00000000 40100000 00000000 3ffe4000 00000000 403e40 08-15 : 00000000 100ee730 803e4000 100efec8 28000820 1011e618 00000000 000000 08-15 : 00000000 100ee730 803e4000 100efec8 28000820 1011e618 00000000 000000 16-23 : 00000000 00000000 00000000 10119ed8 10110000 10110000 10110000 3ff000 16-23 : 00000000 00000000 00000000 10119ed8 10110000 10110000 10110000 3ff000 24-31 : 00000000 0020ba20 0020b9c0 00000000 10119ed8 101190e8 10120000 0020b9 24-31 : 00000000 0020ba20 0020b9c0 00000000 10119ed8 101190e8 10120000 0020b9 FPR : FPR : 00-03 : 3fd741f220000000 403e400000000000 bff0000000000000 000000000000000 00-03 : 3fd741f220000000 403e400000000000 bff0000000000000 000000000000000 04-07 : 3fe0000000000000 bfcdd3dc8b86b160 bfcdd3dc00000000 3fe000000000000 04-07 : 3fe0000000000000 bfcdd3dc8b86b160 bfcdd3dc00000000 3fe000000000000 08-11 : 3fe0000000000001 3ffe400000000000 3feb6d00a3c42ade bc71d0000000000 | 08-11 : 3fe0000000000001 3ffe400000000000 3feb6be4e79fa07b befc931d1e834e0 12-15 : 3ff602de00000000 bf5f8c0e21000000 0000000000000000 000000000000000 | 12-15 : 3ff602de00000000 3f5f8c0e21000000 0000000000000000 000000000000000 16-19 : 0000000000000000 0000000000000000 0000000000000000 000000000000000 16-19 : 0000000000000000 0000000000000000 0000000000000000 000000000000000 20-23 : 0000000000000000 0000000000000000 0000000000000000 000000000000000 20-23 : 0000000000000000 0000000000000000 0000000000000000 000000000000000 24-27 : 0000000000000000 0000000000000000 0000000000000000 000000000000000 24-27 : 0000000000000000 0000000000000000 0000000000000000 000000000000000 28-31 : 0000000000000000 0000000000000000 3ff0000000000000 403e40000000000 28-31 : 0000000000000000 0000000000000000 3ff0000000000000 403e40000000000
214,221c214,221 < mres->FPR[fd].f=-((mres->FPR[fa].f * mres->FPR[fc].f) - mres->FPR[fb].f) ; --- > mres->FPR[fd].f=(mres->FPR[fa].f * mres->FPR[fc].f) - mres->FPR[fb].f ; > fpr_u = (unsigned int *)&mres->FPR[fd].f ; > #ifdef LITTLE_ENDIAN > fpr_u = fpr_u+1 ; > *fpr_u= *fpr_u ^ 0x80000000 ; > #else > *fpr_u= *fpr_u ^ 0x80000000 ; > #endif
大幅に日付け越え。
結局、トレースだけではよく判らず。正攻法で調べてみる事にしました。
レジスタダンプを比較した所、どうやらvbuffer.c:init_view_coordinates()という
関数でデータの結果が異なる部分があるようなので、そこに狙いを
絞って調べてみる事に。
でも眠くて死亡(ぉぃ;
日付け越え。
ppcsim結果異常の調査。トレースしてはdiffとかやってるうちに
ハングらかしたりしてscandisk。ちっとも進まず。
そうこうしているうちに「エコエコアザラク」の映画が始まったり
して思わず観てしまったり。これ、元々TV東京で土曜深夜にやってた
番組だったと思うのすが、途中で打ち切りになったのですよね
(というか、いつの間にか無くなっててどうしたのだろうと思っていたら、
打ち切りになったというのをネットで知った)。1996年作品だと
いう事ですが、そんなに前になるんだっけ?と思ったり。
でも菅野美穂が若いと思ったからそうなのかも。
日付け越え前に帰着。
取りあえず、stat構造体のデータを操作して、バッファ割り当て
量などを揃える様にしてみました。結果、途中の経過はほぼ同じ
結果となりました。で、「ほぼ」にかかってくる所が動くか動かない
かの差の部分になる訳ですが、レンダリング結果がNGな直接の
理由は、project_bbox()というバウンディングボックス設定
関連と思われる関数で、大量の差分が出ていて且つ問題のある
ppcsimの方では実行がスキップされているような感じになって
いました。因みに5000000命令実行した辺り。あぁ、これくらい
の所で差が出て良かった.......
という事はそれよりも手前の実行差分が問題という感じ。
stat.st_modeが違っているかと思ったけど気のせいだったらしい。
8進数でdefineされているのを16進数と思って読んでてどうして
その値が出てくるのか判らなかったりした罠。
動かないのとは直接関係ありませんでしたが、ファイルディスクリプタ
の0〜4はシステム予約として、closeしない様にppcsimでガードしていた
のですが、fd=3(prn)とfd=4(aux)は無くて良い様なので、
0(stdin),1(stdout),2(stderr)だけをclose()ガードする様に変更
しました。
大幅に日付け越え。
どうやら、povray-3.5だけでなく、povray-3.1の方もダメになって
いる模様。
不幸中の幸いか、gccのppc自力コンパイルを実行したときに
ppcsim実行バイナリをコピーして使用していて、それはpovray実行
OKなバイナリでした。そんな訳で、trace を仕掛けてPCの通り道が
違う所をチェックしてみることにしてみました。所が、stat構造体
に値が正しく入っていない頃のバイナリの為、fread()/fwrite()で
使用しているバッファサイズが最新と微妙に違っています。結果、
ちびちびとPC差分が出て、本当に違うのかどうかが判断しにくくて
死亡。
昼前起床。
何気にpovray-3.5のPPCバイナリを実行してみた所、レンダリング結果が
変な事に。truss onでチェックしてみた所、mmap()に768MBも要求していて
エラーになっているようだったので、その辺から調査。どうやらfstat64()の
結果が変なようで、stat構造体の値がヘンテコリンになっているようです。
ネイティブで実行した値が正しくセットされていないようで、それを
チェックしたところppcsimのバグ発覚(^^; 何故これで他のプログラムが
動いているのか謎ですが取りあえず修正。でも、レンダリングが変なのは
直らず。先日リリースした0.91でもNGなので、ヒープの位置を移動した
事には関係無さそう。壊したらしい.........。動くppcsimのバイナリもソースも既に
存在しないのが致命的。データアクセスエラーとかで死んでくれればもっと
簡単なのですが、結果異常は追いかけるの大変なんですよねぇ......
うーむ、どうしよう。
因みに、Linuxバイナリでかつfstat()を
使用しているプログラム以外では問題ありません。
ナイトホスピタル。面白いのぅ。
午前中に起きて洗濯したりppcsimをまとめたり。
ppcsim-0.91リリース。御参考まで。メモリ管理部分とかあまり
デバッグされてないので、不具合があるかも。
休出。
何気にgcc-3.2をCygwinネイティブでコンパイルして、
make checkなど実行してみたり。もう12時間以上実行してますが
終らず。Cygwin的にも少しカーソルが突っかかるなどパフォーマンス
的な問題が出てます。うーむ。
ppcsimのメモリ配置位置を変更。fork()でコピーされる
メモリ領域がセグメント0である必要が無くなったので、
ヒープを0x01000000から配置する様に変更しました。セグメント0
はテキストとargv,argcとスタックとで共有。ただし、Linuxバイナリ
の場合はテキストは0x10000000に配置という感じ。
12時間以上寝てたり(汗;。そして休日出勤。日付け越え。
先日アップデートしたCygwinパッケージですが、以前はgcj(javaコンパイラ)
は入っていなかったのですが、どうやら使える様なので使ってみました。
結果NG。リンクで大量にエラーが出たため色々なライブラリを追加でリンク
したのですが、結果は以下の通り。
java> cat test.java class hello { public static void main(String args[]) { System.out.println("hello world.\n") ; } } java> gcc test.java -lgcj -lz -liconv /usr/lib/gcc-lib/i686-pc-cygwin/3.2/../../../libcygwin.a(libcmain.o)(.text+0x7c): undefined reference to `_WinMain@16' collect2: ld returned 1 exit status
日付け越え。
makeはエラーでこけてました。エラーの状況は変わらず。
で、調査。
エラーしているのはwinsup/cygwin/tty.ccのコンパイルで
GetConsoleWindow()がundefinedでエラー。どうやら
gcc-3.2を入れた時にインストールされたヘッダがマズイ
らしく、
/usr/include/w32api/wincon.h からGetConsoleWindowの
宣言が消えている様です。winsup/w32api/include/wincon.h
と比べてみると、
*** winsup/w32api/include/wincon.h Fri Sep 6 13:26:32 2002 --- /usr/include/w32api/wincon.h Thu Aug 29 07:00:28 2002 *************** *** 132,140 **** BOOL WINAPI GetConsoleScreenBufferInfo(HANDLE,PCONSOLE_SCREEN_BUFFER_INFO); DWORD WINAPI GetConsoleTitleA(LPSTR,DWORD); DWORD WINAPI GetConsoleTitleW(LPWSTR,DWORD); - #if (_WIN32_WINNT >= 0x0500) - HWND WINAPI GetConsoleWindow(void); - #endif COORD WINAPI GetLargestConsoleWindowSize(HANDLE); BOOL WINAPI GetNumberOfConsoleInputEvents(HANDLE,PDWORD); BOOL WINAPI GetNumberOfConsoleMouseButtons(PDWORD); --- 132,137 ----