1

最初に「mips-linux-gnu-gcc-EL」を使用して「exec_sigma」を作成し、次に「mipsel-linux-uclibc-gcc」を使用して「exec_bcm」を作成したテストアプリケーションがあります。

これらの実行可能ファイルのreadelfを実行した後、私は多くの違いを得ました。主に.debug_infoセクションの違いが気になります

elf_sigmaの場合:それは:

[33] .debug_info MIPS_DWARF 00000000 01357b 02fa1e 00 0 0 1

[34] .debug_abbrev MIPS_DWARF 00000000 042f99 0040cd 00 0 0 1

そしてelf_bcmで:それは:

[32] .debug_info MIPS_DWARF 00000000 02329b 0058ba 00 0 0 1

[33] .debug_abbrev MIPS_DWARF 00000000 028b55 000619 00 0 0 1

この違い(サイズの違い)により、アプリケーションでスタックトレースを実行するバグが発生しています。mips-linux-gnu-gcc -ELでは機能しますが、mipsel-linux-uclibc-gccでは機能しません。同じ実行可能ファイルのセクションでこの違いが発生する理由を知りたいのですが、それは正常ですか?

質問を読んでくれてありがとう。

4

1 に答える 1

0

基本的に、2つの異なるコンパイラを使用して同じコードをコンパイルします。コンパイラが同じソースコード自体からのものである可能性がありますが、異なるジョブを実行し、異なるジョブを実行するように構築されていることを確認してください。実行可能ファイルが一致することは期待できません。ここでのバグはあなたの期待です。

「あなたがしなければならないすべて」は、いくつかのアドレスを反転し、すべてのバイトとハーフワードのデータを反転することですが、それ以外は同じバイナリを持っていることを望むかもしれません。これがその理論の非常に単純な問題の1つです。コンパイラがアクセスしたいバイトがあり、1つのエンディアンを使用してアドレス0x100000にあるとします。単一の命令luiは、後でバイトを読み取るためにそのアドレスをレジスタにロードできます。何らかの理由でエンディアンの変更によりそのアドレスに下位ビットが必要になった場合、たとえば0x100003の場合、そのアドレスをレジスタやメモリ位置にロードするために2つの命令が必要になり、そのメモリ位置の1回の読み取りが必要になります。可能な限り最後の瞬間までインドに依存しないことを目標とするコンパイラを作成し、エンディアンレスコードを生成することが可能であるはずです(からのロードワードを使用してすべてのアドレスをレジスタにロードします。テキストは即時ロードを使用しないでください)、それからどういうわけかそれをすべて追跡し、最後にパッチを当てます。なぜ誰もがそのようなコンパイラを作りたいのかを尋ねる必要があります。時間がかからないのは非常に小さなユースケースです。通常、このようなものではなく、コンパイラのパフォーマンスが必要です。

コンパイルされたプログラムを逆アセンブルまたはobjcopyからバイナリに変換し、2つのバイナリを比較すると、2つがどこで分岐しているかがすぐにわかります。逆アセンブルを使用すると、おそらく特定の例ではなく、そのようなもののフレーバーを使用できます。1つのバイト、ワード、または命令を一方のコンパイラで追加する必要があり、もう一方のコンパイラでは追加しないとすぐに(コンパイラが他の点では同一であると仮定して)、アドレス指定の変更により、命令の違いがさらに発生し、バイナリが継続する可能性があります。発散。

于 2012-07-02T14:12:11.183 に答える