Linux nm コマンド

Linux 命令大全Linux コマンド大全


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

4. 特定のシンボルを検索

nm my_program | grep "main"

注意事項

  1. ストリップ(stripped)されたバイナリファイルの場合、nm有用な情報を表示できない可能性があります
  2. 異なるアーキテクチャのバイナリファイルでは、クロスコンパイルツールチェーン内のnm
  3. 動的シンボル(共有ライブラリ内)を表示するには、-Dオプションを使用する必要があります
  4. C++プログラムの場合は、常に-Cオプションを使用してシンボル名をデコードすることをお勧めします

上級テクニック

他のツールと組み合わせて使う

例

# objdumpを使用してより詳細なシンボル情報を表示
objdump -t my_program

# readelfを使用してELFファイルヘッダー情報を表示
readelf -s my_program

スクリプトを作成してシンボルを分析

例

#!/bin/bash
# シンボルタイプの分布を集計
nm $1 | awk '{print $2}' | sort | uniq -c | sort -nr

シンボルマッピングファイルの作成

nm -n my_program > symbol_map.txt

まとめ

nmコマンドはLinux開発者にとって重要なツールの1つです。これを習得すると、次のことができます:

  • プログラム構造をより深く理解できる
  • リンクの問題をすばやく特定できる
  • サードパーティライブラリの内容を分析できる
  • デバッグやリバースエンジニアリングを支援できる

この記事で紹介した基本的な使い方と実際の例を通して、あなたはすでにnmコマンドの核心機能を習得したはずです。実際の作業では、具体的なニーズに合わせてさまざまなオプションパラメータを柔軟に活用できます。


Linux 命令大全Linux コマンド大全

その他の拡張