美文网首页iOS开发系列
助你加快学习速度——nm命令使用详解

助你加快学习速度——nm命令使用详解

作者: 84e94ada13e1 | 来源:发表于2018-07-23 16:04 被阅读12次

    符号是每个ELF文件的一个重要部分,因为它保存了程序实现或使用的所有(全局)变量和函数。符号表中保存了查找程序符号、为符号赋值、重定位符号所需要的全部信息。Linux中 nm用来列出目标文件的符号表;如果nm指令没有指出目标文件,则nm假定目标文件是a.out

    1.语法:

    nm(选项)(参数)

    2.输出

    对于每个符号,nm显示:

    ·符号值,以选项(见下文)选择的基数,或默认为十六进制。

    ·符号类型。 至少使用以下类型; 其他也是,取决于目标文件格式。

    如果是小写,则符号通常是本地的; 如果是大写,则符号为全局(外部)。然而,有一些为特殊全局符号( u , v 和 w )显示的小写符号。

    3.选项

    nm的用法很简单,以下几个关键字比较常用:

    (1)"-A",列出符号名的时候同时显示来自于哪个文件。

    这在同时列出多个文件(比如一个链接库)的符号时比较有用

    (2)"-a",列出所有符号

    这将会把调试符号也列出来。默认状态下调试符号不会被列出。

    (3)"-l",列出符号在源代码中对应的行号

    指定这个参数后,nm将利用调试信息找出文件名以及符号的行号。对于一个已定义符号,将会找出这个符号定义的行号,对于未定义符号,显示为空

    (4)"-n",根据符号的地址来排序

    默认是按符号名称的字母顺序排序的

    (5)"-u",只列出未定义符号

    同"--undefined-only",而"--defined-only"将只列出已定义符号

    4.示例

    test.c

    test.h

    main.c

    好, 我们再来看看全局变量的情形, 我们把main.c改为:

    1. #include

    2. int add(int x, int y)

    3. {

    4. return x + y;}

    5. int aaa;

    6. int bbb = 1;

    7. char szTest[] = "good";

    8. int main()

    9. {

    10. int ccc = 2;

    11. return 0;

    12.}

    然后用nm分析a.out(注意, 如果只有nm命令, 则默认a.out为其要处理的文件):

    1. fs@localhost learn_nm $ ls

    2. main.c

    3. fs@localhost learn_nm $ gcc main.c

    4. fs@localhost learn_nm $ ./a.out

    5. fs@localhost learn_nm $ nm a.out

    6. 08049538 d _DYNAMIC

    7. 08049604 d _GLOBAL_OFFSET_TABLE_

    8. 0804847c R _IO_stdin_used

    9. w _Jv_RegisterClasses

    10.08049528 d __CTOR_END__

    11.08049524 d __CTOR_LIST__

    12.08049530 D __DTOR_END__

    13.0804952c d __DTOR_LIST__

    14.08048520 r __FRAME_END__

    15.08049534 d __JCR_END__

    16.08049534 d __JCR_LIST__

    17.08049628 A __bss_start

    18.08049618 D __data_start

    19.08048430 t __do_global_ctors_aux

    20.08048310 t __do_global_dtors_aux

    21.08048480 R __dso_handle

    22. w __gmon_start__

    23.0804842a T __i686.get_pc_thunk.bx

    24.08049524 d __init_array_end

    25.08049524 d __init_array_start

    26.080483c0 T __libc_csu_fini

    27.080483d0 T __libc_csu_init

    28. U __libc_start_main@@GLIBC_2.0

    29.08049628 A _edata

    30.08049634 A _end

    31.0804845c T _fini

    32.08048478 R _fp_hw

    33.08048274 T _init

    34.080482e0 T _start

    35.08049630 B aaa

    36.08048394 T add

    37.0804961c D bbb

    38.08049628 b completed.5963

    39.08049618 W data_start

    40.0804962c b dtor_idx.5965

    41.08048370 t frame_dummy

    42.080483a2 T main

    43.08049620 D szTest

    44.fs@localhost learn_nm$

    可以看到, 不仅有add函数, 还有全局变量aaa, bbb和szTest, 要注意, aaa是未初始化的, 所以在Bss段, 而bbb、szTest是初始化了的,所以在Data段。 值得注意的是, 并没有ccc, 因为ccc是局部变量, nm看不到的。

    相关文章

      网友评论

        本文标题:助你加快学习速度——nm命令使用详解

        本文链接:https://www.haomeiwen.com/subject/jisjmftx.html