4. Symbol Table
readelf -s
查看符号表
4.1 数据结构
typedef struct
{
Elf32_Word st_name; /* Symbol name (string tbl index) */
Elf32_Addr st_value; /* Symbol value */
Elf32_Word st_size; /* Symbol size */
unsigned char st_info; /* Symbol type and binding */
unsigned char st_other; /* Symbol visibility */
Elf32_Section st_shndx; /* Section index */
} Elf32_Sym;
st_name
, 和section头表一样,4字节,是strtab“表”偏移。st_size
, 符号大小,单位字节.st_other
, 保留,填0;
st_value
:
- 重定位文件中,记录符号相对所在段基地址的偏移;
- 可执行文件中,记录符号的虚拟地址。
st_shndx
:符号所在段对应的段表项在段表内的索引,一般为正,也有下面几种情况:
/* Special section indices. */
#define SHN_UNDEF 0 /* Undefined section */
#define SHN_LORESERVE 0xff00 /* Start of reserved indices */
#define SHN_LOPROC 0xff00 /* Start of processor-specific */
#define SHN_BEFORE 0xff00 /* Order section before all others
(Solaris). */
#define SHN_AFTER 0xff01 /* Order section after all others
(Solaris). */
#define SHN_HIPROC 0xff1f /* End of processor-specific */
#define SHN_LOOS 0xff20 /* Start of OS-specific */
#define SHN_HIOS 0xff3f /* End of OS-specific */
#define SHN_ABS 0xfff1 /* Associated symbol is absolute 符号为绝对值*/
#define SHN_COMMON 0xfff2 /* Associated symbol is common符号在common块,st_value表示符号对齐属性 */
#define SHN_XINDEX 0xffff /* Index is in extra table. */
#define SHN_HIRESERVE 0xffff /* End of reserved indices */
st_info
/* The syminfo section if available contains additional information about
every dynamic symbol. */
typedef struct
{
Elf32_Half si_boundto; /* Direct bindings, symbol bound to */
Elf32_Half si_flags; /* Per symbol flags */
} Elf32_Syminfo;
该字段大小1字节,低4位表示类型,高4位表示符号绑定信息。
用下面的宏操作:
/* How to extract and insert information held in the st_info field. */
#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4)
#define ELF32_ST_TYPE(val) ((val) & 0xf)
#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
5. Reloc Tab
重定位表常见于可重定位目标文件内
- 静态链接生成的可执行文件一般不包含重定位表;
- 动态链接生成的可执行文件暂时不讨论。
重定位表一般存在名称.rel
开头的段内,如.rel.text, .rel.data
。
5.1 结构体
表项:
typedef uint32_t Elf32_Word;
typedef int32_t Elf32_Sword;
typedef uint32_t Elf32_Addr;
/* Relocation table entry without addend (in section of type SHT_REL). */
typedef struct
{
Elf32_Addr r_offset; /* Address */
Elf32_Word r_info; /* Relocation type and symbol index */
} Elf32_Rel;
/* Relocation table entry with addend (in section of type SHT_RELA). */
typedef struct
{
Elf32_Addr r_offset; /* Address */
Elf32_Word r_info; /* Relocation type and symbol index */
Elf32_Sword r_addend; /* Addend */
} Elf32_Rela;
r_offset
:
- 对于可重定位目标文件,是目标位置相对所在段基地址的偏移;
- 对于可执行文件或共享目标文件,表示目标的虚拟地址。
r_info
:
- 低8位表示重定位类型;
- 高24位表示重定位符号表项在重符号表的索引
用下面的宏获取字段以及创建表项:
/* How to extract and insert information held in the r_info field. */
#define ELF32_R_SYM(val) ((val) >> 8)
#define ELF32_R_TYPE(val) ((val) & 0xff)
#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff))
#define ELF64_R_SYM(i) ((i) >> 32)
#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type))
5.2 重定位类型
静态链接中两种:
- 绝对地址重定位
R_386_32
- 相对地址重定位
R_386_PC32
/* i386 relocs. */
#define R_386_NONE 0 /* No reloc */
#define R_386_32 1 /* Direct 32 bit */
#define R_386_PC32 2 /* PC relative 32 bit */
#define R_386_GOT32 3 /* 32 bit GOT entry */
#define R_386_PLT32 4 /* 32 bit PLT address */
#define R_386_COPY 5 /* Copy symbol at runtime */
#define R_386_GLOB_DAT 6 /* Create GOT entry */
#define R_386_JMP_SLOT 7 /* Create PLT entry */
#define R_386_RELATIVE 8 /* Adjust by program base */
#define R_386_GOTOFF 9 /* 32 bit offset to GOT */
#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */
//...
#define R_386_GOT32X 43 /* Load from 32 bit GOT entry,
relaxable. */
/* Keep this the last entry. */
#define R_386_NUM 44
readelf -r
查看:
starr@starr-VirtualBox:~/Documents$ readelf -r a.out
Relocation section '.rel.plt' at offset 0x368 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00001fe4 00000307 R_386_JUMP_SLOT 00000000 puts@GLIBC_2.0
00001fe8 00000507 R_386_JUMP_SLOT 00000000 __libc_start_main@GLIBC_2.0
6. String Table
虽然叫做表,但段名和符号字符串其实是存在一个块中。
查看字符串表:hexdump -s OFFSET -C FILE | more