nm (Unix)

維基百科,自由的百科全書
跳至導覽 跳至搜尋

nm
開發者AT&T貝爾實驗室
首次發布1971年11月3日,​54年前​(1971-11-03
目前版本
    Module:EditAtWikidata第29行Lua錯誤:attempt to index field 'wikibase' (a nil value)
    原始碼庫
    • {{URL|example.com|可选的显示文本}}
    Module:EditAtWikidata第29行Lua錯誤:attempt to index field 'wikibase' (a nil value)
    引擎
      Module:EditAtWikidata第29行Lua錯誤:attempt to index field 'wikibase' (a nil value)
      作業系統Unix類Unix
      類型命令
      許可協定
        Module:EditAtWikidata第29行Lua錯誤:attempt to index field 'wikibase' (a nil value)

        nm命令存在於多數後出版本的Unix類似作業系統中。nm被用來檢查二進制檔案(包括,編譯後的目標模組,共享目的檔,和獨立可執行檔)並顯示這些檔案的內容,或儲存在其中的元資訊,特別是符號表nm這個名字來源於Version 7 Unix,其手冊頁使用術語「名字列表」(name list)而非「符號表」[1]GNU計劃GNU Binutils包中提供了一個nm的實現。

        符號表[編輯]

        來自nm的輸出區分各種符號類型。例如,在一個目的檔所提供的函式和它所需要的函式之間是有區別的。nm被用作除錯的輔助工具,幫助解決名字衝突和C++名稱修飾引起的問題,和驗證工具鏈的其他部分。objdump -treadelf -s也可以檢視目的檔的符號表。

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

        樣例[編輯]

        下面的例子展示了變數和函式在全域局部外部靜態自動初始化的不同情況下的不同符號類型。將其存入檔案test.c中,對這個C代碼如下編譯:gcc -c test.c;或者將其存入檔案test.cpp中,對這個C++代碼如下編譯:g++ -c test.cpp。在二者輸出之間的不同還展示了通過在C++代碼中使用extern "C"英語extern "C"解決名字修飾問題的一個例子。

        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
        

        參見[編輯]

        參照[編輯]

        1. ^ NM(1). Unix Seventh Edition General Commands Manual. [2025-03-14]. 

        外部連結[編輯]