web-dev-qa-db-ja.com

nm対「readelf-s」

Libtest.soという名前の共有ライブラリがあり、その中に1つの関数「foo」があるとします。

ストリップを使用して、libtest.soからすべてのシンボルを破棄します

$strip libtest.so

だから、今私たちが使用する場合:

$nm libtest.so

印刷されます:

nm:libtest.so:記号なし

しかし、使用する場合:

$readelf -s libtest.so 

foo関数はまだその結果から見ることができます:

.。

10:000005dc 5 FUNC GLOBAL DEFAULT 12 _Z3foov

.。

コマンド文字列を使用して確認することもできます。

$strings libtest.so

.。

_Z3foov

.。

ここに私の質問があります、なぜnmは縞模様のlibtest.soの結果を与えないのですか?

ありがとう

35
camino

nmがストライプlibtest.soの結果を出さない理由

元のlibtest.soにはtwoシンボルテーブルがあります。「通常の」テーブル(.symtabセクションと.strtabセクション)と動的テーブル(.dynsymセクションと.dynstrセクション)です。

stripが両方のシンボルテーブルを削除した場合、ライブラリは完全に役に立たなくなります。ダイナミックローダーはその中のシンボルを解決できませんでした。したがって、stripは、意味のある唯一のことを実行します。つまり、「通常の」シンボルテーブルを削除し、動的なシンボルテーブルをそのまま残します。

nm -Dまたはreadelf -sを使用して動的シンボルテーブルにシンボルを表示できます。

「通常の」シンボルテーブルは、デバッグにのみ役立ちます(たとえば、ライブラリによってエクスポートされず、動的シンボルテーブルに表示されない静的関数のエントリが含まれています)。

ただし、ダイナミックローダーは「通常の」シンボルテーブル(高速シンボルルックアップに適した形式ではありません)を確認することはありません。動的なものでのみ。したがって、「通常の」シンボルテーブルはプログラムを正しく動作させるために必要ではありませんが、動的なものは必要です。

60