工具:
readelf -s 查看文件的符号(注意是小写s,大写是查看段)
例子:
Symbol table '.symtab' contains 16 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS stack.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 0 SECTION LOCAL DEFAULT 5
6: 0000000000000004 4 OBJECT LOCAL DEFAULT 3 static_var.2291
7: 0000000000000000 4 OBJECT LOCAL DEFAULT 4 static_var2.2292
8: 0000000000000000 0 SECTION LOCAL DEFAULT 7
9: 0000000000000000 0 SECTION LOCAL DEFAULT 8
10: 0000000000000000 0 SECTION LOCAL DEFAULT 6
11: 0000000000000000 4 OBJECT GLOBAL DEFAULT 3 global_var
12: 0000000000000004 4 OBJECT GLOBAL DEFAULT COM global_unint_var
13: 0000000000000000 34 FUNC GLOBAL DEFAULT 1 func1
14: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND printf
15: 0000000000000022 53 FUNC GLOBAL DEFAULT 1 main
第一列是符号数组下标,15共16个。
第二列是符号的值
第三列是符号的大小
第四列是符号类型
第五列是绑定信息
第六列在C/C++中未使用
第七列是符号名称
链接的接口--符号
可理解为链接的标识
在链接的过程中,变量和函数统称为符号,其名称为符号名
每一个文件都会有一个符号表,记录所有符号名。每个定义的符号都有一个值,对于变量和函数来说,值是其地址。
符号不止有变量和函数
符号的类型:
1. 定义在本文件的全局符号,可以被其他文件引用
2. 在本文件引用的外部符号(类似声明外部对象)
3. 局部符号名,(调试器可以通过这些符号来分析程序或奔溃时的核心转储文件)
4. 段名,一般由编译器产生,值是其起始地址
5. 行为符号,目标文件指令和源代码中代码行的对应关系
6. 特殊符号:
强弱符号:
默认初始化了的全局变量是强符号,未被初始化的是弱符号
定义初始化了的对象为弱符号: __attribute__((weak)) 对象
规则:
1. 不允许同名强符号多次定义,如不同文件中的同名全局变量会冲突
2. 使用时强符号优先于弱符号
3. 如果所有目标文件都是弱符号,使用占用空间最大的一个