nm 命令顯示關(guān)于指定 File 中符號的信息,文件可以是對象文件、可執(zhí)行文件或?qū)ο笪募?。如果文件沒有包含符號信息,nm 命令報告該情況,但不把它解釋為出錯條件。 nm 命令缺省情況下報告十進制符號表示法下的數(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 段,它包含以符號數(shù)據(jù)開頭的塊。對于 nm 命令列出的每個符號,它們的值使用十六進制來表示(缺省行為),并且在該符號前面加上了一個表示符號類型的編碼字符。
可以將目標文件中所包含的不同的部分劃分為段。段可以包含可執(zhí)行代碼、符號名稱、初始數(shù)據(jù)值和許多其他類型的數(shù)據(jù)。有關(guān)這些類型的數(shù)據(jù)的詳細信息,可以閱讀 UNIX 中 nm 的 man 頁面,其中按照該命令輸出中的字符編碼分別對每種類型進行了描述。
對于每一個符號來說,其類型如果是小寫的,則表明該符號是local的;大寫則表明該符號是global(external)的。
D 該符號位于初始化數(shù)據(jù)段中。一般來說,分配到data section中。 例如:定義全局int baud_table[5] = {9600, 19200, 38400, 57600, 115200},會分配到初始化數(shù)據(jù)段中。
庫或?qū)ο竺?/em> 如果您指定了 -A 選項,則 nm 命令只報告與該文件有關(guān)的或者庫或者對象名。
有時會碰到一個編譯了但沒有鏈接的代碼,那是因為它缺失了標識符;這種情況,可以用nm和objdump、readelf命令來查看程序的符號表;所有這些命令做的工作基本一樣;
比如連接器報錯有未定義的標識符;大多數(shù)情況下,會發(fā)生在庫的缺失或企圖鏈接一個錯誤版本的庫的時候;瀏覽目標代碼來尋找一個特殊標識符的引用
nm -uCA *.o | grep foo
-u選項限制了每個目標文件中未定義標識符的輸出。-A選項用于顯示每個標識符的文件名信息;對于C++代碼,常用的還有-C選項,它也為解碼這些標識符;
objdump、readld命令可以完成同樣的任務(wù)。等效命令為:
$objdump -t
$readelf -s
$nm -e a.out
$nm -xv a.out
$nm -X64 /usr/lib/libc.a