16

x86/x86_64 で、アラインされていないメモリ アクセスが禁止されているシステムをエミュレートしたいと考えています。これを行うためのデバッグツールまたは特別なモードはありますか?

SPARC または他の同様の CPU 用に設計されたソフトウェア (C/C++) を使用して、いくつかの x86/x86_64 PC で多くの (CPU 集中型の) テストを実行したいと考えています。しかし、Sparc へのアクセスは制限されています。

私が知っているように、Sparc は常にメモリーの読み取りと書き込みが自然に行われるようにアラインメントをチェックします (任意のアドレスから 1 バイトを読み取るが、アドレスが 4 で割り切れる場合にのみ 4 バイトのワードを読み取ることができます)。

Valgrind または PIN にそのようなモードがあるのでしょうか? またはコンパイラの特別なモード?Linux の非商用ツールを探していますが、Windows ツールも許可されています。

それとも、EFLAGS に秘密の CPU フラグがあるのでしょうか?

4

4 に答える 4

12

ちょうど質問を読んだところですアライメントされていないメモリアクセスは常にバスエラーを引き起こしますか? ウィキペディアの記事Segmentation Faultにリンクされています。

この記事には、あまり一般的ではないIntel プロセッサ フラグAC (Alignment Check)の素晴らしいリマインダーがあります。

そして、それを有効にする方法は次のとおりです (Wikipedia のBus Error exampleから、x86-64 System V 用に修正されたレッド ゾーン クロバー バグにより、これは Linux および MacOS で安全であり、基本的な asm から変換されますが、関数内では決して良い考えではありません: AC への変更を、メモリ アクセスに基づいて順序付けする必要があります。

#if defined(__GNUC__)
# if defined(__i386__)
    /* Enable Alignment Checking on x86 */
    __asm__("pushf\n orl $0x40000,(%%esp)\n popf" ::: "memory");
# elif defined(__x86_64__) 
     /* Enable Alignment Checking on x86_64 */
    __asm__("add $-128, %%rsp \n"    // skip past the red-zone, in case there is one and the compiler has local vars there.
            "pushf\n"
            "orl $0x40000,(%%rsp)\n"
            "popf \n"
            "sub $-128, %%rsp"       // and restore the stack pointer.
           ::: "memory");       // ordered wrt. other mem access
# endif
#endif

有効にすると、 の ARM アライメント設定と同じように機能します。アンアライメントされたメモリ アクセスをトラップする方法を/proc/cpu/alignment参照してください。例えば。

さらに、GCC を使用している場合は、-Wcast-align警告を有効にすることをお勧めします。厳密なアラインメント要件を持つターゲット (ARM など) 向けにビルドする場合、GCC はアラインされていないメモリ アクセスにつながる可能性のある場所を報告します。

ただし、me​​mcpy およびその他の関数に対する libc の手書きの asm は依然として非整列アクセスを行うため、AC を設定することは x86 (x86-64 を含む) では実用的でないことが多いことに注意してください。GCC は、ソースがアラインされていなくても、アラインされていないアクセスを行う asm を出力することがあります。たとえば、隣接する 2 つの配列要素または構造体メンバーを一度にコピーまたはゼロにするための最適化としてです。

于 2013-07-19T14:20:21.630 に答える
8

トリッキーで、私は個人的にはしていませんが、次の方法で行うことができると思います。

x86_64 CPU(具体的には、Intel Corei7をチェックしましたが、他のCPUもチェックしました)には、パフォーマンスカウンターMISALIGN_MEM_REFがあり、メモリ参照の不整合に対抗します。

そのため、まず、Linuxでプログラムを実行し、「perf」ツールを使用して、コードが行った不整合なアクセスの数をカウントできます。

よりトリッキーで興味深いハックは、パフォーマンスカウンターをプログラムしてオーバーフロー時に割り込みを生成し、最初の整列されていないロード/ストアをオーバーフローさせるカーネルモジュールを作成することです。カーネルモジュールでこの割り込みに応答しますが、プロセスにシグナルを送信します。

これにより、事実上、x86_64が非整列アクセスをサポートしないコアになります。

ただし、これは単純ではありません。コードのほかに、システムライブラリも非整列アクセスを使用するため、独自のコードからそれらを分離するのは難しいでしょう。

于 2012-08-07T06:15:29.280 に答える
0

おそらく、すべての整列された動きで、どうにかして SSE にコンパイルできます。でのアライメントmovapsされていないアクセスは不正であり、おそらく他のアーキテクチャでは不正なアライメントされていないアクセスとして動作するでしょう。

于 2012-08-07T00:14:52.577 に答える