binutils工具集之---nm
nm用于列出程序文件中的符號。建立nmtest.c文件:
1 #include<time.h>2 3 int global1;4 int global2=3;5 6 static int static_global1;7 static int static_global2=3;8 9 void foo()10 {11 static int internal1;12 static int internal2=3;13 time(0);14 }15 16 static void bar()17 {18 19 }2021 int main(void)22 {23 int local1;24 int local2=3;25 foo();26 return 0;27 }執行 gcc -g -c nmtest.c
然后
?
?
nm的第一列是指程序運行時符號在內存中的地址,它表示函數或變量的開始地址;第二列是指相應的符號放在哪個段,最后一列則是符號的名稱。
第二列的信息對我們非常有用,可以讓我了解在程序中所定義的一個符號是被放在程序的哪一個段的。下面列出常見字母含義(更多詳情man):
?
上面nm的結果顯示,存在地址為0的符號,此時列出的地址由于程序還沒完成鏈接,所以是指符號在對應段中的相對偏移位置。另外,還可以看出time符號沒有定義,因為它在c標準庫libc.a內。由上可得結論:
無論靜態變量是否初始化,程序段的分配方式都是一樣的(都在數據段),初始化的靜態變量會被分配到.data段中,否則分配在.bss段中;
非靜態的全局變量所分配的段只與其是否初始化有關。初始化了則分配在.data段,否則分配在.bss段;
函數無論是靜態還是非靜態的,總是分配在.test段中,小寫t表示靜態函數,大寫T表示非靜態。
函數內的局部變量由于是分配在棧上的,所以在nm中看不到他們的身影。
man是個查詢指令的強大工具~~~
執行gcc -g nmtest.c -o test
? ? ? ?nm -n test
發現global1的變量的分配空間從前面的C變成了B,time符號從無定義變成了分配在.test段中。
nm命令:
選項/屬性:
-a或--debug-syms:顯示調試符號。
-B:等同于--format=bsd,用來兼容MIPS的nm。
-C或--demangle:將低級符號名解碼(demangle)成用戶級名字。這樣可以使得C++函數名具有可讀性。
-D或--dynamic:顯示動態符號。該任選項僅對于動態目標(例如特定類型的共享庫)有意義。
-f format:使用format格式輸出。format可以選取bsd、sysv或posix,該選項在GNU的nm中有用。默認為bsd。
-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的任選項
轉載于:https://www.cnblogs.com/yangguang-it/p/6443898.html
總結
以上是生活随笔為你收集整理的binutils工具集之---nm的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自然数幂求和方法1:扰动法(求两次)
- 下一篇: poj3421 X-factor Cha