功能
列出.o .a .so中的符號信息,包括諸如符號的值,符號類型及符號名稱等。所謂符號,通常指定義出的函數,全局變量等等。
使用
nm [option(s)] [file(s)]
有用的options:
-A 在每個符號信息的前面打印所在對象文件名稱;
-C 輸出demangle過了的符號名稱;
-D 打印動態符號;
-l 使用對象文件中的調試信息打印出所在源文件及行號;
-n 按照地址/符號值來排序;
-u 打印出那些未定義的符號;
常見的符號類型:
A 該符號的值在今后的鏈接中將不再改變;
B 該符號放在BSS段中,通常是那些未初始化的全局變量;
D 該符號放在普通的數據段中,通常是那些已經初始化的全局變量;
T 該符號放在代碼段中,通常是那些全局非靜態函數;
U 該符號未定義過,需要自其他對象文件中鏈接進來;
W 未明確指定的弱鏈接符號;同鏈接的其他對象文件中有它的定義就用上,否則就用一個系統特別指定的默認值。
注意幾點:
-C 總是適用於c++編譯出來的對象文件。還記得c++中有重載么?為了區分重載函數,c++編譯器會將函數返回值/參數等信息附加到函數名稱中去形成一個mangle過的符號,那用這個選項列出符號的時候,做一個逆操作,輸出那些原始的、我們可理解的符號名稱。
使用 -l 時,必須保證你的對象文件中帶有符號調式信息,這一般要求你在編譯的時候指定一個 -g 選項,見 Linux:Gcc。
使用nm前,最好先用Linux:File查看對象文件所屬處理器架構,然后再用相應交叉版本的nm工具。
例子
nm -u hello.o
顯示hello.o 中的未定義符號,需要和其他對象文件進行鏈接.
nm -A /usr/lib/* 2>/dev/null | grep "T memset"
在 /usr/lib/ 目錄下找出哪個庫文件定義了memset函數.
nm -o /lib/*.so||grep sin