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

        外部链接[编辑]