次のコードは無効な出力を生成します。
#include <stdio.h>
extern const int i1, i2, i3, i4;
int main()
{
printf("i1=%d\n", i1);
printf("i2=%d\n", i2);
printf("i3=%d\n", i3);
printf("i4=%d\n", i4);
return 0;
}
const int dum1=1;
const int dum2=2;
const int dum3=3;
//const int dum4=4;
//const int dum5=5;
//const int dum6=6;
const int i1=1111;
const int i2=2222;
const int i3=3333;
const int i4=4444;
ランダムな数のダミー定数を試してみると、結果は次のように異なります。
良い:
i1=1111
i2=2222
i3=3333
i4=4444
悪いことに:
i1=1111
i2=2222
i3=3333
i4=0
i1=1111
i2=2222
i3=0
i4=0
md5-a7a998816ff6355b19ebaf6bb16f20b1
i1=1111
i2=0
i3=0
i4=0
md5-50fa41c3352404f2cadd42c17104c34f
ee-gcc -o hello.elf hello.c
ps2client -h 192.168.1.10 execee host:hello.elf
このバグにより、OPLのsize_ds34bt_irxおよび/またはsize_ds34usb_irxが0になります。起動時にOPLがランダムにクラッシュします(黒い画面)。 OPLのランダムな場所にコード行を追加すると、このバグが表示されたり消えたりします。
以下を使用して表示すると、ELFファイルの最後の128ビットに無効な値があるようです。
ee-objdump -D hello.elf
elfファイルの値は適切であるため、elfのロード中にどこかで問題が発生したようです。
その結論に到達した方法は驚くべきものです
ELF内の値が適切であると思われる場合は、ps2linkの問題だと思いませんか? ELFをロードするために別の方法を使用した場合はどうなりますか?
ps2linkがメモリをクリアしていないことが原因である可能性があります。 sceSifLoadElf()関数はメモリをゼロにしないため、ELFにその関数がロードされる前にメモリが消去されないと、不良データが表示される可能性があります。
ELF内の値が適切であると思われる場合は、ps2linkの問題だと思いませんか? ELFをロードするために別の方法を使用した場合はどうなりますか?
はい、ELFファイルのデータは良さそうなので、この問題のタイトルは少し誤解を招くと思います。 別のローダーを試してみます。
ps2linkがメモリをクリアしていないことが原因である可能性があります。 sceSifLoadElf()関数はメモリをゼロにしないため、ELFにその関数がロードされる前にメモリが消去されないと、不良データが表示される可能性があります。
const intは、.sdata(静的データ)セクションにあります。 .sdataセクションはelfファイルからメモリに16バイト/ 128ビット単位でどこかにコピーされていると思います。 おそらく、.sdataセクションが128ビットの倍数でない場合、残りのデータはコピーされず、その場所にゼロが残りますか?
または、.sdataセクションが正しくコピーされているのに、別のゼロ化されたセクションがその隣に正しく配置されていない可能性がありますか? そして、ゼロ調整は.sdataがコピーされた後に発生しますか?
こんにちは、
@ sp193が正しく、問題がps2link
にあるかどうかを確認するために、例を変更しました。関数scr_prinf
を使用して、画面に出力を表示し、次のように簡単に実行できます。 ULaunchELF
またはPCSX2
にロード
ファイルの内容
#include <stdio.h>
void init_scr(void);
void scr_printf(const char *, ...) __attribute__((format(printf,1,2)));
extern const int i1, i2, i3, i4;
int main()
{
init_scr();
scr_printf("i1=%d\n", i1);
scr_printf("i2=%d\n", i2);
scr_printf("i3=%d\n", i3);
scr_printf("i4=%d\n", i4);
while(1) {}
return 0;
}
const int dum1=1;
const int dum2=2;
const int dum3=3;
const int dum4=4;
const int dum5=5;
const int i1=1111;
const int i2=2222;
const int i3=3333;
const int i4=4444;
コンパイルプロセス
ee-gcc -o hello.elf hello.c -L$PS2SDK/ee/lib -ldebug
この場合、 PCSX2
を使用した出力
ご覧のとおり、結果は@rickgaiserがコメントしたものと同じです。
i1=1111
i2=2222
i3=3333
i4=0
ありがとう
ps2linkは、関数SifLoadElfを使用してelfファイルをロードします。
https://github.com/ps2dev/ps2link/blob/1ec566c54bb8b567ee0a702982b392f37807b5e2/ee/cmdHandler.c#L138
その結果、IOPでRPC関数が呼び出されます。 LOADFILEの一部。
これはLOADFILEのバグでしょうか? または、おそらく私たちのツールチェーンは、LOADFILEが期待するようにセクションを整列させていませんか? sbv_patchesでこの問題を修正できますか? LOADFILEにパッチを適用しているのがわかりますが、これに関連するパッチはありますか?
LOADFILEのSBVパッチは、LoadModuleBuffer()のRPC関数を有効にすることでした。 何らかの理由で、その関数はLOADFILEの初期バージョンではサポートされていません。 ソニーもパッチを当てているので、明らかに見落とされていたものです。
私はバグを見つけました:
crt0は、16バイト/ 128ビット単位で.bssセクションをクリアします。 .bssセクションを少なくとも16バイト/ 128ビットに揃える必要があります。 以前は、これはps2sdkのlinkerfileによって保証されていました。 ただし、binutilsのデフォルトのlinkerscript(https://github.com/ps2dev/ps2toolchain/commit/7c494f217d379639aaca23d3c588e48986177a51)は、crt0の.bssセクションを適切に配置しません。 その結果、.sdataの最後のいくつかの値もクリアされます。
ここで組み込みのbinutilsリンカースクリプトの修正を作成しました。 これはnewlibPRの一部になります。
IIRC、セクションが128ビットにアラインされていることを常に確認したいのですが、DMAアラインメントなどと関係があると思いますが、確かではありません。
この問題は、最近マージされたnewlib PR、特にこのコミットで解決されました: https ://github.com/ps2dev/ps2toolchain/commit/f5544b8d68fbdf611e277e9583714ae6627f3a61
最も参考になるコメント
私はバグを見つけました:
crt0は、16バイト/ 128ビット単位で.bssセクションをクリアします。 .bssセクションを少なくとも16バイト/ 128ビットに揃える必要があります。 以前は、これはps2sdkのlinkerfileによって保証されていました。 ただし、binutilsのデフォルトのlinkerscript(https://github.com/ps2dev/ps2toolchain/commit/7c494f217d379639aaca23d3c588e48986177a51)は、crt0の.bssセクションを適切に配置しません。 その結果、.sdataの最後のいくつかの値もクリアされます。
ここで組み込みのbinutilsリンカースクリプトの修正を作成しました。 これはnewlibPRの一部になります。