2010-11-24 19 views

答えて

2

_startシンボルは、任意のオブジェクトファイルで定義できます。通常は自動的に生成されます(Cではmainに対応)。リンカはそれが_startシンボルを探し、elf headere_entryフィールドにその値を置くすべてのオブジェクトファイルを処理したとき

.globl _start 
_start: 
    // assembly here 

:あなたはそれは、アセンブラソースファイル内のインスタンスのために、自分自身を生成することができます。ローダは、このフィールドからアドレスを取得し、メモリ内のすべてのセクションのロードが完了し、ファイルを実行する準備ができた後で、そのフィールドを呼び出します。

+0

通常、 '_start'は少なくともGCC/glibcでは' main'ではありません: '_start'は初期化関数を呼び出してから' main'を呼び出し、 'exit () 'が返された値を' main'で返します。 – ysdx

0

わかりませんが、このリンクを試してみてください。http://www.docstoc.com/docs/23942105/UNIX-ELF-File-Format (8ページ)実行可能であれば、エントリポイントが表示されます。基本的にオフセットを計算する必要があります。 x86の小さなエンディアンを覚えていることを確かめてください(あなたが使っていると思います)。バイト編集を読んでいれば再注文してください。正直言ってこのことについて確信を持っていないかもしれません。

+0

リンクされたドキュメントがペイウォールの背後にあるようです... – Calmarius

1

リンカスクリプト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になります。

関連する問題