libcの異なるシンボルが異なるバインディング宣言を使用するのはなぜですか?
1510 0x0003d200 0xf7d55200 WEAK FUNC 55 system
454 0x00067b40 0xf7d7fb40 WEAK FUNC 474 puts
147 0x000303d0 0xf7d483d0 GLOBAL FUNC 33 exit
からreadelf -s /lib/i386-linux-gnu/libc-2.27.so
、
1510: 0003d200 55 FUNC WEAK DEFAULT 13 system@@GLIBC_2.0
454: 00067b40 474 FUNC WEAK DEFAULT 13 puts@@GLIBC_2.0
147: 000303d0 33 FUNC GLOBAL DEFAULT 13 exit@@GLIBC_2.0
この質問から、作成者の libc にLOCAL
終了があるようです。
さまざまなlibcバインディングレベルの背後に隠れた韻や理由は何ですか?
ベストアンサー1
glibc の弱いシンボルは、静的リンクでも再定義を可能にします。
グローバル出口(Global Exit)は強力なシンボルです。追加の定義は解決されず、リンクエラーが発生します。
したがって、独自のものを提供することができputs
、2番目の定義がputs
強力でない場合は、puts
メモリスペース(サイズ)が最も大きい定義が選択されます。
なぜ最大サイズですか?さて、GCCにはいくつかの識別子が必要ですが、ほとんどのglibcは一般に公開シンボルが一般的にプライベートシンボルにエイリアスされるように構造化されています。これはサイズが非常に小さいことを意味します(ジャンプ)。つまりputs
、独自の実装を提供する場合、まったく同じ方法でエイリアスで構成しないと、実装が失敗する可能性が高くなります。puts
エイリアスポインティングの場合__IO_puts
。
これは、標準ライブラリが標準ライブラリ呼び出しの実装を提供するメカニズムです。そしてこれをオーバーライドできます。