.soファイルからエクスポートされるシンボルを一覧表示するにはどうすればよいですか?可能であれば、それらのソースも知りたいです(たとえば、静的ライブラリから取得した場合)。
違いがある場合は、gcc 4.0.2を使用しています。
nm
はGNUではなくBSDだからnm
です。
.soファイルからエクスポートされるシンボルを一覧表示するにはどうすればよいですか?可能であれば、それらのソースも知りたいです(たとえば、静的ライブラリから取得した場合)。
違いがある場合は、gcc 4.0.2を使用しています。
nm
はGNUではなくBSDだからnm
です。
回答:
シンボルをリストするための標準的なツールはnm
です。これは次のように簡単に使用できます。
nm -gD yourLib.so
C ++ライブラリのシンボルを表示したい場合は、シンボルをデマングルする「-C」オプションを追加します(デマングルがはるかに読みやすくなります)。
nm -gDC yourLib.so
.soファイルがelf形式の場合、2つのオプションがあります。
いずれかobjdump
(-C
C ++のデマングルにも役立ちます):
$ objdump -TC libz.so
libz.so: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
0000000000002010 l d .init 0000000000000000 .init
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 free
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __errno_location
0000000000000000 w D *UND* 0000000000000000 _ITM_deregisterTMCloneTable
または使用readelf
:
$ readelf -Ws libz.so
Symbol table '.dynsym' contains 112 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000002010 0 SECTION LOCAL DEFAULT 10
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND free@GLIBC_2.2.5 (14)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __errno_location@GLIBC_2.2.5 (14)
4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable
readelf -Ws
はすべてのシンボルをnm -g
表示し、外部から見えるシンボルのみを表示することに注意してください。複数のシンボルファイルを調べてコマンドの交換を開始する場合、これは混乱を招く可能性があります。
objectdump -TC
リストにも追加します。とは逆にreadelf -Ws
、マングルされた名前は表示されません。
.so
ファイルの場合--dynamic
、nm
コマンドラインに追加する必要がある場合があります。
.so
ファイルがelf形式の場合、readelfプログラムを使用して、バイナリからシンボル情報を抽出できます。このコマンドは、シンボルテーブルを提供します。
readelf -Ws /usr/lib/libexample.so
この.so
ファイルで定義されているもののみを抽出し、それが参照するライブラリーでは抽出しないでください。この場合、7番目の列には数値が含まれます。単純な正規表現を使用して抽出できます。
readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'
readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
すべてのシンボルが常にnmで表示されていたため、なぜ-fvisibility = hiddenと#pragma GCCの可視性が何の影響もないように思えたのですが、この記事でreadelfとobjdumpが表示されるまで、そこに気づきました。実際には2つのシンボルテーブルのようです:
前者には、リンカまたはインストールコマンドに指定できるストリップまたは-sスイッチでストリップできるデバッグシンボルが含まれていると思います。nmに何もリストされなくなっても、エクスポートされたシンボルはELFの「動的シンボルテーブル」にあるため、エクスポートされます。後者は後者です。
C ++ .so
ファイルの場合、最終的なnm
コマンドはnm --demangle --dynamic --defined-only --extern-only <my.so>
# nm --demangle --dynamic --defined-only --extern-only /usr/lib64/libqpid-proton-cpp.so | grep work | grep add
0000000000049500 T proton::work_queue::add(proton::internal::v03::work)
0000000000049580 T proton::work_queue::add(proton::void_function0&)
000000000002e7b0 W proton::work_queue::impl::add_void(proton::internal::v03::work)
000000000002b1f0 T proton::container::impl::add_work_queue()
000000000002dc50 T proton::container::impl::container_work_queue::add(proton::internal::v03::work)
000000000002db60 T proton::container::impl::connection_work_queue::add(proton::internal::v03::work)
nm
していますが、-D
and-g
(IIRC)などの一部のオプションには応答しません。