nm
linux命令
nm命令主要是用來列出某些文件中的符號。
目錄
nm是納米的符號形式。
linux中,nm用來列出目標文件的符號清單。
下面是nm命令的格式:nm [-a|--debug-syms] [-g|--extern-only] [-B][-C|--demangle] [-D|--dynamic] [-s|--print-armap][-o|--print-file-name] [-n|--numeric-sort][-p|--no-sort] [-r|--reverse-sort] [--size-sort][-u|--undefined-only] [-l|--line-numbers] [--help][--version] [-t radix|--radix=radix][-P|--portability] [-f format|--format=format][--target=bfdname] [objfile...]
如果沒有為nm命令指出目標文件,則nm假定目標文件是a.out。下面列出該命令的任選項,大部分支持“-”開頭的短格式和“—“開頭的長格式。
-A、-o或--print-file-name:在找到的各個符號的名字前加上文件名,而不是在此文件的所有符號前只出現文件名一次。
例如nm libtest.a的輸出如下:
CPThread.o:
00000068 T Main__8CPThreadPv
00000038 T Start__8CPThread
00000014 T _._8CPThread
00000000 T __8CPThread
00000000 ? __FRAME_BEGIN__
…………………………………
則nm –A 的輸出如下:
libtest.a:CPThread.o:00000068 T Main__8CPThreadPv
libtest.a:CPThread.o:00000038 T Start__8CPThread
libtest.a:CPThread.o:00000014 T _._8CPThread
libtest.a:CPThread.o:00000000 T __8CPThread
libtest.a:CPThread.o:00000000 ? __FRAME_BEGIN__
…………………………………………………………
-a或--debug-syms:顯示調試符號。
-B:等同於--format=bsd,用來兼容MIPS的nm。
-C或--demangle:將低級符號名解碼(demangle)成用戶級名字。這樣可以使得C++函數名具有可讀性。
-D或--dynamic:顯示動態符號。該任選項僅對於動態目標(例如特定類型的共享庫)有意義。
-g或--extern-only:僅顯示外部符號。
-n、-v或--numeric-sort:按符號對應地址的順序排序,而非按符號名的字元順序。
-p或--no-sort:按目標文件中遇到的符號順序顯示,不排序。
-P或--portability:使用POSIX.2標準輸出格式代替默認的輸出格式。等同於使用任選項-f posix。
-s或--print-armap:當列出庫中成員的符號時,包含索引。索引的內容包含:哪些模塊包含哪些名字的映射。
-r或--reverse-sort:反轉排序的順序(例如,升序變為降序)。
--size-sort:按大小排列符號順序。該大小是按照一個符號的值與它下一個符號的值進行計算的。
-t radix或--radix=radix:使用radix進位顯示符號值。radix只能為“d”表示十進位、“o”表示八進位或“x”表示十六進位。
--target=bfdname:指定一個目標代碼的格式,而非使用系統的默認格式。
-u或--undefined-only:僅顯示沒有定義的符號(那些外部符號)。
-l或--line-numbers:對每個符號,使用調試信息來試圖找到文件名和行號。對於已定義的符號,查找符號地址的行號。對於未定義符號,查找指向符號重定位入口的行號。如果可以找到行號信息,顯示在符號信息之後。
-V或--version:顯示nm的版本號。
--help:顯示nm的任選項。
…………………………………………
輸出符號類型說明(大寫表示全局,小寫表示局部)
“A”該符號的值是絕對的,在以後的鏈接過程中,不允許進行改變。這樣的符號值,常常出現在中斷向量表中,例如用符號來表示各個中斷向量函數在中斷向量表中的位置。
“B”該符號的值出現在非初始化數據段(bss)中。例如,在一個文件中定義全局static int test。則該符號test的類型為B,位於bss section中。其值表示該符號在bss段中的偏移。一般而言,bss段分配於RAM中
“C”該符號為common。common symbol是未初始化數據段。該符號沒有包含於一個普通section中。只有在鏈接過程中才進行分配。符號的值表示該符號需要的位元組數。例如在一個c文件中,定義int test,並且該符號在別的地方會被引用,則該符號類型即為C。否則其類型為B。
補充:該符號所佔的空間並不存在於執行文件中,而在初始化執行環境時分配此空間,但不會清零,可讀寫。
“D”該符號位於初始化數據段中。一般來說,分配到data section中。例如定義全局int baud_table[5] = {9600, 19200, 38400, 57600, 115200},則會分配於初始化數據段中。
補充:該符號所佔用的空間存在於執行文件中,在初始化執行環境時分配,並複製數據到此空間,可讀寫。
“G”該符號也位於初始化數據段中。主要用於small object提高訪問small data object的一種方式。
“I”該符號是對另一個符號的間接引用。
“N”該符號是一個debugging符號。
“R”該符號位於只讀數據區。例如定義全局const int test[] = {123, 123};則test就是一個只讀數據區的符號。注意在cygwin下如果使用gcc直接編譯成MZ格式時,源文件中的test對應_test,並且其符號類型為D,即初始化數據段中。但是如果使用m6812-elf-gcc這樣的交叉編譯工具,源文件中的test對應目標文件的test,即沒有添加下劃線,並且其符號類型為R。一般而言,位於rodata section。值得注意的是,如果在一個函數中定義const char *test = “abc”, const char test_int = 3。使用nm都不會得到符號信息,但是字元串“abc”分配於只讀存儲器中,test在rodata section中,大小為4。
補充:此符號所佔用的空間存在於執行文件中,是否使用副本空間並不確定。只讀。
“S”符號位於非初始化數據區,用於small object。
“T”該符號位於代碼區text section。
“U”該符號在當前文件中是未定義的,即該符號的定義在別的文件中。例如,當前文件調用另一個文件中定義的函數,在這個被調用的函數在當前就是未定義的;但是在定義它的文件中類型是T。但是對於全局變數來說,在定義它的文件中,其符號類型為C,在使用它的文件中,其類型為U。
“V”該符號是一個weak object。
“W “The symbol is a weak symbol that has not been specifically tagged as a weak object symbol.
“-”該符號是a.out格式文件中的stabs symbol。
“?”該符號類型沒有定義