19

.so ファイル (libstdc++.so.6 など) で nm を実行すると、シンボルが表示されず、nm --dynamic を使用する必要がある場合があります。しかし、他のいくつかの .so ファイルでは、--dynamic なしでシンボルを見ることができます。

ドキュメントは次のように述べています。

通常のシンボルではなく動的シンボルを表示します。これは、特定の種類の共有ライブラリなどの動的オブジェクトに対してのみ意味があります。

しかし、それは紛らわしいです...共有ライブラリのどの「タイプ」が必要ですか--dynamic? これはどのように決定されますか?ライブラリのコンパイル中?すべての共有ライブラリは動的 (つまり、実行時に動的にロードできる) だと思っていましたが、私の理解は正しくないようです。

4

2 に答える 2

18

シンボルが共有ライブラリからエクスポートされていない場合normal symbol tabledynamic symbol table.

ELF ファイルには多くの種類のシンボルがあります。

  • のシンボル部分Normal Symbol table。これは merenm libabc.soまたはからの出力objdump --syms libabc.soです。これらのシンボルは、静的リンク中にのみ使用されます。

  • のシンボル部分Dynamic Symbol table。これは、nm --dynamic libabc.soまたはからの出力objdump --dynamic-syms libabc.soです。動的シンボル テーブルは、シンボルを参照する ELF ファイルとそれらを定義する ELF ファイルの間でシンボルをバインドするランタイム リンカー/ローダーによって使用されるテーブルです。static linkerこれは、共有ライブラリをそれを必要とするアプリケーションとリンクするときにも使用されます。undefined symbol errorsこれは、リンク中にすべてを表示するのに役立つコンポーネントです。

  • Hidden symbols- これらは を使用してマークされた記号_attribute_ ((visibility("hidden")))です。これらのシンボルは外部にエクスポートされず、ライブラリ内でのみ使用できます。可視性はリンクのステップでチェックされるため、共有ライブラリに対してのみ適用されます。デフォルトの可視性は ですpublic。つまり、特に指定しない限り、シンボルはエクスポートされます。を使用して動作を変更できます-fvisibility=default|internal|hidden|protected

デフォルトの ELF イメージ シンボルの可視性を指定されたオプションに設定します。コード内でオーバーライドされない限り、すべてのシンボルがこれでマークされます。この機能を使用すると、共有オブジェクト ライブラリのリンクとロード時間を大幅に改善し、より最適化されたコードを生成し、ほぼ完璧な API エクスポートを提供し、シンボルの衝突を防ぐことができます。配布するすべての共有オブジェクトでこれを使用することを強くお勧めします。命名法にもかかわらず、デフォルトは常にパブリックを意味します。共有オブジェクトの外部からリンクできます。protected と internal は実際の使用ではほとんど役に立たないため、他の一般的に使用されるオプションのみが非表示になります。-fvisibility が指定されていない場合のデフォルトは default です。つまり、すべてのシンボルを public にします。これにより、以前のバージョンの GCC と同じ動作が発生します。

これらの手法の概要、利点、および使用方法については、 http: //gcc.gnu.org/wiki/Visibilityを参照してください。

--dynamicのオプションをいつ使用するかという質問に答えるにはnm、共有ライブラリによってエクスポートされたすべてのシンボルと、それらを参照する ELF イメージで使用できるシンボルのみを一覧表示する場合です。

于 2013-03-11T19:40:14.240 に答える
2

共有ライブラリが削除され、ダイナミック シンボル テーブルのみが含まれている場合は、共有ライブラリに対して--dynamicorオプションを使用する必要があります。-D

このオプションを他の共有ライブラリに使用して、ダイナミック シンボル テーブルを明示的に表示することができます。これは、ダイナミック リンカーによって参照されるテーブルであるためです。

このfileユーティリティは、共有ライブラリが削除されているかどうかを示します。例:

$ file /usr/lib64/libcrypt-nss-2.26.so
[..] ELF 64-bit LSB shared object, x86-64 [..], not stripped
$ file /usr/lib64/libxml2.so.2.9.7
[..] ELF 64-bit LSB shared object, x86-64 [..], stripped

異なるシンボル テーブルに異なるシンボルを含める方法の例:

$ nm -D /usr/lib64/libcrypt-nss-2.26.so | wc -l
39
$ nm /usr/lib64/libcrypt-nss-2.26.so | wc -l 
112
于 2018-05-23T15:41:36.257 に答える