2012-05-02 1 views
15

実行ファイルのELFファイルがreadelf -aを通して見ることができるプログラム(セグメント)ヘッダとセクションヘッダを有し、ここでは一例である:ELFファイルのどの部分をメモリにロードする必要がありますか?

enter image description here

enter image description here

二つの絵は、上記されていますセクションヘッダーとプログラム(セグメント)ヘッダーをそれぞれ示します。セグメントヘッダーは、プログラムをメモリにロードするために使用されるいくつかのセクションヘッダーで構成されていることがわかります。

.text、.rodata、.data、.bssセクションをメモリにロードするだけでよいですか?

セグメントの他のすべてのセクション(たとえば、第3セグメントの.ctors、.dtors、.jcr)が整列に使用されていますか?

+1

_aligning_? –

+0

@ Adrianoはい、ページサイズに合わせてyesなので、プログラムのさまざまな部分に対してさまざまな保護を使用できます。たとえば、.text(rx)、data(rw-) –

答えて

18

セクションとセグメントは完全に2つの異なる概念です。セクションはそこに格納されているデータのセマンティクス(すなわち、それが使用されるもの)に関係し、デバッグの目的を除いてプログラムまたは共有ライブラリがリンクされると実際には無関係です。セクションヘッダーを完全に削除(またはランダムなゴミで上書き)することもできます。プログラムは引き続き動作します。

セグメント(プログラムヘッダーロードディレクティブ)は、プログラムをロードするときに実際にカーネルお​​よび/またはダイナミックリンカーが参照するものです。たとえば、2つのロード・ディレクティブがあります。最初のものは、ファイルの最初の4k(1ページ)がアドレス0x08048000にマップされ、このマッピングの最初の0x4b8バイトだけが実際に使用されることを示します(残りはアラインメントです)。 2つ目は、ファイルの最初の8k(2ページ)がアドレス0x08049000にマップされるようにします。その大部分は整列です。最初の0xf14バイトはloadディレクティブの一部ではなく(ちょうど整列)、無駄になります。 0x08049f14から、ファイルからマップされた0x108バイトが実際に使用され、別の0x10バイト(0x118のMemSizeに達する)はローダー(カーネルまたはダイナミックリンカー)によってゼロ充填されます。これは、0x0804a02c(2番目にマップされたページ)までです。 2番目にマップされたページの残りの部分は未使用/無駄です(ただし、mallocはヒープの一部として使用するために回復する可能性があります)。

最後に、セクションヘッダーはまったく使用されませんが、実行中にプログラムによって多くの異なるセクションの内容が使用される可能性があります。 .ctors.dtorsのアドレス範囲は、2回目のロードマッピングの開始時にあるため、実行時にプログラムによってマップされ、アクセス可能です(ランタイムスタートアップ/終了コードは、C++の場合はそれらを使用してグローバルコンストラクタとデストラクタを実行します)。 ctor/dtor属性の「GNU C」コードが使用されました)。 .dataは、2番目にマップされたページのアドレス0x0804a00cで開始することにも注意してください。これにより、再配置が適用された後に最初のページが読み取り専用に保護されます(プログラムヘッダーのRELROディレクティブ)。

+0

+1は指摘用GNU_RELRO – SquareRootOfTwentyThree

+0

CにはコンストラクタC++としてのデストラクタ? –

+0

いいえ、GCCはCではなく、 "GNU C"です。あなたは例外やコンストラクタのようなあらゆる種類の非標準的な処理を行うことができます。 –

関連する問題