nm命令使用詳解,讓你加快學習(xi)速度
時(shi)間:2018-07-20 來源:未(wei)知
nm 命令(ling)詳(xiang)解
符(fu)號(hao)(hao)是每個(ge)ELF文(wen)件(jian)的一(yi)個(ge)重要(yao)(yao)部分,因為(wei)它(ta)保(bao)存了(le)程(cheng)序實現(xian)或使用的所有(you)(全局)變量和函數。符(fu)號(hao)(hao)表中(zhong)保(bao)存了(le)查找程(cheng)序符(fu)號(hao)(hao)、為(wei)符(fu)號(hao)(hao)賦值、重定(ding)位(wei)符(fu)號(hao)(hao)所需要(yao)(yao)的全部信息。Linux中(zhong) nm用來列出(chu)目(mu)標文(wen)件(jian)的符(fu)號(hao)(hao)表;如果nm指令沒(mei)有(you)指出(chu)目(mu)標文(wen)件(jian),則nm假(jia)定(ding)目(mu)標文(wen)件(jian)是a.out
1.語法:
nm(選項)(參數)

2.輸出
對于每個符號,nm顯示:
·符(fu)號值,以選項(見下文)選擇的基數,或默認為十(shi)六進制。
·符號(hao)類型。 至少使用以下類型; 其他(ta)也是,取決于(yu)目標文件格式。
如果(guo)是小寫(xie)(xie),則符(fu)(fu)(fu)號(hao)通常是本地的; 如果(guo)是大(da)寫(xie)(xie),則符(fu)(fu)(fu)號(hao)為全局(ju)(外部)。然而(er),有一(yi)些為特殊(shu)全局(ju)符(fu)(fu)(fu)號(hao)( u , v 和 w )顯示的小寫(xie)(xie)符(fu)(fu)(fu)號(hao)。

3.選項
nm的用(yong)法很(hen)簡單,以下(xia)幾個關鍵字比較(jiao)常用(yong):
(1)"-A",列出符(fu)號名的(de)時候(hou)同時顯示(shi)來自于哪(na)個文件。
這在同(tong)時(shi)列出多(duo)個(ge)文件(jian)(比(bi)如一(yi)個(ge)鏈接庫)的符號時(shi)比(bi)較有用
(2)"-a",列出(chu)所有符號
這將會(hui)把調試符號也(ye)列(lie)出(chu)來。默認(ren)狀態(tai)下調試符號不會(hui)被列(lie)出(chu)。
(3)"-l",列出符號在源代碼(ma)中對應的行號
指定(ding)這個參數后,nm將利用調試(shi)信息(xi)找出(chu)文件(jian)名以及(ji)符(fu)號(hao)的行號(hao)。對(dui)于一個已定(ding)義(yi)符(fu)號(hao),將會找出(chu)這個符(fu)號(hao)定(ding)義(yi)的行號(hao),對(dui)于未(wei)定(ding)義(yi)符(fu)號(hao),顯示(shi)為空
(4)"-n",根(gen)據符(fu)號的地址來排序
默認是按符號名稱(cheng)的(de)字母順序排序的(de)
(5)"-u",只列出未定義符號
同"--undefined-only",而"--defined-only"將只列出(chu)已定義符號
4.示例
test.c

test.h

main.c


好, 我們(men)再(zai)來看看全局變量的情形, 我們(men)把(ba)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(注意, 如果只(zhi)有nm命令(ling), 則默認a.out為其要處(chu)理的文件):
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$
可以看到(dao), 不(bu)僅有add函數, 還有全局變量aaa, bbb和szTest, 要(yao)注(zhu)意, aaa是未(wei)初(chu)始化(hua)的(de)(de), 所(suo)以在Bss段(duan), 而bbb、szTest是初(chu)始化(hua)了的(de)(de),所(suo)以在Data段(duan)。 值(zhi)得注(zhu)意的(de)(de)是, 并沒有ccc, 因(yin)為ccc是局部變量, nm看不(bu)到(dao)的(de)(de)。

