2012-02-06 9 views
4
nm -D /lib32/libc.so.6 | grep '\<fopen\>' 
0005d0c0 T fopen 
00109750 T fopen 

readelf -s /lib32/libc.so.6 | egrep '0005d0c0|00109750' 
181: 0005d0c0 50 FUNC GLOBAL DEFAULT 12 [email protected]@GLIBC_2.1 
182: 00109750 136 FUNC GLOBAL DEFAULT 12 [email protected]_2.0 
679: 0005d0c0 50 FUNC GLOBAL DEFAULT 12 [email protected]@GLIBC_2.1 
680: 00109750 136 FUNC GLOBAL DEFAULT 12 [email protected]_2.0 

は私の質問です:なぜ/lib32/libc.so.6に2つの "fopen"シンボルがあるのですか?ここ

  1. /lib32/libc.so.6はそれに2つのfopenのシンボルを持っている理由は?同じターゲットファイル内の同じシンボルは禁止する必要があります。

  2. なぜfopenの代わりにreadelf -sがfopen @@ GLIBC_2.1と[email protected]_2.0をダンプするのですか?

おかげで同じシンボルの

答えて

3

実際には複数の定義は大丈夫ですし、いくつかの方法で発生する可能性があります。それらのうちの1つ(ここではそうではない)は、弱い記号である。

glibcダイナミックリンカはシンボルのバージョン管理をサポートしており、glibcはそれを使用します。これはglibc 2.1からfopenのバージョンをエクスポートし、glibc 2.0から下位互換性のあるバージョンを異なるインタフェースでエクスポートします。

動的リンク時に、アプリケーションは特定のバージョンまたはデフォルトのものを選択できます。

+0

ありがとうgby、これについての例を挙げてください。ありがとう:) – camino

+1

共有ライブラリに関する何かの惑星上の最も良いリソースは、Ulrich Drepperの「共有ライブラリを書く方法」です:http://people.redhat.com/ drepper/dsohowto.pdf – gby

+0

ありがとう! :) – camino

9

ここで何が起こっているのか理解するために、まずバイナリ互換性がどのように伝統的に処理されているかを理解する必要があります。

"外部バージョニング"のメカニズムが使用されました。 libfoo.so.1で始まり、既存の関数のABIを変更する必要が生じたときには、libfoo.so.2を導入する必要がありました。

libfoo.so.2が古いABIとlibfoo.so.1を使用し続け、そして新しいのaplicationsが新しいABIとlibfoo.so.2を使用する前にリンクされたアプリケーション。

これはすべて、詳細にはhereで説明されています。

しかしglibcはextensionを導入しました。新しいライブラリを導入する代わりに(既存のコードと99%のコードを共有する)、新しいシンボルを既存のライブラリに導入します。

libc.so.6のバージョンは、のバージョン6にとどまり、古いバイナリが動作し、ABIが進化します。 fopenの特定の場合において

struct FILE非互換変化はglibcのバージョン2.1で行いました。 glibc-2.0システム上でリンクされていたバイナリは、古いstruct FILE(当時利用可能だった唯一のもの)を引き続き使用し、_IO_old_fopen(そのうち[email protected]_2.0はエイリアスです)を引き続き呼び出します。 glibc-2.1以降にリンクされているバイナリは新しいstruct FILEを使用し、_IO_new_fopen[email protected]_2.1はエイリアス)を呼び出します。

@@は、現在ののデフォルトシンボルバージョンを示す単なる表記です。

関連する問題