nm命令存在於多數後出版本的Unix類似作業系統中。nm被用來檢查二進制檔案(包括,編譯後的目標模組,共享目的檔,和獨立可執行檔)並顯示這些檔案的內容,或儲存在其中的元資訊,特別是符號表。來自nm的輸出區分各種符號類型。例如,在一個目的檔所提供的函式和它所需要的函式之間是有區別的。nm被用作除錯的輔助工具,幫助解決名字衝突和C++名稱修飾引起的問題,和驗證工具鏈的其他部分。

nm
開發者AT&T貝爾實驗室
首次發布1971年11月3日,​52年前​(1971-11-03
作業系統Unix類Unix
類型命令

GNU計劃GNU Binutils包中提供了一個nm的實現。objdump -treadelf -s也可以檢視目的檔的符號表。

nm輸出樣例

下面的例子展示了變數和函式在全域局部外部靜態自動初始化的不同情況下的不同符號類型。

/*
 * 文件名: test.c
 * 对于C代码如下编译: 
 * gcc -c test.c
 *
 * 文件名:test.cpp
 * 对于C++代码如下编译:
 * g++ -c test.cpp
 */

int global_var;
int global_var_init = 26;

static int static_var;
static int static_var_init = 25;

static int static_function()
{
    return 0;
}

int global_function(int p)
{
    static int local_static_var;
    static int local_static_var_init=5;

    local_static_var = p;

    return local_static_var_init + local_static_var;
}

int global_function2()
{
    int x;
    int y;
    return x+y;
}

#ifdef __cplusplus
extern "C" {
#endif
void non_mangled_function()
{
    // I do nothing
}
#ifdef __cplusplus
}
#endif

int main(void)
{
    global_var = 1;
    static_var = 2;

    return 0;
}

如果上述代碼使用了gcc C編譯器來編譯,nm -n命令的輸出將把符號按其位址的數值來排序成如下這樣:

$ nm -n test.o
0000000000000000 B global_var
0000000000000000 D global_var_init
0000000000000000 t static_function
0000000000000004 b static_var
0000000000000004 d static_var_init
0000000000000008 b local_static_var.1
0000000000000008 d local_static_var_init.0
000000000000000f T global_function
0000000000000033 T global_function2
0000000000000045 T non_mangled_function
0000000000000050 T main

在使用了C++編譯器時,輸出是不同的:

$nm -n test.o
0000000000000000 B global_var
0000000000000000 D global_var_init
0000000000000000 t _ZL15static_functionv
0000000000000004 b _ZL10static_var
0000000000000004 d _ZL15static_var_init
0000000000000008 b _ZZ15global_functioniE16local_static_var
0000000000000008 d _ZZ15global_functioniE21local_static_var_init
000000000000000f T _Z15global_functioni
0000000000000033 T _Z16global_function2v
0000000000000045 T non_mangled_function
0000000000000050 T main

在二者輸出之間的不同還展示了通過在C++代碼中使用extern "C"英語extern "C"解決名稱修飾問題的一個例子。

符號類型
符號類型 描述
A 全域絕對符號
a 局部絕對符號
B 全域bss符號
b 局部bss符號
D 全域資料符號
d 局部資料符號
f 原始檔名字符號
L 全域執行緒本地符號(TLS)
l 靜態執行緒本地符號(TLS)
R 全域唯讀符號
r 局部唯讀符號
T 全域正文符號
t 局部正文符號
U 未定義符號

參見

外部連結