Linux nm コマンド
nmLinuxシステムにおける重要なコマンドラインツールで、正式名称は「Name List」です。バイナリオブジェクトファイル(ライブラリファイルや実行可能ファイルなど)内のシンボル情報を表示するために使用され、プログラマーやバイナリファイルを解析する際によく使われるツールです。
主な機能
- オブジェクトファイル内のシンボル(関数、変数など)を一覧表示
- シンボルのタイプと属性を表示
- プログラムのリンク問題の分析に役立つ
- デバッグとリバースエンジニアリングを支援
基本構文
nm [选项] 文件名
よく使うオプションとパラメータの説明
| オプション | 説明 |
|---|---|
-a |
デバッグシンボルを含むすべてのシンボルを表示 |
-g |
外部(グローバル)シンボルのみ表示 |
-u |
未定義のシンボルのみ表示 |
-D |
動的シンボルを表示(共有ライブラリ用) |
-C |
C++シンボル名をデコード(demangle)する |
-l |
シンボルの行番号を表示(デバッグ情報が必要) |
-S |
シンボルのサイズを表示 |
-t |
出力形式を指定(d-10進数、o-8進数、x-16進数) |
--size-sort |
シンボルサイズ順に並べ替え |
--defined-only |
定義済みのシンボルのみ表示 |
シンボルタイプの説明
nm出力されるシンボルタイプは1文字で表されます。よくあるものは次のとおりです:
| タイプ | 説明 |
|---|---|
| A | 絶対シンボル。リンク時に変更されない |
| B/b | 未初期化データセグメント(BSSセグメント)内のシンボル |
| D/d | 初期化済みデータセグメント内のシンボル |
| T/t | コードセグメント内のシンボル(Tはグローバル、tはローカルを表す) |
| U | 未定義のシンボル(他のファイルからリンクする必要がある) |
| W/w | 弱シンボル(weak symbol) |
| R/r | 読み取り専用データセグメント内のシンボル |
| C | 共通シンボル(common symbol) |
| I | 他のシンボルを間接参照する |
実際の使用例
例1:実行可能ファイルのシンボルテーブルを表示
nm /bin/ls
出力例:
0000000000000000 A _IO_stdin_used 0000000000000000 R _fp_hw 0000000000000000 T _init 0000000000000000 W _ITM_deregisterTMCloneTable 0000000000000000 W _ITM_registerTMCloneTable 0000000000000000 W __cxa_finalize 0000000000000000 W __gmon_start__ 0000000000000000 T __libc_csu_fini 0000000000000000 T __libc_csu_init ...
例2:未定義のシンボルのみ表示
nm -u /bin/ls
出力例:
U __ctype_toupper_loc
U __errno_location
U __overflow
U __stack_chk_fail
U __strtoul_internal
U _obstack_begin
U _obstack_newchunk
U abort
U access
...
例3:C++プログラムのシンボルを表示(名前をデコード)
nm -C my_program
出力例:
0000000000000000 T main 0000000000000000 T std::cout 0000000000000000 T std::basic_ostream<char, std::char_traits >& std::operator<< <std::char_traits >(std::basic_ostream<char, std::char_traits >&, char const*) ...
例4:シンボルのサイズを表示し、サイズ順に並べ替え
nm -S --size-sort my_library.so
出力例:
0000000000000001 0000000000000001 T func1 0000000000000002 0000000000000002 T func2 0000000000000004 0000000000000004 D global_var 0000000000000008 0000000000000008 B large_buffer ...
よくある使用シナリオ
1. リンクエラーの解決
「undefined reference」エラーが発生した場合、以下のコマンドを使用して、nmどのシンボルが未定義かを確認できます:
nm -u my_program.o
2. ライブラリファイルの内容を分析
共有ライブラリがエクスポートするシンボルを表示:
nm -D libexample.so
3. 2つのバージョンのバイナリファイルを比較
例
nm old_version > old.txt
nm new_version > new.txt
diff old.txt new.txt
nm new_version > new.txt
diff old.txt new.txt
4. 特定のシンボルを検索
nm my_program | grep "main"
注意事項
- ストリップ(stripped)されたバイナリファイルの場合、
nm有用な情報を表示できない可能性があります - 異なるアーキテクチャのバイナリファイルでは、クロスコンパイルツールチェーン内の
nm - 動的シンボル(共有ライブラリ内)を表示するには、
-Dオプションを使用する必要があります - C++プログラムの場合は、常に
-Cオプションを使用してシンボル名をデコードすることをお勧めします
上級テクニック
他のツールと組み合わせて使う
例
# objdumpを使用してより詳細なシンボル情報を表示
objdump -t my_program
# readelfを使用してELFファイルヘッダー情報を表示
readelf -s my_program
objdump -t my_program
# readelfを使用してELFファイルヘッダー情報を表示
readelf -s my_program
スクリプトを作成してシンボルを分析
例
#!/bin/bash
# シンボルタイプの分布を集計
nm $1 | awk '{print $2}' | sort | uniq -c | sort -nr
# シンボルタイプの分布を集計
nm $1 | awk '{print $2}' | sort | uniq -c | sort -nr
シンボルマッピングファイルの作成
nm -n my_program > symbol_map.txt
まとめ
nmコマンドはLinux開発者にとって重要なツールの1つです。これを習得すると、次のことができます:
- プログラム構造をより深く理解できる
- リンクの問題をすばやく特定できる
- サードパーティライブラリの内容を分析できる
- デバッグやリバースエンジニアリングを支援できる
この記事で紹介した基本的な使い方と実際の例を通して、あなたはすでにnmコマンドの核心機能を習得したはずです。実際の作業では、具体的なニーズに合わせてさまざまなオプションパラメータを柔軟に活用できます。
その他の拡張
Linux コマンド大全