システムは、プロセスイメージを作成または拡張するとき、ファイルのセグメントを仮想メモリーセグメントに論理的にコピーします。システムがファイルをいつ物理的に読み取るかは、プログラムの挙動やシステムの負荷などに依存します。
プロセスは実行時に論理ページを参照しないかぎり物理ページを必要としません。プロセスは一般に多くのページを未参照状態のままにします。したがって、物理読み取りを遅延させると、システム性能を向上させることができます。この効率性を実現するには、実行可能ファイルと共有オブジェクトファイルには、ファイルオフセットと仮想アドレスがページサイズを法として同じであるセグメントイメージが存在する必要があります。
32 ビットのセグメントの仮想アドレスとファイルオフセットは、64K (0x10000) を法として同じです。64 ビットのセグメントの仮想アドレスとファイルオフセットは、1M バイト (0x100000) を法として同じです。セグメントを最大ページサイズに整列すると、ファイルは物理ページサイズには関係なくページング処理に対して適切になります。
デフォルトでは 64 ビット SPARC プログラムは開始アドレス (0x100000000) にリンクされます。プログラム全体は、テキスト、データ、ヒープ、スタック、および共用オブジェクト依存関係を含めて、4G バイトより上に存在します。そうすることにより、プログラムがポインタを切り捨てると、アドレス空間の最下位 4G バイトでフォルトが発生することになるので、64 ビットプログラムが正しいことをより簡単に確認できます。64 ビットプログラムは 4G バイトより上でリンクされていますが、リンカーに mapfile および -M オプションを使用することにより、プログラムを 4G バイト未満でリンクすることも可能です。詳細は、/usr/lib/ld/sparcv9/map.below4G を参照してください。
次の図に、SPARC バージョンの実行可能ファイルの例を示します。

次の表に、前の図に示した読み込み可能セグメント要素の定義を示します。
表 7–28 SPARC: ELF プログラムヘッダーセグメント (64K に整列)| メンバー | テキスト | データ | 
|---|---|---|
| p_type | PT_LOAD | PT_LOAD | 
| p_offset | 0x0 | 0x4000 | 
| p_vaddr | 0x10000 | 0x24000 | 
| p_paddr | 指定なし | 指定なし | 
| p_filesize | 0x3a82 | 0x4f5 | 
| p_memsz | 0x3a82 | 0x10a4 | 
| p_flags | PF_R + PF_X | PF_R + PF_W + PF_X | 
| p_align | 0x10000 | 0x10000 | 
次の図に、x86 バージョンの実行可能ファイルの例を示します。

次の表に、前の図に示した読み込み可能セグメント要素の定義を示します。
表 7–29 32 ビット x86: ELF プログラムヘッダーセグメント (64K に整列)| メンバー | テキスト | データ | 
|---|---|---|
| p_type | PT_LOAD | PT_LOAD | 
| p_offset | 0x0 | 0x4000 | 
| p_vaddr | 0x8050000 | 0x8064000 | 
| p_paddr | 指定なし | 指定なし | 
| p_filesize | 0x32fd | 0x3a0 | 
| p_memsz | 0x32fd | 0xdc4 | 
| p_flags | PF_R + PF_X | PF_R + PF_W + PF_X | 
| p_align | 0x10000 | 0x10000 | 
例に示したファイルオフセットと仮想アドレスは、テキストとデータの両方に対して最大ページサイズを法として同じですが、最大 4 ファイルページ (ページサイズとファイルシステムブロックサイズに依存) に、純粋ではないテキストやデータが含まれます。
先頭テキストページには、ELF ヘッダー、プログラムヘッダーテーブル、およびほかの情報が存在します。
最終テキストページには、データの始まりのコピーが存在します。
先頭データページには、テキストの終わりのコピーが存在します。
最後のデータページには、実行中プロセスに関連していないファイル情報が存在できます。論理的にはシステムは、あたかも各セグメントが完全であり分離されているようにメモリーアクセス権を設定します。セグメントのアドレスは調整され、アドレス空間の各論理ページに同じアクセス権セットが確実に存在するようになります。前の例では、テキストの終わりとデータの始まりを保持しているファイル領域が 2 回対応付けされます。 1 回はテキストに関して 1 つの仮想アドレスで対応付けされ、もう 1 回はデータに関して別の仮想アドレスで対応付けされます。
前の例は、テキストセグメントを丸めた、典型的な Solaris OS のバイナリを反映したものです。
データセグメントの終わりは、初期化されていないデータに対して特別な処理を必要とします (初期値が 0 になるようにシステムで定義されている)。ファイルの最後のデータページに、論理メモリーページに存在しない情報が存在する場合、これらのデータは 0 に設定しなければなりません (実行可能ファイルの未知の内容のままにしてはならない)。
ほかの 3 ページに含まれる純粋でないテキストまたはデータは、論理的にはプロセスイメージの一部ではありません。システムがこれらの純粋でないテキストまたはデータを除去するかどうかについては、規定されていません。このプログラムのメモリーイメージが 4K バイト (0x1000) ページを使用する例を、次の図に示します。単純化するために次の図では、1 ページのサイズのみを示しています。


