nm命令詳解


前言

nm是name的縮寫,它顯示指定文件中的符號信息,文件可以是對象文件、可執行文件或對象文件庫。如果文件中沒有包含符號信息,nm報告該情況,單不把他解釋為出錯。nm缺省情況下報告十進制符號表示法下的數字值。

選項

  • -a/--debug-syms:顯示所有符號,包括debugger-only symbols
  • -B:等同於 --format=bsd,兼容 MIPS nm
  • -C/--demangle:將低級符號名解析成用戶級名字。這樣可以使得C++函數名具有可讀性。
  • --no-demangle:默認選項,不將低級符號名解析成用戶級名字。
  • -D/--dynamic:顯示動態符號。這個選項只對動態目標(比如特定類型的共享庫)有意義。
  • -f format/--format=format:使用format格式輸出。format可以選取bsd、sysv或posix,該選項在GNU的nm中有用。默認為bsd
  • -g/--extern-only:只顯示外部符號
  • -l/--line-numbers:對於每一個符號,使用debug信息找到文件名和行號。
  • -n/-v/--numeric-sort:按符號對應地址的順序排序,而不是按符號名字符順序排序
  • -p/--no-sort:按照目標文件中遇到的符號順序顯示,不排序
  • -P/--portability:按照POSIX2.0標准格式輸出,等同於使用 -f posix
  • -r/--reverse-sort:反轉排序
  • -s/--print-armap:當列出庫中成員的符號時,包含索引。索引的內容包括:哪些模塊包含哪些名字的映射
  • -u/--undefined-only:只顯示未定義符號
  • --defined-only:只顯示定義的符號

符號說明

對於每一個符號來說,其類型如果是小寫的,則表明該符號是local的。大寫則表明該符號是global(external)的

  • A:該符號的值是絕對的,在以后的鏈接過程中,不允許改變。這樣的符號,常常出現在中斷向量表中,例如用符號來表示各個中斷向量函數在中斷向量表中的位置。
  • B:該符號的值出現在非初始化數據段BSS中。例如,一個文件中定義全局 static int s_int。則符號s_int 類型為b,位於bss section中。其值表示該符號在bss段的偏移。一般而言,bss段分配於RAM中。
  • C:該符號為common。common symbol是未初始化數據段。該符號沒有包含於一個普通section中。只有在鏈接過程中才進行分配。符號的值表示要分配的字節數。例如,在一個c文件中,定義 int g_no_init,並且該符號在別的地方會被引用,則該符號類型就是C,否則為B。
  • D:該符號位於初始化數據段中。一般來說,分配到data section中。比如,全局變量 int g_init = 2;
  • G:該符號也位於初始化數據段。主要用於small object,提高訪問small data object的一種方式。
  • I:該符號是對另一個符號的間接引用。
  • N:該符號是一個debugging符號
  • R:該符號位於只讀數據區。比如,全局變量 const int const_int = 0; 如果在一個函數中定義 const char* test = "abc"; const int a = 2; 使用nm都不會得到符號信息。但是字符串"abc"分配於只讀存儲器中,test 在rodata section中,大小為4
  • S:符號位於非初始化數據區,用於 small object
  • T:符號位於代碼區 text section
  • U:符號在當前文件中是未定義的,即該符號的定義在別的文件中。比如,當前文件中調用另一個文件中的函數,在這個本目標文件中,函數就是未定義的。但是在定義它的文件中,類型為T。但是對於全局變量來說,在定義它的文件中,符號類型是C,在使用它的文件中,類型是U。
  • V:該符號是一個weak object
  • ?:該符號類型沒有定義

示例

尋找特殊標識

有時會碰到一個編譯了但沒有鏈接的代碼,那是因為它缺失了標識符;這種情況,可以用nm和objdump、readelf命令來查看程序的符號表;所有這些命令做的工作基本一樣;
比如連接器報錯有未定義的標識符;大多數情況下,會發生在庫的缺失或企圖鏈接一個錯誤版本的庫的時候;瀏覽目標代碼來尋找一個特殊標識符的引用:

nm -uCA *.o | grep foo

-u選項限制了每個目標文件中未定義標識符的輸出。-A選項用於顯示每個標識符的文件名信息;對於C++代碼,常用的還有-C選項,它也為解碼這些標識符;

objdump、readld命令可以完成同樣的任務。等效命令為: $objdump -t $readelf -s

只顯示外部的定義的符號

nm add.o --defined-only -g


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM