一、 动态符号表(dynamic symbol table)
动态符号表,即”.dynsym”节。
目标文件中的“符号表(symbol table)”所包含的信息用于定位和重定位程序中的符号定义和引用。目标文件的其它部分通过一个符号在这个表中的索引值来使用 该符号。索引值从 0 开始计数,但值为 0 的表项(即第一项)并没有实际的意义,它表示未定义的符号。这里用常量 STN_UNDEF 来表示未定义的符号。
一个符号表项的格式定义如下:
typedef struct
{
Elf64_Word st_name; /* Symbol name (string tbl index) */
unsigned char st_info; /* Symbol type and binding */
unsigned char st_other; /* Symbol visibility */
Elf64_Section st_shndx; /* Section index */
Elf64_Addr st_value; /* Symbol value */
Elf64_Xword st_size; /* Symbol size */
} Elf64_Sym;
1. st_name
符号的名字。但它并不是一个字符串,而是一个指向字符串表的索引值,在字符串表中对应位置上的字符串就是该符号名字的实际文本。如果此值为非 0,它代表符号名在字符串表中的索引值。如果此值为 0,那么此符号无名字。
偏移开始的位置是从 .dynstr 节 ( 进行动态链接所需的字符串,通常是表示与符号表各项关联的名称的字符串。) 开头开始计算。
0x978 + 0x282 然后读到第一个0结尾就是st_name。
2. st_info
符号的类型和属性。
ST_BIND
名称 | 值 | |
STB_LOCAL | 0 | 表明本符号是一个本地符号。它只出现在本文件中,在本文件外该符号无效。 |
STB_GLOBAL | 1 | 表明本符号是一个全局符号。当有多个文件被连接在一起时,在所有文 件中该符号都是可见的。正常情况下,在一个文件中定义的全局符号,一 定是在其它文件中需要被引用,否则无须定义为全局。 |
STB_WEAK | 2 | 弱符号。这些符号与全局符号类似,但其定义具有较低的优先级。 |
STB_LOOS | 10 | 本符号类保留用于特定于操作系统的语义。 |
STB_HIOS | 12 | 本符号类保留用于特定于操作系统的语义。 |
STB_LOPROC | 13 | 本符号类保留用于特定于处理器的语义。 |
STB_HIPROC | 15 | 本符号类保留用于特定于处理器的语义。 |
ST_TYPE
名称 | 值 | |
STT_NOTYPE | 0 | 本符号类型未指定。 |
STT_OBJECT | 1 | 本符号是一个数据对象,比如变量、数组等。 |
STT_FUNC | 2 | 本符号是一个函数,或者其它的可执行代码。 |
STT_SECTION | 3 | 本符号与一个节相关联,用于重定位,通常具有 STB_LOCAL 属性。 |
STT_FILE | 4 | 本符号是一个文件符号,它具有 STB_LOCAL 属性,它的节索引值是 SHN_ABS。在符号表中如果存在本类符号的话,它会出现在所有 STB_LOCAL 类符号的前部。 |
STT_LOPROC | 13 | 本符号类型为特殊处理器保留。 |
STT_HIPROC | 15 | 本符号类型为特殊处理器保留。 |
3. st_other
本数据成员目前暂未使用,在目标文件中一律赋值为 0。
4. st_shndx
所定义的每一个符号表项都与某节有关。此成员包含相关节头表索引。部分节索引会表示特殊含义。
5. st_value
在可执行文件和共享库文件中,st_value 不再是一个节内的偏移量,而是一个虚拟地址,直接指向符号所在的内存位置。这种情况下,st_shndx 就不再需要了。
6. st_size
符号的大小。各种符号的大小各不相同,比如一个对象的大小就是它实际占用的字节数。如果一个符号的大小为 0 或者大小未知,则这个值为 0。