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]. 

        外部連結[編輯]