文章目录
- 1 nm指令
- 2 符号类型的含义
- 3 简单示例
1 nm指令
nm是names的缩写, nm命令主要是用来列出某些文件中的符号(说白了就是一些函数和全局变量等)。
nm命令的输出包含三个部分:
1 符号值。默认显示十六进制,也可以指定;
2 符号类型。小写表示是本地符号,大写表示全局符号(external);
3 符号名称
2 符号类型的含义
A: 符号值是绝对的。在进一步的连接中,不会被改变。
B: 符号位于未初始化数据段(known as BSS).
C: 共用(common)符号. 共用符号是未初始化的数据。在连接时,多个共用符号可能采用一个同样的名字,如果这个符号在某个地方被定义,共用符号被认为是未定义的引用.
D: 已初始化数据段的符号
G: 已初始化数据段中的小目标(small objective)符号. 一些目标文件格式允许更有效的访问小目标数据,比如一个全局的int变量相对于一个大的全局数组。
I: 其他符号的直接应用,这是GNU扩展的,很少用了.
N: 调试符号.
R: 只读数据段符号.
S: 未初始化数据段中的小目标(small object)符号.
T: 代码段的符号.
U: 未定义符号.
V: 弱对象(weak object)符号. 当一个已定义的弱符号被连接到一个普通定义符号,普通定义符号可以正常使用,当一个未定义的弱对象被连接到一个未定义的符号,弱符号的值为0.
W: 一个没有被指定一个弱对象符号的弱符号(weak symbol)。
-: a.out目标文件中的刺符号(stabs symbol). 这种情况下,打印的下一个值是其他字段,描述字段,和类型。刺符号用于保留调试信息.
?: 未知符号类型,或者目标文件特有的符号类型.
3 简单示例
nm nm_test.so
运行结果如下:
nm_test.so的源码如下:
#include <stdio.h>
int add(int x, int y)
{
return x + y;
}
int global_a;
int global_b = 1;
char szTest[] = "Hello";
int main()
{
int part_c = 2;
return 0;
}
从运行结果图中可以看出, 有add函数, 有全局变量global_a, global_b和szTest, 要注意, global_a是未初始化的, 所以在Bss段, 而global_b、szTest是初始化了的, 所以在Data段。 值得注意的是, 并没有global_c, 因为global_c是局部变量, nm看不到的。
在上面看不到"Hello", 因为nm是用来看szTest而非"Hello"的。 如果想要看字符串"Hello",可以使用前面提到的strings
命令。