私はELF仕様を読んできたので、プログラムエントリポイントと_startアドレスがどこから来たのか分かりません。ELFファイルでは、_startのアドレスはどのように決定されますか?
かなり安定した場所にいなければならないようですが、私はいくつかの簡単なプログラムを作って、_startはいつも別の場所にあります。
誰でも明示できますか?
私はELF仕様を読んできたので、プログラムエントリポイントと_startアドレスがどこから来たのか分かりません。ELFファイルでは、_startのアドレスはどのように決定されますか?
かなり安定した場所にいなければならないようですが、私はいくつかの簡単なプログラムを作って、_startはいつも別の場所にあります。
誰でも明示できますか?
_start
シンボルは、任意のオブジェクトファイルで定義できます。通常は自動的に生成されます(Cではmain
に対応)。リンカはそれが_start
シンボルを探し、elf headerのe_entry
フィールドにその値を置くすべてのオブジェクトファイルを処理したとき
.globl _start
_start:
// assembly here
:あなたはそれは、アセンブラソースファイル内のインスタンスのために、自分自身を生成することができます。ローダは、このフィールドからアドレスを取得し、メモリ内のすべてのセクションのロードが完了し、ファイルを実行する準備ができた後で、そのフィールドを呼び出します。
わかりませんが、このリンクを試してみてください。http://www.docstoc.com/docs/23942105/UNIX-ELF-File-Format (8ページ)実行可能であれば、エントリポイントが表示されます。基本的にオフセットを計算する必要があります。 x86の小さなエンディアンを覚えていることを確かめてください(あなたが使っていると思います)。バイト編集を読んでいれば再注文してください。正直言ってこのことについて確信を持っていないかもしれません。
リンクされたドキュメントがペイウォールの背後にあるようです... – Calmarius
リンカスクリプトld
を見てみましょうが使用している:
ld -verbose
をフォーマットで文書化されている:https://sourceware.org/binutils/docs-2.25/ld/Scripts.html
それは基本的に実行ファイルが生成される方法についてのすべてを決定します。 Binutilsの2.24のUbuntu 14.04 64ビットで
、それは行を含む:
ENTRY(_start)
_start
シンボルにエントリポイントを設定する(CTNによって述べたようにELFヘッダになる)
そしてその後:0x400000
+ SIZEOF_HEADERS
第1のヘッダのアドレスを設定
. = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
。
は、私が0x800000
にそのアドレスを変更した、ld -T
と私のカスタムスクリプトを渡され、それが働いた:readelf -s
は_start
は、そのアドレスであることを述べています。
これを変更するもう1つの方法は、-Ttext-segment=0x800000
オプションを使用することです。
0x400000
= 4Mビット= getconf PAGE_SIZE
を使用する理由がに尋ねたように、第2のページの先頭から開始することです:Why is the ELF execution entry point virtual address of the form 0x80xxxxx and not zero 0x0?
質問は、コマンドラインから_start
を設定する方法について説明します。Why is the ELF entry point 0x8048000 not changeable with the "ld -e" option?
SIZEOF_HEADERS
ELF +プログラムヘッダーのサイズで、ELFファイルの先頭にあります。そのデータは、Linuxによって仮想メモリ空間の始めにロードされます(TODOはなぜですか?)2つのプログラムヘッダを持つ最小限のLinux x86-64 helloの世界では0xb0
という価値があり、_start
のシンボルは0x4000b0になります。
通常、 '_start'は少なくともGCC/glibcでは' main'ではありません: '_start'は初期化関数を呼び出してから' main'を呼び出し、 'exit () 'が返された値を' main'で返します。 – ysdx