2011-10-11 2 views
5

私はいくつかのプログラムを書いており、64ビットでコンパイルするとメモリマッピングセグメント(例えば共有オブジェクトと共有メモリが保持される)が常に7f9aca84a000-7fff88400000のどこかに位置しますが、まったく同じではありません。ELF64/x86_64とメモリマッピングセグメントの開始アドレス(共有オブジェクト用)

x86_64アーキテクチャ(ELF64)でこのメモリセグメントの固定開始アドレスがあるかどうか、またはこのセグメントの最大範囲と最小範囲は何ですか?

ここで私はこの質問をしています。システムをTru64 UNIXからLinuxに移行しています。このシステムでは、IPC Sys V共有メモリの複雑な固定メモリマッピングが使用され、このセグメント内の構造から別の構造に移動するために連鎖リストが使用されています。このコードのサイズと複雑さ、そして私たちが手に取っていた時間が限られているため、共有メモリの開始を固定する堅牢な方法を見つけようとしています(セグメントを接続する特定のアドレス)。 64ビットでは、仮想アドレス空間が非常に大きく(48ビットの事実上可能なアドレス)、「安全な」固定アドレスを選択する方が32ビットよりもはるかに簡単でリスクも低くなります。

答えて

4

x86-64のメモリマッピングレイアウトは、arch/x86/mm/mmap.cで定義されています。ご覧のとおり、トップダウンとボトムアップの2つの戦略が使用されています。

デフォルトでは、トップダウン割り当てが使用されます。これは、スタックの最大範囲(スタックrlimitで定義されている)の128MBより小さく、ランダムなオフセットで微調整され、そこからメモリに下位のマッピングを割り当てます。

ボトムアップ割り当てはフォールバックです。次のいずれかの場合に使用されます。

  • スタックrlimitは無制限です。
  • このプロセスは、性格がADDR_COMPAT_LAYOUTです。または
  • vm.legacy_va_layout sysctlがゼロではありません。

ボトムアップ割り当ての場合、マップされた領域には、ランダムオフセットによって調整されたTASK_SIZE/3から順に上位アドレスが割り当てられます。 x86-64のTASK_SIZE0x800000000000であるため、ボトムアップの割り当ては約0x2AAAAAAAAAAAから開始されます。

どちらの割り当て戦略でもOKである固定マッピングには、適切な穴があることをお勧めします。2 * TASK_SIZE/3 - 0x500000000000を使用します。

+0

このような洞察をいただきありがとうございます。あなたが私に指摘したすべての情報を見て回ります。 – Huygens

+0

私たち自身の開始アドレスを与えることはできませんか? – sdkie

3

私はあなたには(まだ!)直接的な答えはありませんが、私は高いメモリ範囲外のメモリをうまくマッピングできたと言えるでしょう。たとえば、次のように

#include <stdio.h> 
#include <sys/mman.h> 
#include <stdint.h> 

#define ADDRESS 0x700000000 

int main(int argc, char *argv[]) { 
    uint64_t *map = mmap((void *)ADDRESS, 4096, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 

    map[0] = 64; 

    printf("Value: %lu\n", map[0]); 

    munmap(map, 4096); 

    return 0; 
} 

は私が現時点ではカーネルソースに目を通す時間がない怖いが、私は間違いなく、後で見てみましょう。私はいつもこの質問の答えが何であるか疑問に思いました。 。 。

+0

System V IPCのコードでも同様の手法が使用されていますので、shmatを呼び出すときに特別なアドレスを設定しました。マニュアルページのextractを参照してください。shmaddrがNULLでなく、shmflgにSHM_RNDが指定されている場合、SHMLBAの最も近い倍数に切り捨てられたshmaddrに等しいアドレスで接続が発生します。それ以外の場合、shmaddrは、アタッチが発生するページアライメントされたアドレスでなければなりません。 – Huygens

+0

難しいのは、提案したアドレス(0x700000000)のような正しいアドレスを決定することです。私たちの選択を明確に正当化できるようにしたいと考えています。 – Huygens

4

mmapedセグメントの固定開始アドレスはありますか?

いいえLinuxはASLR(Address Space Layout Randomization)をサポートしています。つまり、プログラム内のアドレスにはランダム性の要素があります。これは、いくつかの悪用を成功させる可能性を低くすることです。さらに、おそらく、いくつかのカーネルパッチは、異なるASLR戦略(通常のx86の場合)を実装しています。つまり、PaX、exec-shieldを考えてみましょう...

したがって、固定アドレスを使用する場合は、MAP_FIXED @Etherealが推奨するように。

関連する問題