セグメント読み込みは、実行可能ファイルと共有オブジェクトでは異なる側面が 1 つ存在します。実行可能ファイルのセグメントには、標準的には絶対コードが存在します。プロセスを正しく実行するには、セグメントは実行可能ファイルを作成するために使用された仮想アドレスに存在しなければなりません。システムは変化しない p_vaddr 値を仮想アドレスとして使用します。
一方、通常は共有オブジェクトのセグメントには、位置独立のコードが存在します。したがって、セグメントの仮想アドレスは、実行動作を無効にすることなくプロセス間で変化させることができます。
システムは個々のプロセスごとに仮想アドレスを選択しますが、セグメントの相対位置は維持します。位置独立のコードはセグメント間で相対アドレス指定を使用するので、メモリーの仮想アドレス間の差は、ファイルの仮想アドレス間の差に一致しなければなりません。
次の表は、いくつかのプロセスに対する共有オブジェクト仮想アドレスの割り当ての例で、一定の相対位置になることを示しています。これらの表は、ベースアドレスの計算も示しています。
表 7–30 32 ビット SPARC: ELF 共有オブジェクトセグメントアドレスの例| 送信元 | テキスト | データ | ベースアドレス | 
|---|---|---|---|
| ファイル | 0x0 | 0x4000 | 0x0 | 
| プロセス 1 | 0xc0000000 | 0xc0024000 | 0xc0000000 | 
| プロセス 2 | 0xc0010000 | 0xc0034000 | 0xc0010000 | 
| プロセス 3 | 0xd0020000 | 0xd0024000 | 0xd0020000 | 
| プロセス 4 | 0xd0030000 | 0xd0034000 | 0xd0030000 | 
表 7–31 32 ビット x86: ELF 共有オブジェクトセグメントアドレスの例
| 送信元 | テキスト | データ | ベースアドレス | 
|---|---|---|---|
| ファイル | 0x0 | 0x4000 | 0x0 | 
| プロセス 1 | 0x8000000 | 0x8004000 | 0x80000000 | 
| プロセス 2 | 0x80081000 | 0x80085000 | 0x80081000 | 
| プロセス 3 | 0x900c0000 | 0x900c4000 | 0x900c0000 | 
| プロセス 4 | 0x900c6000 | 0x900ca000 | 0x900c6000 | 
動的リンクを開始する動的実行可能ファイルまたは共有オブジェクトは、1 つの PT_INTERP プログラムヘッダー要素を保持できます。システムは exec(2) の実行中に、PT_INTERP セグメントからパス名を取り出し、そのインタプリタファイルのセグメントから初期プロセスイメージを作成します。インタプリタはシステムから制御を受け取り、アプリケーションプログラムに対して環境を提供する必要があります。
Solaris OS では、インタプリタは実行時リンカー ld.so.1(1) として知られています。