符号是每个ELF文件的一个重要部分,因为它保存了程序实现或使用的所有(全局)变量和函数。符号表中保存了查找程序符号、为符号赋值、重定位符号所需要的全部信息。Linux中?nm用来列出目标文件的符号表;如果nm指令没有指出目标文件,则nm假定目标文件是a.out
1.语法:
nm(选项)(参数)
2.输出
对于每个符号,nm显示:
·符号值,以选项(见下文)选择的基数,或默认为十六进制。
·符号类型。?至少使用以下类型;?其他也是,取决于目标文件格式。
如果是小写,则符号通常是本地的;?如果是大写,则符号为全局(外部)。然而,有一些为特殊全局符号(?u?,?v?和?w?)显示的小写符号。
3.选项
nm的用法很简单,以下几个关键字比较常用:
(1)"-A",列出符号名的时候同时显示来自于哪个文件。
这在同时列出多个文件(比如一个链接库)的符号时比较有用
(2)"-a",列出所有符号
这将会把调试符号也列出来。默认状态下调试符号不会被列出。
(3)"-l",列出符号在源代码中对应的行号
指定这个参数后,nm将利用调试信息找出文件名以及符号的行号。对于一个已定义符号,将会找出这个符号定义的行号,对于未定义符号,显示为空
(4)"-n",根据符号的地址来排序
默认是按符号名称的字母顺序排序的
(5)"-u",只列出未定义符号
同"--undefined-only",而"--defined-only"将只列出已定义符号
4.示例
test.c
test.h
main.c
好,?我们再来看看全局变量的情形,?我们把main.c改为:
1.?#include
2.?int?add(int?x,?int?y)
3.?{
4.?return?x?+?y;}
5.?int?aaa;
6.?int?bbb?=?1;
7.?char?szTest[]?=?"good";
8.?int?main()
9.?{
10.?int?ccc?=?2;
11.?return?0;
12.}
然后用nm分析a.out(注意,?如果只有nm命令,?则默认a.out为其要处理的文件):
1.?fs@localhost?learn_nm?$?ls
2.?main.c
3.?fs@localhost?learn_nm?$?gcc?main.c
4.?fs@localhost?learn_nm?$?./a.out
5.?fs@localhost?learn_nm?$?nm?a.out
6.?08049538?d?_DYNAMIC
7.?08049604?d?_GLOBAL_OFFSET_TABLE_
8.?0804847c?R?_IO_stdin_used
9.?w?_Jv_RegisterClasses
10.08049528?d?__CTOR_END__
11.08049524?d?__CTOR_LIST__
12.08049530?D?__DTOR_END__
13.0804952c?d?__DTOR_LIST__
14.08048520?r?__FRAME_END__
15.08049534?d?__JCR_END__
16.08049534?d?__JCR_LIST__
17.08049628?A?__bss_start
18.08049618?D?__data_start
19.08048430?t?__do_global_ctors_aux
20.08048310?t?__do_global_dtors_aux
21.08048480?R?__dso_handle
22.?w?__gmon_start__
23.0804842a?T?__i686.get_pc_thunk.bx
24.08049524?d?__init_array_end
25.08049524?d?__init_array_start
26.080483c0?T?__libc_csu_fini
27.080483d0?T?__libc_csu_init
28.?U?__libc_start_main@@GLIBC_2.0
29.08049628?A?_edata
30.08049634?A?_end
31.0804845c?T?_fini
32.08048478?R?_fp_hw
33.08048274?T?_init
34.080482e0?T?_start
35.08049630?B?aaa
36.08048394?T?add
37.0804961c?D?bbb
38.08049628?b?completed.5963
39.08049618?W?data_start
40.0804962c?b?dtor_idx.5965
41.08048370?t?frame_dummy
42.080483a2?T?main
43.08049620?D?szTest
44.fs@localhost?learn_nm$
可以看到,?不仅有add函数,?还有全局变量aaa,?bbb和szTest,?要注意,?aaa是未初始化的,?所以在Bss段,?而bbb、szTest是初始化了的,所以在Data段。?值得注意的是,?并没有ccc,?因为ccc是局部变量,?nm看不到的。
嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!
无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。
(点击找小助理免费领取)扫码进群领资料https://s.pdb2.com/pages/20230519/16QijNiGb32IFIn.html