リンカへの入力として与えられるファイルは、オブジェクトファイルと呼ばれます。リンカは画像ファイルを生成し、それがローダーによる入力として使用されます。
「MicrosoftPortableExecutableand Common ObjectFileFormatSpecification 」の宣伝文
RVA(相対仮想アドレス)。画像ファイルにおいて、メモリにロードされた後のアイテムのアドレス。画像ファイルのベースアドレスが差し引かれます。アイテムのRVAは、ほとんどの場合、ディスク上のファイル内の位置(ファイルポインター)とは異なります。
オブジェクトファイルでは、メモリ位置が割り当てられていないため、RVAはあまり意味がありません。この場合、RVAはセクション(この表の後半で説明)内のアドレスであり、後でリンク中に再配置が適用されます。簡単にするために、コンパイラは各セクションの最初のRVAをゼロに設定する必要があります。
VA(仮想アドレス)。イメージファイルのベースアドレスが減算されないことを除いて、RVAと同じです。Windowsは、物理メモリとは関係なく、プロセスごとに個別のVAスペースを作成するため、このアドレスは「VA」と呼ばれます。ほとんどすべての目的で、VAは単なるアドレスと見なす必要があります。ローダーがイメージを優先位置にロードしない可能性があるため、VAはRVAほど予測可能ではありません。
これを読んだ後でも、私はまだそれを理解していません。たくさん質問があります。誰でも実際的な方法でそれを説明できますか?Object File
記載されているように&の用語に固執してくださいImage File
。
私が住所について知っているのはそれだけです
- オブジェクトファイルでも画像ファイルでも、正確なメモリ位置がわからないので、
- オブジェクトファイルの生成中のアセンブラは、セクション
.data
&.text
(関数名の場合)に関連するアドレスを計算します。 - 複数のオブジェクトファイルを入力として受け取るリンカーは、1つの画像ファイルを生成します。生成中に、最初に各オブジェクトファイルのすべてのセクションをマージし、マージ中に、各セクションに関連するアドレスオフセットを再計算します。そして、グローバルオフセットのようなものはありません。
私が知っていることに何か問題がある場合は、私を訂正してください。
編集:
フランソワ1世の答えを読んだ後、私は物理アドレス、VA、RVAとは何か、そしてそれらの間の関係は何かについて明確になりました。
すべての変数とメソッドのRVAは、再配置中にリンカーによって計算される必要があります。したがって、(メソッド/変数のRVAの値)==(ファイルの先頭からのオフセット)?真実でなければなりません。しかし、驚くべきことに、そうではありません。なぜそうなのか?
PEView を使用してこれを確認したc:\WINDOWS\system32\kernel32.dll
ところ、次のことがわかりました。
- RVAとFileOffsetは、セクションの先頭まで同じです(
.text
このdllの最初のセクションです)。 - の先頭から
.text
最後のセクションまで(.data
)RVAとFileOffsetが異なります。また、最初のセクションの最初のバイトのRVAは、「常に」次のように表示されます。.rsrc
.reloc
0x1000
- 興味深いのは、各セクションのバイトがFileOffsetで連続していることです。つまり、別のセクションは、セクションの最後のバイトの次のバイトから始まります。しかし、RVAで同じことを見ると、これらはセクションの最後のバイトと次のセクションの最初のバイトのRVAの間の大きなギャップです。
私の推測:
すべて、最初の(
.text
ここの)セクションの前にあったデータのバイトは、実際にはプロセスのVAスペースにロードされません。これらのデータのバイトは、これらのセクションを見つけて説明するために使用されます。それらは「メタセクションデータ」と呼ぶことができます。プロセスのVAスペースにロードされていないため。
RVA == FileOffset
RVAという用語の使用も無意味です。これがこれらのバイトの理由です。以来、
- RVA用語は、VAスペースに実際にロードされるバイトに対してのみ有効です。
.text
、、、.data
のバイト.rsrc
は.reloc
そのようなバイトです。- RVAから開始する代わりに、
0x00000
PEViewソフトウェアはから開始し0x1000
ます。
なぜ3回目の観測なのか理解できません。私は説明できません。