2017-06-26 2 views
3

は、私が(外部関数funへの呼び出しを含むmain.cのファイルを持っている)移転やシンボルテーブル値

int main() 
{ 
fun(); 
} 

とreadelfが-rの結果、私はちょうどしたい

 
Relocation section '.rela.text' at offset 0x298 contains 3 entries: 
Offset   Info   Type   Sym. Value Sym. Name +Addend 
00000000000a 000b00000002 R_X86_64_PC32  0000000000000000 fun - 4 

を以下のようです情報フィールド(シンボルテーブルのエントリ)がシンボルfunでマッピングされ、sym.valueが0000である理由を知っていますか?

+0

オブジェクトファイルで 'readelf'を呼び出していますか?シンボル 'fun'がリンカによってまだ解決されていないときは? –

+0

はい私はオブジェクトファイル上のreadelfを呼び出しましたオブジェクトファイルはリンカによって作成されていません..Linkerはそのオブジェクトファイルをリンクするだけですので上記のコードのオブジェクトファイルを作成でき、私の質問に示されているようにreadelfの結果を得ます – Akshay

+3

オブジェクトファイルはありませんそれらは基本的に単一の[*翻訳単位*](https://en.wikipedia.org/wiki/Translation_unit_(プログラミング))を表します。他の場所で定義されたシンボルは解決できません。そのため、そのような関数の値はゼロです。 –

答えて

1

C標準ではは実際にはではありませんが、これがどのようにカバーで動作するかを指定しています。以下の説明は非常に一般的な実装方法です。コードを保持している単一の翻訳単位で


int main() { fun(); } 

コンパイルされているから入手可能な情報(まだリンクされていない)オブジェクトファイルは基本的に次のとおりです。

symbol status value 
------ ------ ----- 
main defined pointer to main within object 
fun  needed zero 

それためですを知っています。mainは、funに関する情報はありませんが、後で見つける必要があります。したがって、オブジェクトファイルを読み取ると、当然、funの未知の値が返されます。もちろん

、あなたは、このような別の翻訳単位のように、同様funを定義するためにいくつかのコードが必要になります。

void fun(void) { puts("Hello, world."); } 

は、以下の情報につながるこのをコンパイル:

symbol status value 
------ ------ ----- 
fun  defined pointer to fun within object 
puts needed zero 

これらを結びつけるのは、のリンクステージです。 オブジェクトファイル(およびCランタイムライブラリputsなどの他の依存関係のオブジェクト/ライブラリファイル)も一緒にバインドし、未定義シンボルを使用するすべてのコードを調整します。

これで、すべてのシンボルがわかっており、すべての参照が解決された実行可能ファイル形式になります。

関連する問題