2

チュートリアルに従って、自分のOS用にNewLibを移植しています。

crt0を終了したら、「最初のオブジェクトとしてリンクする」必要があると書かれています。どうやってやるの?

4

3 に答える 3

4

crt0を終了したら、「最初のオブジェクトとしてリンクする」必要があると書かれています。

それは正確に言うことを意味します。OSのアプリケーションがリンクされている場合、crt0は、リンカーのコマンドラインの最初のオブジェクトファイルである必要があります。他のオブジェクトファイルの前です。

従来、UNIXリンカは、最初のオブジェクト/ライブラリから最後のオブジェクト/ライブラリにループオーバーしてルックアップを行うことにより、シンボルを解決します。最初のオブジェクトファイルとして配置すると、システムシンボル(関数、変数)が他のファイルではなくcrt0crt0ファイルから選択されるようになります。

さらに、R ..が指摘しているように、従来のリンカは、アプリケーションのエントリポイントがコードセグメントの先頭にあると想定しています。これは、リンク先のページにあるソースコードにも当てはまります。コードの最初の記号は_start、プログラムのエントリポイントの通常の名前です。

たとえばgcc -v a.c -o a、Debianで実行している場合(に注意して-vください)、次のリンクコマンドが表示されます(読みやすくするために新しい行を追加しました)。

/usr/lib/gcc/i486-linux-gnu/4.4.4/collect2
--build-id
--eh-frame-hdr
-m elf_i386
--hash-style=both
-dynamic-linker /lib/ld-linux.so.2
-o a 
/usr/lib/gcc/i486-linux-gnu/4.4.4/../../../../lib/crt1.o 
/usr/lib/gcc/i486-linux-gnu/4.4.4/../../../../lib/crti.o 
/usr/lib/gcc/i486-linux-gnu/4.4.4/crtbegin.o
-L/usr/lib/gcc/i486-linux-gnu/4.4.4
-L/usr/lib/gcc/i486-linux-gnu/4.4.4
-L/usr/lib/gcc/i486-linux-gnu/4.4.4/../../../../lib
-L/lib/../lib
-L/usr/lib/../lib
-L/usr/lib/gcc/i486-linux-gnu/4.4.4/../../.. 
/tmp/ccndJ4YV.o
-lgcc
--as-needed
-lgcc_s
--no-as-needed
-lc
-lgcc
--as-needed
-lgcc_s
--no-as-needed 
/usr/lib/gcc/i486-linux-gnu/4.4.4/crtend.o 
/usr/lib/gcc/i486-linux-gnu/4.4.4/../../../../lib/crtn.o

crt1がコマンドラインの最初のオブジェクトであることがわかります。リンカースクリプト(私のシステムでは-m elf_i386-> ->)を見ると、Linuxにはがないことを確認できますが、:、、、、、があります。また、アプリケーションオブジェクトファイル(上記のサンプル)は、との間に配置されます。find /usr -name '*elf_i386*'/usr/lib/ldscripts/elf_i386.xcrt0crt1crticrtbegincrtendcrtn/tmp/ccndJ4YV.ocrtbegincrtend

于 2010-08-01T11:45:20.223 に答える
1

にジャンプする前にmain()、cランタイムは初期化を行う必要があります。このジョブは。によって処理されcert{i,n,0}ます。

ここに画像の説明を入力してください

于 2016-06-09T15:57:56.383 に答える
0

少なくともテストするための1つの方法は、crt0.oをコンパイラまたはリンカのコマンドラインの最初のファイルとして配置することです。

本番環境では、リンカーコマンドファイルに配置します。

于 2010-08-01T11:38:59.200 に答える