nm 命令顯示關(guān)于指定 File 中符號(hào)的信息,文件可以是對(duì)象文件、可執(zhí)行文件或?qū)ο笪募?。如果文件沒有包含符號(hào)信息,nm 命令報(bào)告該情況,但不把它解釋為出錯(cuò)條件。 nm 命令缺省情況下報(bào)告十進(jìn)制符號(hào)表示法下的數(shù)字值。
$nm myProgrammer
08049f28 d _DYNAMIC
08049ff4 d _GLOBAL_OFFSET_TABLE_
080484dc R _IO_stdin_used
w _Jv_RegisterClasses
08049f18 d __CTOR_END__
08049f14 d __CTOR_LIST__
08049f20 D __DTOR_END__
08049f1c d __DTOR_LIST__
080485e0 r __FRAME_END__
08049f24 d __JCR_END__
08049f24 d __JCR_LIST__
0804a014 A __bss_start
0804a00c D __data_start
08048490 t __do_global_ctors_aux
08048360 t __do_global_dtors_aux
0804a010 D __dso_handle
w __gmon_start__
08048482 T __i686.get_pc_thunk.bx
08049f14 d __init_array_end
08049f14 d __init_array_start
08048480 T __libc_csu_fini
08048410 T __libc_csu_init
U __libc_start_main@@GLIBC_2.0
0804a014 A _edata
0804a01c A _end
080484bc T _fini
080484d8 R _fp_hw
080482b4 T _init
08048330 T _start
0804a014 b completed.6086
0804a00c W data_start
0804a018 b dtor_idx.6088
080483c0 t frame_dummy
080483e4 T main
U printf@@GLIBC_2.0
這些包含可執(zhí)行代碼的段稱為正文段。同樣地,數(shù)據(jù)段包含了不可執(zhí)行的信息或數(shù)據(jù)。另一種類型的段,稱為 BSS 段,它包含以符號(hào)數(shù)據(jù)開頭的塊。對(duì)于 nm 命令列出的每個(gè)符號(hào),它們的值使用十六進(jìn)制來表示(缺省行為),并且在該符號(hào)前面加上了一個(gè)表示符號(hào)類型的編碼字符。
可以將目標(biāo)文件中所包含的不同的部分劃分為段。段可以包含可執(zhí)行代碼、符號(hào)名稱、初始數(shù)據(jù)值和許多其他類型的數(shù)據(jù)。有關(guān)這些類型的數(shù)據(jù)的詳細(xì)信息,可以閱讀 UNIX 中 nm 的 man 頁面,其中按照該命令輸出中的字符編碼分別對(duì)每種類型進(jìn)行了描述。
選項(xiàng)說明
- -a或--debug-syms:顯示所有的符號(hào),包括debugger-only symbols。
- -B:等同于--format=bsd,用來兼容MIPS的nm。
- -C或--demangle:將低級(jí)符號(hào)名解析(demangle)成用戶級(jí)名字。這樣可以使得C++函數(shù)名具有可讀性。
- --no-demangle:默認(rèn)的選項(xiàng),不需要將低級(jí)符號(hào)名解析成用戶級(jí)名。
- -D或--dynamic:顯示動(dòng)態(tài)符號(hào)。該任選項(xiàng)僅對(duì)于動(dòng)態(tài)目標(biāo)(例如特定類型的共享庫)有意義。
- -f format:使用format格式輸出。format可以選取bsd、sysv或posix,該選項(xiàng)在GNU的nm中有用。默認(rèn)為bsd。
- -g或--extern-only:僅顯示外部符號(hào)。
- -n、-v或--numeric-sort:按符號(hào)對(duì)應(yīng)地址的順序排序,而非按符號(hào)名的字符順序。
- -p或--no-sort:按目標(biāo)文件中遇到的符號(hào)順序顯示,不排序。
- -P或--portability:使用POSIX.2標(biāo)準(zhǔn)輸出格式代替默認(rèn)的輸出格式。等同于使用任選項(xiàng)-f posix。
- -s或--print-armap:當(dāng)列出庫中成員的符號(hào)時(shí),包含索引。索引的內(nèi)容包含:哪些模塊包含哪些名字的映射。
- -r或--reverse-sort:反轉(zhuǎn)排序的順序(例如,升序變?yōu)榻敌?。
- --size-sort:按大小排列符號(hào)順序。該大小是按照一個(gè)符號(hào)的值與它下一個(gè)符號(hào)的值進(jìn)行計(jì)算的。
- --target=bfdname:指定一個(gè)目標(biāo)代碼的格式,而非使用系統(tǒng)的默認(rèn)格式。
- -u或--undefined-only:僅顯示沒有定義的符號(hào)(那些外部符號(hào))。
- --defined-only:僅顯示定義的符號(hào)。
- -l或--line-numbers:對(duì)每個(gè)符號(hào),使用調(diào)試信息來試圖找到文件名和行號(hào)。
- -V或--version:顯示nm的版本號(hào)。
- --help:顯示nm的選項(xiàng)。
符號(hào)說明
對(duì)于每一個(gè)符號(hào)來說,其類型如果是小寫的,則表明該符號(hào)是local的;大寫則表明該符號(hào)是global(external)的。
- A 該符號(hào)的值是絕對(duì)的,在以后的鏈接過程中,不允許進(jìn)行改變。這樣的符號(hào)值,常常出現(xiàn)在中斷向量表中,例如用符號(hào)來表示各個(gè)中斷向量函數(shù)在中斷向量表中的位置。
- B 該符號(hào)的值出現(xiàn)在非初始化數(shù)據(jù)段(bss)中。例如,在一個(gè)文件中定義全局static int test。則該符號(hào)test的類型為b,位于bss section中。其值表示該符號(hào)在bss段中的偏移。一般而言,bss段分配于RAM中。
- C 該符號(hào)為common。common symbol是未初始話數(shù)據(jù)段。該符號(hào)沒有包含于一個(gè)普通section中。只有在鏈接過程中才進(jìn)行分配。符號(hào)的值表示該符號(hào)需要的字節(jié)數(shù)。例如在一個(gè)c文件中,定義int test,并且該符號(hào)在別的地方會(huì)被引用,則該符號(hào)類型即為C。否則其類型為B。
-
D 該符號(hào)位于初始化數(shù)據(jù)段中。一般來說,分配到data section中。
例如:定義全局int baud_table[5] = {9600, 19200, 38400, 57600, 115200},會(huì)分配到初始化數(shù)據(jù)段中。
- G 該符號(hào)也位于初始化數(shù)據(jù)段中。主要用于small object提高訪問small data object的一種方式。
- I 該符號(hào)是對(duì)另一個(gè)符號(hào)的間接引用。
- N 該符號(hào)是一個(gè)debugging符號(hào)。
- R 該符號(hào)位于只讀數(shù)據(jù)區(qū)。
- 例如定義全局const int test[] = {123, 123};則test就是一個(gè)只讀數(shù)據(jù)區(qū)的符號(hào)。
- 值得注意的是,如果在一個(gè)函數(shù)中定義const char *test = "abc", const char test_int = 3。使用nm都不會(huì)得到符號(hào)信息,但是字符串"abc"分配于只讀存儲(chǔ)器中,test在rodata section中,大小為4。
- S 符號(hào)位于非初始化數(shù)據(jù)區(qū),用于small object。
- T 該符號(hào)位于代碼區(qū)text section。
- U 該符號(hào)在當(dāng)前文件中是未定義的,即該符號(hào)的定義在別的文件中。
例如,當(dāng)前文件調(diào)用另一個(gè)文件中定義的函數(shù),在這個(gè)被調(diào)用的函數(shù)在當(dāng)前就是未定義的;但是在定義它的文件中類型是T。但是對(duì)于全局變量來說,在定義它的文件中,其符號(hào)類型為C,在使用它的文件中,其類型為U。
- V 該符號(hào)是一個(gè)weak object。
- W The symbol is a weak symbol that has not been specifically tagged as a weak object symbol.
- ? 該符號(hào)類型沒有定義
庫或?qū)ο竺?/em>
如果您指定了 -A 選項(xiàng),則 nm 命令只報(bào)告與該文件有關(guān)的或者庫或者對(duì)象名。
示例
- 尋找特殊標(biāo)識(shí)
有時(shí)會(huì)碰到一個(gè)編譯了但沒有鏈接的代碼,那是因?yàn)樗笔Я藰?biāo)識(shí)符;這種情況,可以用nm和objdump、readelf命令來查看程序的符號(hào)表;所有這些命令做的工作基本一樣;
比如連接器報(bào)錯(cuò)有未定義的標(biāo)識(shí)符;大多數(shù)情況下,會(huì)發(fā)生在庫的缺失或企圖鏈接一個(gè)錯(cuò)誤版本的庫的時(shí)候;瀏覽目標(biāo)代碼來尋找一個(gè)特殊標(biāo)識(shí)符的引用
nm -uCA *.o | grep foo
-u選項(xiàng)限制了每個(gè)目標(biāo)文件中未定義標(biāo)識(shí)符的輸出。-A選項(xiàng)用于顯示每個(gè)標(biāo)識(shí)符的文件名信息;對(duì)于C++代碼,常用的還有-C選項(xiàng),它也為解碼這些標(biāo)識(shí)符;
objdump、readld命令可以完成同樣的任務(wù)。等效命令為:
$objdump -t
$readelf -s
- 列出 a.out 對(duì)象文件的靜態(tài)和外部符
$nm -e a.out
- 以十六進(jìn)制顯示符號(hào)大小和值并且按值排序符號(hào)
$nm -xv a.out
- 顯示 libc.a 中所有 64 位對(duì)象符號(hào),忽略所有 32 位對(duì)象
$nm -X64 /usr/lib/libc.a